Made samples kind of smoother? TODO: Add some effects to cover the bad parts up :D
This commit is contained in:
@@ -6,17 +6,29 @@ use rodio::Source;
|
||||
pub struct Sample {
|
||||
num_sample: usize,
|
||||
_sample_rate: u32,
|
||||
_sample_rate_multiplier: u32,
|
||||
sample: SampleInfo,
|
||||
data: Vec<u16>,
|
||||
}
|
||||
|
||||
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 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<Self::Item> {
|
||||
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<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 sample_rate(&self) -> u32 {
|
||||
self._sample_rate
|
||||
self._sample_rate*self._sample_rate_multiplier
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user