This sounds pretty decent now

This commit is contained in:
Gwilym Inzani 2023-08-05 00:24:11 +01:00
parent 47455a0377
commit aabfb1b083
2 changed files with 28 additions and 9 deletions

View file

@ -112,6 +112,7 @@ struct TrackerChannel {
struct EnvelopeState {
frame: usize,
envelope_id: usize,
finished: bool,
}
#[derive(Clone)]
@ -167,10 +168,16 @@ impl Tracker {
let pattern_slots =
&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) {
for (i, (channel, pattern_slot)) in self.channels.iter_mut().zip(pattern_slots).enumerate()
{
if pattern_slot.sample != 0 && self.tick == 0 {
let sample = &self.track.samples[pattern_slot.sample as usize - 1];
channel.play_sound(mixer, sample);
self.envelopes[i] = sample.volume_envelope.map(|envelope_id| EnvelopeState {
frame: 0,
envelope_id,
finished: false,
});
}
if self.tick == 0 {
@ -182,12 +189,14 @@ impl Tracker {
&pattern_slot.effect1,
self.tick,
&mut self.global_settings,
&mut self.envelopes[i],
);
channel.apply_effect(
mixer,
&pattern_slot.effect2,
self.tick,
&mut self.global_settings,
&mut self.envelopes[i],
);
}
@ -204,11 +213,13 @@ impl Tracker {
} else {
envelope_state.frame += 1;
if !envelope_state.finished {
if let Some(sustain) = envelope.sustain {
if envelope_state.frame >= sustain {
envelope_state.frame = sustain;
}
}
}
if let Some(loop_end) = envelope.loop_end {
if envelope_state.frame >= loop_end {
@ -304,6 +315,7 @@ impl TrackerChannel {
effect: &PatternEffect,
tick: u32,
global_settings: &mut GlobalSettings,
envelope_state: &mut Option<EnvelopeState>,
) {
if let Some(channel) = self
.channel_id
@ -314,6 +326,9 @@ impl TrackerChannel {
PatternEffect::None => {}
PatternEffect::Stop => {
channel.volume(0);
if let Some(envelope_state) = envelope_state {
envelope_state.finished = true;
}
}
PatternEffect::Arpeggio(first, second) => {
match tick % 3 {
@ -345,6 +360,10 @@ impl TrackerChannel {
PatternEffect::NoteCut(wait) => {
if tick == *wait {
channel.volume(0);
if let Some(envelope_state) = envelope_state {
envelope_state.finished = true;
}
}
}
PatternEffect::Portamento(amount) => {

View file

@ -490,21 +490,21 @@ struct EnvelopeData {
impl From<&xmrs::envelope::Envelope> for EnvelopeData {
fn from(e: &xmrs::envelope::Envelope) -> Self {
let mut amounts = vec![Num::new(e.point[0].value as i16) / 0xff];
let mut amounts = vec![];
// it should be sampled at 50fps, but we're sampling at 60fps, so need to do a bit of cheating here.
for frame in 1..(e.point.last().unwrap().frame * 60 / 50) {
let xm_frame = (frame * 50 / 60).max(1);
for frame in 0..(e.point.last().unwrap().frame * 60 / 50) {
let xm_frame = frame * 50 / 60;
let index = e
.point
.iter()
.rposition(|point| point.frame < xm_frame)
.unwrap();
.unwrap_or(0);
let first_point = &e.point[index];
let second_point = &e.point[index + 1];
let amount = EnvelopePoint::lerp(first_point, second_point, xm_frame) / 255.0;
let amount = EnvelopePoint::lerp(first_point, second_point, xm_frame) / 64.0;
let amount = Num::from_raw((amount * (1 << 8) as f32) as i16);
amounts.push(amount);