Improve accuracy of the volume

This commit is contained in:
Gwilym Inzani 2023-07-23 22:10:25 +01:00
parent 095723bbf8
commit d233a2539c
3 changed files with 20 additions and 20 deletions

View file

@ -19,7 +19,7 @@ pub struct Sample<'a> {
pub data: &'a [u8], pub data: &'a [u8],
pub should_loop: bool, pub should_loop: bool,
pub restart_point: u32, pub restart_point: u32,
pub volume: Num<i16, 4>, pub volume: Num<i16, 8>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -46,9 +46,9 @@ pub enum PatternEffect {
/// Plays an arpeggiation of three notes in one row, cycling betwen the current note, current note + first speed, current note + second speed /// Plays an arpeggiation of three notes in one row, cycling betwen the current note, current note + first speed, current note + second speed
Arpeggio(Num<u16, 8>, Num<u16, 8>), Arpeggio(Num<u16, 8>, Num<u16, 8>),
Panning(Num<i16, 4>), Panning(Num<i16, 4>),
Volume(Num<i16, 4>), Volume(Num<i16, 8>),
VolumeSlide(Num<i16, 4>), VolumeSlide(Num<i16, 8>),
FineVolumeSlide(Num<i16, 4>), FineVolumeSlide(Num<i16, 8>),
NoteCut(u32), NoteCut(u32),
Portamento(Num<u16, 8>), Portamento(Num<u16, 8>),
/// Slide each tick the first amount to at most the second amount /// Slide each tick the first amount to at most the second amount

View file

@ -102,7 +102,7 @@ pub struct Tracker {
struct TrackerChannel { struct TrackerChannel {
channel_id: Option<ChannelId>, channel_id: Option<ChannelId>,
base_speed: Num<u32, 8>, base_speed: Num<u32, 8>,
volume: Num<i16, 4>, volume: Num<i32, 8>,
} }
impl Tracker { impl Tracker {
@ -143,7 +143,7 @@ impl Tracker {
let pattern_slots = let pattern_slots =
&self.track.pattern_data[pattern_data_pos..pattern_data_pos + self.track.num_channels]; &self.track.pattern_data[pattern_data_pos..pattern_data_pos + self.track.num_channels];
for (channel, pattern_slot) in self.channels.iter_mut().zip(pattern_slots).skip(3) { for (channel, pattern_slot) in self.channels.iter_mut().zip(pattern_slots) {
if pattern_slot.sample != 0 && self.tick == 0 { if pattern_slot.sample != 0 && self.tick == 0 {
let sample = &self.track.samples[pattern_slot.sample as usize - 1]; let sample = &self.track.samples[pattern_slot.sample as usize - 1];
channel.play_sound(mixer, sample); channel.play_sound(mixer, sample);
@ -210,7 +210,7 @@ impl TrackerChannel {
let mut new_channel = SoundChannel::new(sample.data); let mut new_channel = SoundChannel::new(sample.data);
new_channel.volume(sample.volume); new_channel.volume(sample.volume.change_base());
if sample.should_loop { if sample.should_loop {
new_channel new_channel
@ -219,7 +219,7 @@ impl TrackerChannel {
} }
self.channel_id = mixer.play_sound(new_channel); self.channel_id = mixer.play_sound(new_channel);
self.volume = sample.volume; self.volume = sample.volume.change_base();
} }
fn set_speed(&mut self, mixer: &mut Mixer<'_>, speed: Num<u32, 8>) { fn set_speed(&mut self, mixer: &mut Mixer<'_>, speed: Num<u32, 8>) {
@ -259,19 +259,19 @@ impl TrackerChannel {
channel.panning(*panning); channel.panning(*panning);
} }
PatternEffect::Volume(volume) => { PatternEffect::Volume(volume) => {
channel.volume(*volume); channel.volume(volume.change_base());
self.volume = *volume; self.volume = volume.change_base();
} }
PatternEffect::VolumeSlide(amount) => { PatternEffect::VolumeSlide(amount) => {
if tick != 0 { if tick != 0 {
self.volume = (self.volume + *amount).max(0.into()); self.volume = (self.volume + amount.change_base()).max(0.into());
channel.volume(self.volume); channel.volume(self.volume.try_change_base().unwrap());
} }
} }
PatternEffect::FineVolumeSlide(amount) => { PatternEffect::FineVolumeSlide(amount) => {
if tick == 0 { if tick == 0 {
self.volume = (self.volume + *amount).max(0.into()); self.volume = (self.volume + amount.change_base()).max(0.into());
channel.volume(self.volume); channel.volume(self.volume.try_change_base().unwrap());
} }
} }
PatternEffect::NoteCut(wait) => { PatternEffect::NoteCut(wait) => {

View file

@ -55,7 +55,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
fine_tune: f64, fine_tune: f64,
relative_note: i8, relative_note: i8,
restart_point: u32, restart_point: u32,
volume: Num<i16, 4>, volume: Num<i16, 8>,
} }
let mut samples = vec![]; let mut samples = vec![];
@ -76,7 +76,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
usize::MAX usize::MAX
}; };
let volume = Num::from_raw((sample.volume * (1 << 4) as f32) as i16); let volume = Num::from_raw((sample.volume * (1 << 8) as f32) as i16);
let sample = match &sample.data { let sample = match &sample.data {
SampleDataType::Depth8(depth8) => depth8 SampleDataType::Depth8(depth8) => depth8
@ -163,10 +163,10 @@ pub fn parse_module(module: &Module) -> TokenStream {
.unwrap_or(1.into()), .unwrap_or(1.into()),
), ),
0x80..=0x8F => PatternEffect::FineVolumeSlide( 0x80..=0x8F => PatternEffect::FineVolumeSlide(
-Num::new((slot.volume - 0x80) as i16) / 16, -Num::new((slot.volume - 0x80) as i16) / 64,
), ),
0x90..=0x9F => PatternEffect::FineVolumeSlide( 0x90..=0x9F => PatternEffect::FineVolumeSlide(
Num::new((slot.volume - 0x90) as i16) / 16, Num::new((slot.volume - 0x90) as i16) / 64,
), ),
0xC0..=0xCF => PatternEffect::Panning( 0xC0..=0xCF => PatternEffect::Panning(
Num::new(slot.volume as i16 - (0xC0 + (0xCF - 0xC0) / 2)) / 64, Num::new(slot.volume as i16 - (0xC0 + (0xCF - 0xC0) / 2)) / 64,
@ -299,10 +299,10 @@ pub fn parse_module(module: &Module) -> TokenStream {
} }
0xE => match slot.effect_parameter >> 4 { 0xE => match slot.effect_parameter >> 4 {
0xA => PatternEffect::FineVolumeSlide( 0xA => PatternEffect::FineVolumeSlide(
Num::new((slot.effect_parameter & 0xf) as i16) / 16, Num::new((slot.effect_parameter & 0xf) as i16) / 64,
), ),
0xB => PatternEffect::FineVolumeSlide( 0xB => PatternEffect::FineVolumeSlide(
-Num::new((slot.effect_parameter & 0xf) as i16) / 16, -Num::new((slot.effect_parameter & 0xf) as i16) / 64,
), ),
0xC => PatternEffect::NoteCut((slot.effect_parameter & 0xf).into()), 0xC => PatternEffect::NoteCut((slot.effect_parameter & 0xf).into()),
_ => PatternEffect::None, _ => PatternEffect::None,