From 15921ffcc9d22d09524600b2e943cb873cd8842b Mon Sep 17 00:00:00 2001 From: Irjan Olsen Date: Sun, 5 Feb 2023 04:32:36 +0100 Subject: [PATCH] Made samples kind of smoother? TODO: Add some effects to cover the bad parts up :D --- src/sampler.rs | 44 +++++++++++++++++++++++++++++++++----------- src/tracker.rs | 4 ++-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/sampler.rs b/src/sampler.rs index 7207fdf..2fd17f9 100644 --- a/src/sampler.rs +++ b/src/sampler.rs @@ -6,17 +6,29 @@ use rodio::Source; pub struct Sample { num_sample: usize, _sample_rate: u32, + _sample_rate_multiplier: u32, sample: SampleInfo, + data: Vec, } impl Sample { - pub fn new(sample_rate: u32, sample: SampleInfo) -> Self { + pub fn new(sample_rate: u32, mut sample: SampleInfo) -> Self { + let mut data: Vec = vec![]; + for i in 0..sample.data.len() { + if i % 2 == 1 { + data.push((sample.data[i-1] as u16) | ((sample.data[i] as u16)<<8)) + } else { + data.push((sample.data[i] as u16) | ((sample.data[i+1] as u16)<<8)) + } + } println!("Sample data len: {}", sample.data.len()); println!("Sample reported len: {}", sample.length); Self { num_sample: 0, _sample_rate: sample_rate, + _sample_rate_multiplier: 256, sample, + data, } } @@ -36,33 +48,43 @@ impl Sample { } impl Iterator for Sample { - type Item = f32; + type Item = u16; fn next(&mut self) -> Option { - if self.sample.data.len() == 0 { - return Some(0.0); + if self.data.len() == 0 { + return Some(0); } - let value = self.sample.data[self.num_sample]; + let index_1 = self.num_sample/self._sample_rate_multiplier as usize; + let index_2 = (index_1 + 1) % self.data.len(); + + let value_1 = self.data[index_1]; + let value_2 = self.data[index_2]; + + let second_index_weight = (self.num_sample % self._sample_rate_multiplier as usize) as f32 / 100.0; + let first_index_weight = 1.0 - second_index_weight; + + let value = value_1 as f32 * first_index_weight + value_2 as f32 * second_index_weight; + self.num_sample = self.num_sample.wrapping_add(1); - if self.num_sample >= self.sample.data.len() { - self.num_sample = 0; + if self.num_sample >= self.sample.repeat_length as usize * 2 * self._sample_rate_multiplier as usize { + self.num_sample = self.sample.repeat_start as usize * 2 * self._sample_rate_multiplier as usize; } - Some((value as i8 as f32)/(i8::MAX as f32)) + Some(value as u16) } } impl Source for Sample { fn current_frame_len(&self) -> Option { - Some(self.sample.data.len()-self.num_sample) + Some(self.sample.repeat_length as usize - self.num_sample) } fn channels(&self) -> u16 { 1 } fn sample_rate(&self) -> u32 { - self._sample_rate + self._sample_rate*self._sample_rate_multiplier } fn total_duration(&self) -> Option { - Some(Duration::new(0, (self.sample.data.len() * 1_000_000_000 / self._sample_rate as usize) as u32)) + Some(Duration::new(0, (self.sample.repeat_length as usize * 1_000_000_000 / self._sample_rate as usize) as u32)) } } \ No newline at end of file diff --git a/src/tracker.rs b/src/tracker.rs index f6c5514..2bc45e9 100644 --- a/src/tracker.rs +++ b/src/tracker.rs @@ -3,7 +3,7 @@ use std::io::BufReader; use std::time::Duration; use modfile::ptmf; use rodio::{OutputStream, OutputStreamHandle, Sink, Source}; -use rodio::source::SineWave; +use rodio::source::{SamplesConverter, SineWave}; use crate::note::Note; use crate::sampler::Sample; @@ -104,7 +104,7 @@ impl Tracker { pub fn load_file(&mut self, file: &str) { let mut reader = BufReader::new(File::open(file).unwrap()); - let mut module = ptmf::read_mod(&mut reader, false).unwrap(); + let mut module = ptmf::read_mod(&mut reader, true).unwrap(); println!("Loading: {}", module.name); println!("\tLength: {:?}", module.length);