mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Properly implement delay and envelopes
This commit is contained in:
parent
5494ae29e1
commit
352b352b27
|
@ -406,11 +406,12 @@ impl TrackerChannel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatternEffect::NoteDelay(wait) => {
|
PatternEffect::NoteDelay(wait) => {
|
||||||
if tick <= *wait {
|
if tick < *wait {
|
||||||
channel.volume(0);
|
channel.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
if tick == *wait + 1 {
|
if tick == *wait {
|
||||||
|
channel.resume();
|
||||||
channel.volume((self.volume * global_settings.volume).try_change_base().unwrap());
|
channel.volume((self.volume * global_settings.volume).try_change_base().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,33 +524,41 @@ impl EnvelopeData {
|
||||||
fn new(e: &xmrs::envelope::Envelope, bpm: u32) -> Self {
|
fn new(e: &xmrs::envelope::Envelope, bpm: u32) -> Self {
|
||||||
let mut amounts = vec![];
|
let mut amounts = vec![];
|
||||||
|
|
||||||
// FT2 manual says number of ticks / second = BPM * 0.4 = BPM * 4 / 10. GBA runs at 60Hz
|
for frame in 0..=(Self::envelope_frame_to_gba_frame(e.point.last().unwrap().frame, bpm)) {
|
||||||
for frame in 0..(e.point.last().unwrap().frame as u32 * 60 * 10 / bpm / 4) {
|
let xm_frame = Self::gba_frame_to_envelope_frame(frame, bpm);
|
||||||
let xm_frame = frame * bpm * 4 / 60 / 10;
|
|
||||||
let index = e
|
let index = e
|
||||||
.point
|
.point
|
||||||
.iter()
|
.iter()
|
||||||
.rposition(|point| point.frame < xm_frame as u16)
|
.rposition(|point| point.frame < xm_frame)
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let first_point = &e.point[index];
|
let first_point = &e.point[index];
|
||||||
let second_point = &e.point[index + 1];
|
let second_point = &e.point[index + 1];
|
||||||
|
|
||||||
let amount = EnvelopePoint::lerp(first_point, second_point, xm_frame as u16) / 64.0;
|
let amount = EnvelopePoint::lerp(first_point, second_point, xm_frame) / 64.0;
|
||||||
let amount = Num::from_f32(amount);
|
let amount = Num::from_f32(amount);
|
||||||
|
|
||||||
amounts.push(amount);
|
amounts.push(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
let sustain = if e.sustain_enabled {
|
let sustain = if e.sustain_enabled {
|
||||||
Some(e.point[e.sustain_point as usize].frame as usize * 60 / 50)
|
Some(
|
||||||
|
Self::envelope_frame_to_gba_frame(e.point[e.sustain_point as usize].frame, bpm)
|
||||||
|
as usize,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let (loop_start, loop_end) = if e.loop_enabled {
|
let (loop_start, loop_end) = if e.loop_enabled {
|
||||||
(
|
(
|
||||||
Some(e.point[e.loop_start_point as usize].frame as usize * 60 / 50),
|
Some(Self::envelope_frame_to_gba_frame(
|
||||||
Some(e.point[e.loop_end_point as usize].frame as usize * 60 / 50),
|
e.point[e.loop_start_point as usize].frame,
|
||||||
|
bpm,
|
||||||
|
) as usize),
|
||||||
|
Some(Self::envelope_frame_to_gba_frame(
|
||||||
|
e.point[e.loop_end_point as usize].frame,
|
||||||
|
bpm,
|
||||||
|
) as usize),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(None, None)
|
(None, None)
|
||||||
|
@ -563,4 +571,14 @@ impl EnvelopeData {
|
||||||
loop_end,
|
loop_end,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn envelope_frame_to_gba_frame(envelope_frame: u16, bpm: u32) -> u16 {
|
||||||
|
// FT2 manual says number of ticks / second = BPM * 0.4
|
||||||
|
// somehow this works as a good approximation :/
|
||||||
|
(envelope_frame as u32 * 250 / bpm) as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gba_frame_to_envelope_frame(gba_frame: u16, bpm: u32) -> u16 {
|
||||||
|
(gba_frame as u32 * bpm / 250) as u16
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue