convenience methods for playing/stopping specific audio channels
This commit is contained in:
parent
5f5bc79d86
commit
13b18e3d71
|
@ -7,6 +7,7 @@ use sdl2::keyboard::Scancode;
|
|||
use libretrogd::audio::*;
|
||||
use libretrogd::graphics::*;
|
||||
use libretrogd::system::*;
|
||||
use libretrogd::utils::rnd_value;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct AudioChannelStatus {
|
||||
|
@ -58,11 +59,13 @@ fn main() -> Result<()> {
|
|||
|
||||
let mut is_running = true;
|
||||
|
||||
let sound1 = load_and_convert_wav(Path::new("./assets/pickup-coin.wav"), system.audio.spec())?;
|
||||
let sound2 = load_and_convert_wav(Path::new("./assets/powerup.wav"), system.audio.spec())?;
|
||||
let sound3 = load_and_convert_wav(Path::new("./assets/explosion.wav"), system.audio.spec())?;
|
||||
let sound4 = load_and_convert_wav(Path::new("./assets/jump.wav"), system.audio.spec())?;
|
||||
let sound5 = load_and_convert_wav(Path::new("./assets/laser-shoot.wav"), system.audio.spec())?;
|
||||
let sounds = [
|
||||
load_and_convert_wav(Path::new("./assets/pickup-coin.wav"), system.audio.spec())?,
|
||||
load_and_convert_wav(Path::new("./assets/powerup.wav"), system.audio.spec())?,
|
||||
load_and_convert_wav(Path::new("./assets/explosion.wav"), system.audio.spec())?,
|
||||
load_and_convert_wav(Path::new("./assets/jump.wav"), system.audio.spec())?,
|
||||
load_and_convert_wav(Path::new("./assets/laser-shoot.wav"), system.audio.spec())?,
|
||||
];
|
||||
|
||||
let mut statuses = [AudioChannelStatus { size: 0, position: 0, playing: false }; NUM_CHANNELS];
|
||||
|
||||
|
@ -80,29 +83,34 @@ fn main() -> Result<()> {
|
|||
}
|
||||
|
||||
if system.keyboard.is_key_pressed(Scancode::Num1) {
|
||||
audio_device.play_buffer(&sound1, false)?;
|
||||
audio_device.play_buffer(&sounds[0], false)?;
|
||||
}
|
||||
|
||||
if system.keyboard.is_key_pressed(Scancode::Num2) {
|
||||
audio_device.play_buffer(&sound2, false)?;
|
||||
audio_device.play_buffer(&sounds[1], false)?;
|
||||
}
|
||||
|
||||
if system.keyboard.is_key_pressed(Scancode::Num3) {
|
||||
audio_device.play_buffer(&sound3, false)?;
|
||||
audio_device.play_buffer(&sounds[2], false)?;
|
||||
}
|
||||
|
||||
if system.keyboard.is_key_pressed(Scancode::Num4) {
|
||||
audio_device.play_buffer(&sound4, false)?;
|
||||
audio_device.play_buffer(&sounds[3], false)?;
|
||||
}
|
||||
|
||||
if system.keyboard.is_key_pressed(Scancode::Num5) {
|
||||
audio_device.play_buffer(&sound5, false)?;
|
||||
audio_device.play_buffer(&sounds[4], false)?;
|
||||
}
|
||||
|
||||
if system.keyboard.is_key_pressed(Scancode::Num6) {
|
||||
audio_device.play_generator(SineWaveGenerator::new(), false);
|
||||
}
|
||||
|
||||
if system.keyboard.is_key_pressed(Scancode::Num7) {
|
||||
let index = rnd_value(0, sounds.len() - 1);
|
||||
audio_device.play_buffer_on_channel(7, &sounds[index], false)?;
|
||||
}
|
||||
|
||||
for index in 0..NUM_CHANNELS {
|
||||
let channel = &audio_device[index];
|
||||
let mut status = &mut statuses[index];
|
||||
|
|
|
@ -188,6 +188,9 @@ impl AudioChannel {
|
|||
pub enum AudioDeviceError {
|
||||
#[error("That buffer's AudioSpec does not match the device's AudioSpec")]
|
||||
AudioSpecMismatch,
|
||||
|
||||
#[error("The channel index {0} is out of range")]
|
||||
ChannelIndexOutOfRange(usize),
|
||||
}
|
||||
|
||||
pub struct AudioDevice {
|
||||
|
@ -230,6 +233,15 @@ impl AudioDevice {
|
|||
self.channels.iter().any(|channel| channel.playing)
|
||||
}
|
||||
|
||||
pub fn stop_channel(&mut self, channel_index: usize) -> Result<(), AudioDeviceError> {
|
||||
if channel_index >= NUM_CHANNELS {
|
||||
Err(AudioDeviceError::ChannelIndexOutOfRange(channel_index))
|
||||
} else {
|
||||
self.channels[channel_index].stop();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop_all(&mut self) {
|
||||
for channel in self.channels.iter_mut() {
|
||||
channel.stop();
|
||||
|
@ -253,7 +265,27 @@ impl AudioDevice {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn play_generator(&mut self, generator: impl AudioGenerator + 'static, loops: bool) -> Result<Option<&mut AudioChannel>, AudioDeviceError> {
|
||||
pub fn play_buffer_on_channel(
|
||||
&mut self,
|
||||
channel_index: usize,
|
||||
buffer: &AudioBuffer,
|
||||
loops: bool,
|
||||
) -> Result<(), AudioDeviceError> {
|
||||
if buffer.spec != self.spec {
|
||||
Err(AudioDeviceError::AudioSpecMismatch)
|
||||
} else if channel_index >= NUM_CHANNELS {
|
||||
Err(AudioDeviceError::ChannelIndexOutOfRange(channel_index))
|
||||
} else {
|
||||
self.channels[channel_index].play_buffer(buffer, loops);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play_generator(
|
||||
&mut self,
|
||||
generator: impl AudioGenerator + 'static,
|
||||
loops: bool,
|
||||
) -> Result<Option<&mut AudioChannel>, AudioDeviceError> {
|
||||
if let Some(channel) = self.stopped_channels_iter_mut().next() {
|
||||
channel.play_generator(generator, loops);
|
||||
Ok(Some(channel))
|
||||
|
@ -262,6 +294,20 @@ impl AudioDevice {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn play_generator_on_channel(
|
||||
&mut self,
|
||||
channel_index: usize,
|
||||
generator: impl AudioGenerator + 'static,
|
||||
loops: bool,
|
||||
) -> Result<(), AudioDeviceError> {
|
||||
if channel_index >= NUM_CHANNELS {
|
||||
Err(AudioDeviceError::ChannelIndexOutOfRange(channel_index))
|
||||
} else {
|
||||
self.channels[channel_index].play_generator(generator, loops);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn playing_channels_iter(&mut self) -> impl Iterator<Item = &AudioChannel> {
|
||||
self.channels.iter().filter(|channel| channel.playing)
|
||||
|
|
Loading…
Reference in a new issue