Made samples kind of smoother? TODO: Add some effects to cover the bad parts up :D

This commit is contained in:
2023-02-05 04:32:36 +01:00
parent 8dd99a5ead
commit 15921ffcc9
2 changed files with 35 additions and 13 deletions

View File

@@ -6,17 +6,29 @@ use rodio::Source;
pub struct Sample { pub struct Sample {
num_sample: usize, num_sample: usize,
_sample_rate: u32, _sample_rate: u32,
_sample_rate_multiplier: u32,
sample: SampleInfo, sample: SampleInfo,
data: Vec<u16>,
} }
impl Sample { 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<u16> = 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 data len: {}", sample.data.len());
println!("Sample reported len: {}", sample.length); println!("Sample reported len: {}", sample.length);
Self { Self {
num_sample: 0, num_sample: 0,
_sample_rate: sample_rate, _sample_rate: sample_rate,
_sample_rate_multiplier: 256,
sample, sample,
data,
} }
} }
@@ -36,33 +48,43 @@ impl Sample {
} }
impl Iterator for Sample { impl Iterator for Sample {
type Item = f32; type Item = u16;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if self.sample.data.len() == 0 { if self.data.len() == 0 {
return Some(0.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); self.num_sample = self.num_sample.wrapping_add(1);
if self.num_sample >= self.sample.data.len() { if self.num_sample >= self.sample.repeat_length as usize * 2 * self._sample_rate_multiplier as usize {
self.num_sample = 0; 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 { impl Source for Sample {
fn current_frame_len(&self) -> Option<usize> { fn current_frame_len(&self) -> Option<usize> {
Some(self.sample.data.len()-self.num_sample) Some(self.sample.repeat_length as usize - self.num_sample)
} }
fn channels(&self) -> u16 { 1 } fn channels(&self) -> u16 { 1 }
fn sample_rate(&self) -> u32 { fn sample_rate(&self) -> u32 {
self._sample_rate self._sample_rate*self._sample_rate_multiplier
} }
fn total_duration(&self) -> Option<Duration> { fn total_duration(&self) -> Option<Duration> {
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))
} }
} }

View File

@@ -3,7 +3,7 @@ use std::io::BufReader;
use std::time::Duration; use std::time::Duration;
use modfile::ptmf; use modfile::ptmf;
use rodio::{OutputStream, OutputStreamHandle, Sink, Source}; use rodio::{OutputStream, OutputStreamHandle, Sink, Source};
use rodio::source::SineWave; use rodio::source::{SamplesConverter, SineWave};
use crate::note::Note; use crate::note::Note;
use crate::sampler::Sample; use crate::sampler::Sample;
@@ -104,7 +104,7 @@ impl Tracker {
pub fn load_file(&mut self, file: &str) { pub fn load_file(&mut self, file: &str) {
let mut reader = BufReader::new(File::open(file).unwrap()); 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!("Loading: {}", module.name);
println!("\tLength: {:?}", module.length); println!("\tLength: {:?}", module.length);