mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Try a pure rust implementation to allow for looping correctly
This commit is contained in:
parent
a61069fb60
commit
8191de3546
|
@ -412,65 +412,31 @@ impl MixerBuffer {
|
||||||
working_buffer: &mut [Num<i16, 4>],
|
working_buffer: &mut [Num<i16, 4>],
|
||||||
channels: impl Iterator<Item = &'a mut SoundChannel>,
|
channels: impl Iterator<Item = &'a mut SoundChannel>,
|
||||||
) {
|
) {
|
||||||
|
working_buffer.fill(0.into());
|
||||||
|
|
||||||
let mut channels = channels
|
let mut channels = channels
|
||||||
.filter(|channel| !channel.is_done)
|
.filter(|channel| !channel.is_done)
|
||||||
.filter_map(|channel| {
|
.filter_map(|channel| {
|
||||||
let playback_speed = if channel.is_stereo {
|
let playback_speed = if channel.is_stereo {
|
||||||
|
if (channel.pos + 2 * self.frequency.buffer_size() as u32).floor()
|
||||||
|
>= channel.data.len() as u32
|
||||||
|
{
|
||||||
|
if channel.should_loop {
|
||||||
|
channel.pos = 0.into();
|
||||||
|
} else {
|
||||||
|
channel.is_done = true;
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
2.into()
|
2.into()
|
||||||
} else {
|
} else {
|
||||||
channel.playback_speed
|
channel.playback_speed
|
||||||
};
|
};
|
||||||
|
|
||||||
if (channel.pos + playback_speed * self.frequency.buffer_size() as u32).floor()
|
|
||||||
>= channel.data.len() as u32
|
|
||||||
{
|
|
||||||
// TODO: This should probably play what's left rather than skip the last bit
|
|
||||||
if channel.should_loop {
|
|
||||||
channel.pos = 0.into();
|
|
||||||
} else {
|
|
||||||
channel.is_done = true;
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some((channel, playback_speed))
|
Some((channel, playback_speed))
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((channel, playback_speed)) = channels.next() {
|
|
||||||
if channel.volume != 0.into() {
|
|
||||||
if channel.is_stereo {
|
|
||||||
unsafe {
|
|
||||||
agb_rs__mixer_add_stereo_first(
|
|
||||||
channel.data.as_ptr().add(channel.pos.floor() as usize),
|
|
||||||
working_buffer.as_mut_ptr(),
|
|
||||||
channel.volume,
|
|
||||||
self.frequency.buffer_size(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let right_amount = ((channel.panning + 1) / 2) * channel.volume;
|
|
||||||
let left_amount = ((-channel.panning + 1) / 2) * channel.volume;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
agb_rs__mixer_add_first(
|
|
||||||
channel.data.as_ptr().add(channel.pos.floor() as usize),
|
|
||||||
working_buffer.as_mut_ptr(),
|
|
||||||
playback_speed,
|
|
||||||
left_amount,
|
|
||||||
right_amount,
|
|
||||||
self.frequency.buffer_size(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
working_buffer.fill(0.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.pos += playback_speed * self.frequency.buffer_size() as u32;
|
|
||||||
} else {
|
|
||||||
working_buffer.fill(0.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (channel, playback_speed) in channels {
|
for (channel, playback_speed) in channels {
|
||||||
if channel.volume != 0.into() {
|
if channel.volume != 0.into() {
|
||||||
if channel.is_stereo {
|
if channel.is_stereo {
|
||||||
|
@ -486,15 +452,24 @@ impl MixerBuffer {
|
||||||
let right_amount = ((channel.panning + 1) / 2) * channel.volume;
|
let right_amount = ((channel.panning + 1) / 2) * channel.volume;
|
||||||
let left_amount = ((-channel.panning + 1) / 2) * channel.volume;
|
let left_amount = ((-channel.panning + 1) / 2) * channel.volume;
|
||||||
|
|
||||||
unsafe {
|
let channel_len = Num::<u32, 8>::new(channel.data.len() as u32);
|
||||||
agb_rs__mixer_add(
|
|
||||||
channel.data.as_ptr().add(channel.pos.floor() as usize),
|
'outer: for i in 0..self.frequency.buffer_size() {
|
||||||
working_buffer.as_mut_ptr(),
|
while channel.pos >= channel_len {
|
||||||
playback_speed,
|
if channel.should_loop {
|
||||||
left_amount,
|
channel.pos -= channel_len;
|
||||||
right_amount,
|
} else {
|
||||||
self.frequency.buffer_size(),
|
channel.is_done = true;
|
||||||
);
|
break 'outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = channel.data[channel.pos.floor() as usize] as i8 as i16;
|
||||||
|
|
||||||
|
working_buffer[2 * i] += left_amount * value;
|
||||||
|
working_buffer[2 * i + 1] += right_amount * value;
|
||||||
|
|
||||||
|
channel.pos += playback_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
let relative_note = sample.relative_note;
|
let relative_note = sample.relative_note;
|
||||||
let volume = sample.volume as f64;
|
let volume = sample.volume as f64;
|
||||||
|
|
||||||
let mut sample = match &sample.data {
|
let sample = match &sample.data {
|
||||||
SampleDataType::Depth8(depth8) => {
|
SampleDataType::Depth8(depth8) => {
|
||||||
depth8.iter().map(|value| *value as u8).collect::<Vec<_>>()
|
depth8.iter().map(|value| *value as u8).collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
@ -77,15 +77,6 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if should_loop {
|
|
||||||
sample.append(&mut sample.clone());
|
|
||||||
sample.append(&mut sample.clone());
|
|
||||||
sample.append(&mut sample.clone());
|
|
||||||
sample.append(&mut sample.clone());
|
|
||||||
sample.append(&mut sample.clone());
|
|
||||||
sample.append(&mut sample.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
instruments_map.insert((instrument_index, sample_index), samples.len());
|
instruments_map.insert((instrument_index, sample_index), samples.len());
|
||||||
samples.push(SampleData {
|
samples.push(SampleData {
|
||||||
data: sample,
|
data: sample,
|
||||||
|
|
Loading…
Reference in a new issue