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::audio::*;
|
||||||
use libretrogd::graphics::*;
|
use libretrogd::graphics::*;
|
||||||
use libretrogd::system::*;
|
use libretrogd::system::*;
|
||||||
|
use libretrogd::utils::rnd_value;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
struct AudioChannelStatus {
|
struct AudioChannelStatus {
|
||||||
|
@ -58,11 +59,13 @@ fn main() -> Result<()> {
|
||||||
|
|
||||||
let mut is_running = true;
|
let mut is_running = true;
|
||||||
|
|
||||||
let sound1 = load_and_convert_wav(Path::new("./assets/pickup-coin.wav"), system.audio.spec())?;
|
let sounds = [
|
||||||
let sound2 = load_and_convert_wav(Path::new("./assets/powerup.wav"), system.audio.spec())?;
|
load_and_convert_wav(Path::new("./assets/pickup-coin.wav"), system.audio.spec())?,
|
||||||
let sound3 = load_and_convert_wav(Path::new("./assets/explosion.wav"), system.audio.spec())?;
|
load_and_convert_wav(Path::new("./assets/powerup.wav"), system.audio.spec())?,
|
||||||
let sound4 = load_and_convert_wav(Path::new("./assets/jump.wav"), system.audio.spec())?;
|
load_and_convert_wav(Path::new("./assets/explosion.wav"), system.audio.spec())?,
|
||||||
let sound5 = load_and_convert_wav(Path::new("./assets/laser-shoot.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];
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
if system.keyboard.is_key_pressed(Scancode::Num6) {
|
||||||
audio_device.play_generator(SineWaveGenerator::new(), false);
|
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 {
|
for index in 0..NUM_CHANNELS {
|
||||||
let channel = &audio_device[index];
|
let channel = &audio_device[index];
|
||||||
let mut status = &mut statuses[index];
|
let mut status = &mut statuses[index];
|
||||||
|
|
|
@ -188,6 +188,9 @@ impl AudioChannel {
|
||||||
pub enum AudioDeviceError {
|
pub enum AudioDeviceError {
|
||||||
#[error("That buffer's AudioSpec does not match the device's AudioSpec")]
|
#[error("That buffer's AudioSpec does not match the device's AudioSpec")]
|
||||||
AudioSpecMismatch,
|
AudioSpecMismatch,
|
||||||
|
|
||||||
|
#[error("The channel index {0} is out of range")]
|
||||||
|
ChannelIndexOutOfRange(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AudioDevice {
|
pub struct AudioDevice {
|
||||||
|
@ -230,6 +233,15 @@ impl AudioDevice {
|
||||||
self.channels.iter().any(|channel| channel.playing)
|
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) {
|
pub fn stop_all(&mut self) {
|
||||||
for channel in self.channels.iter_mut() {
|
for channel in self.channels.iter_mut() {
|
||||||
channel.stop();
|
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() {
|
if let Some(channel) = self.stopped_channels_iter_mut().next() {
|
||||||
channel.play_generator(generator, loops);
|
channel.play_generator(generator, loops);
|
||||||
Ok(Some(channel))
|
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]
|
#[inline]
|
||||||
pub fn playing_channels_iter(&mut self) -> impl Iterator<Item = &AudioChannel> {
|
pub fn playing_channels_iter(&mut self) -> impl Iterator<Item = &AudioChannel> {
|
||||||
self.channels.iter().filter(|channel| channel.playing)
|
self.channels.iter().filter(|channel| channel.playing)
|
||||||
|
|
Loading…
Reference in a new issue