mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
This sounds pretty decent now
This commit is contained in:
parent
47455a0377
commit
aabfb1b083
|
@ -112,6 +112,7 @@ struct TrackerChannel {
|
||||||
struct EnvelopeState {
|
struct EnvelopeState {
|
||||||
frame: usize,
|
frame: usize,
|
||||||
envelope_id: usize,
|
envelope_id: usize,
|
||||||
|
finished: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -167,10 +168,16 @@ 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) {
|
for (i, (channel, pattern_slot)) in self.channels.iter_mut().zip(pattern_slots).enumerate()
|
||||||
|
{
|
||||||
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);
|
||||||
|
self.envelopes[i] = sample.volume_envelope.map(|envelope_id| EnvelopeState {
|
||||||
|
frame: 0,
|
||||||
|
envelope_id,
|
||||||
|
finished: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tick == 0 {
|
if self.tick == 0 {
|
||||||
|
@ -182,12 +189,14 @@ impl Tracker {
|
||||||
&pattern_slot.effect1,
|
&pattern_slot.effect1,
|
||||||
self.tick,
|
self.tick,
|
||||||
&mut self.global_settings,
|
&mut self.global_settings,
|
||||||
|
&mut self.envelopes[i],
|
||||||
);
|
);
|
||||||
channel.apply_effect(
|
channel.apply_effect(
|
||||||
mixer,
|
mixer,
|
||||||
&pattern_slot.effect2,
|
&pattern_slot.effect2,
|
||||||
self.tick,
|
self.tick,
|
||||||
&mut self.global_settings,
|
&mut self.global_settings,
|
||||||
|
&mut self.envelopes[i],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,11 +213,13 @@ impl Tracker {
|
||||||
} else {
|
} else {
|
||||||
envelope_state.frame += 1;
|
envelope_state.frame += 1;
|
||||||
|
|
||||||
|
if !envelope_state.finished {
|
||||||
if let Some(sustain) = envelope.sustain {
|
if let Some(sustain) = envelope.sustain {
|
||||||
if envelope_state.frame >= sustain {
|
if envelope_state.frame >= sustain {
|
||||||
envelope_state.frame = sustain;
|
envelope_state.frame = sustain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(loop_end) = envelope.loop_end {
|
if let Some(loop_end) = envelope.loop_end {
|
||||||
if envelope_state.frame >= loop_end {
|
if envelope_state.frame >= loop_end {
|
||||||
|
@ -304,6 +315,7 @@ impl TrackerChannel {
|
||||||
effect: &PatternEffect,
|
effect: &PatternEffect,
|
||||||
tick: u32,
|
tick: u32,
|
||||||
global_settings: &mut GlobalSettings,
|
global_settings: &mut GlobalSettings,
|
||||||
|
envelope_state: &mut Option<EnvelopeState>,
|
||||||
) {
|
) {
|
||||||
if let Some(channel) = self
|
if let Some(channel) = self
|
||||||
.channel_id
|
.channel_id
|
||||||
|
@ -314,6 +326,9 @@ impl TrackerChannel {
|
||||||
PatternEffect::None => {}
|
PatternEffect::None => {}
|
||||||
PatternEffect::Stop => {
|
PatternEffect::Stop => {
|
||||||
channel.volume(0);
|
channel.volume(0);
|
||||||
|
if let Some(envelope_state) = envelope_state {
|
||||||
|
envelope_state.finished = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PatternEffect::Arpeggio(first, second) => {
|
PatternEffect::Arpeggio(first, second) => {
|
||||||
match tick % 3 {
|
match tick % 3 {
|
||||||
|
@ -345,6 +360,10 @@ impl TrackerChannel {
|
||||||
PatternEffect::NoteCut(wait) => {
|
PatternEffect::NoteCut(wait) => {
|
||||||
if tick == *wait {
|
if tick == *wait {
|
||||||
channel.volume(0);
|
channel.volume(0);
|
||||||
|
|
||||||
|
if let Some(envelope_state) = envelope_state {
|
||||||
|
envelope_state.finished = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatternEffect::Portamento(amount) => {
|
PatternEffect::Portamento(amount) => {
|
||||||
|
|
|
@ -490,21 +490,21 @@ struct EnvelopeData {
|
||||||
|
|
||||||
impl From<&xmrs::envelope::Envelope> for EnvelopeData {
|
impl From<&xmrs::envelope::Envelope> for EnvelopeData {
|
||||||
fn from(e: &xmrs::envelope::Envelope) -> Self {
|
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.
|
// 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) {
|
for frame in 0..(e.point.last().unwrap().frame * 60 / 50) {
|
||||||
let xm_frame = (frame * 50 / 60).max(1);
|
let xm_frame = frame * 50 / 60;
|
||||||
let index = e
|
let index = e
|
||||||
.point
|
.point
|
||||||
.iter()
|
.iter()
|
||||||
.rposition(|point| point.frame < xm_frame)
|
.rposition(|point| point.frame < xm_frame)
|
||||||
.unwrap();
|
.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) / 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);
|
let amount = Num::from_raw((amount * (1 << 8) as f32) as i16);
|
||||||
|
|
||||||
amounts.push(amount);
|
amounts.push(amount);
|
||||||
|
|
Loading…
Reference in a new issue