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 {
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user