Skip to content

Commit

Permalink
Add more OpenAL backend
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkleiny committed Jul 19, 2024
1 parent ff7e306 commit 6d6407c
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 39 deletions.
131 changes: 107 additions & 24 deletions backends/sdl/src/audio.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Audio backend for SDL2

pub use audio::*;
use common::Vec3;
use openal_sys::{
alBufferData, alDeleteSources, alGenBuffers, alGenSources, alGetSourcei, alSource3f, alSourcef, alSourcei,
ALCcontext, ALCdevice, ALint, ALuint,
alBufferData, alDeleteSources, alGenBuffers, alGenSources, alGetSourcef, alGetSourcefv, alGetSourcei, alSource3f,
alSourcePlay, alSourcef, alSourcei, ALCcontext, ALCdevice, ALboolean, ALfloat, ALint, ALuint,
};

// TODO: finish implementing me

/// An audio backend for SDL2.
pub struct SdlAudioBackend {
device: *mut ALCdevice,
Expand Down Expand Up @@ -50,10 +49,8 @@ impl AudioBackend for SdlAudioBackend {

fn buffer_write_data(&self, buffer: BufferId, sampler_rate: AudioSampleRate, data: &[u8]) -> Result<(), BufferError> {
unsafe {
let buffer = buffer.into();

alBufferData(
buffer,
buffer.into(),
openal_sys::AL_FORMAT_MONO16,
data.as_ptr() as *const _,
data.len() as i32,
Expand Down Expand Up @@ -103,6 +100,7 @@ impl AudioBackend for SdlAudioBackend {
let mut source: ALuint = 0;

alGenSources(1, &mut source as *mut _);

alSourcef(source, openal_sys::AL_GAIN, 1.0);
alSourcef(source, openal_sys::AL_PITCH, 1.0);
alSource3f(source, openal_sys::AL_POSITION, 0.0, 0.0, 0.0);
Expand All @@ -119,10 +117,9 @@ impl AudioBackend for SdlAudioBackend {

fn source_is_playing(&self, source: SourceId) -> Option<bool> {
unsafe {
let source = source.into();
let mut state: ALint = 0;

alGetSourcei(source, openal_sys::AL_SOURCE_STATE, &mut state as *mut _);
alGetSourcei(source.into(), openal_sys::AL_SOURCE_STATE, &mut state as *mut _);

match state {
openal_sys::AL_PLAYING => Some(true),
Expand All @@ -131,54 +128,140 @@ impl AudioBackend for SdlAudioBackend {
}
}

fn source_get_volume(&self, source: SourceId) -> Option<f32> {
fn source_get_gain(&self, source: SourceId) -> Option<f32> {
unsafe {
let source = source.into();
let mut volume: i32 = 0;
let mut gain = 0.0f32;

alGetSourcei(source, openal_sys::AL_GAIN, &mut volume as *mut _);
alGetSourcef(source.into(), openal_sys::AL_GAIN, &mut gain as *mut _);

Some(volume as f32)
Some(gain)
}
}

fn source_set_volume(&self, source: SourceId, volume: f32) -> Result<(), SourceError> {
fn source_set_gain(&self, source: SourceId, gain: f32) -> Result<(), SourceError> {
unsafe {
let source = source.into();
alSourcef(source.into(), openal_sys::AL_GAIN, gain);

Ok(())
}
}

fn source_get_pitch(&self, source: SourceId) -> Option<f32> {
unsafe {
let mut pitch = 0.0f32;

alGetSourcef(source.into(), openal_sys::AL_PITCH, &mut pitch as *mut _);

Some(pitch)
}
}

fn source_set_pitch(&self, source: SourceId, pitch: f32) -> Result<(), SourceError> {
unsafe {
alSourcef(source.into(), openal_sys::AL_PITCH, pitch);

Ok(())
}
}

fn source_get_position(&self, source: SourceId) -> Option<Vec3> {
unsafe {
let mut position = Vec3::ZERO;

alGetSourcefv(source.into(), openal_sys::AL_POSITION, &mut position.x as *mut ALfloat);

Some(position)
}
}

alSourcef(source, openal_sys::AL_GAIN, volume);
fn source_set_position(&self, source: SourceId, position: Vec3) -> Result<(), SourceError> {
unsafe {
alSource3f(
source.into(),
openal_sys::AL_POSITION,
position.x,
position.y,
position.z,
);

Ok(())
}
}

fn source_set_velocity(&self, source: SourceId, velocity: Vec3) -> Result<(), SourceError> {
unsafe {
alSource3f(
source.into(),
openal_sys::AL_VELOCITY,
velocity.x,
velocity.y,
velocity.z,
);

Ok(())
}
}

fn source_get_velocity(&self, source: SourceId) -> Option<Vec3> {
unsafe {
let mut velocity = Vec3::ZERO;

alGetSourcefv(source.into(), openal_sys::AL_VELOCITY, &mut velocity.x as *mut ALfloat);

Some(velocity)
}
}

fn source_is_looping(&self, source: SourceId) -> Option<bool> {
unsafe {
let mut looping: ALint = 0;

alGetSourcei(source.into(), openal_sys::AL_LOOPING, &mut looping as *mut _);

match looping as ALboolean {
openal_sys::AL_TRUE => Some(true),
_ => Some(false),
}
}
}

fn source_set_looping(&self, source: SourceId, looping: bool) -> Result<(), SourceError> {
unsafe {
let looping = if looping {
openal_sys::AL_TRUE
} else {
openal_sys::AL_FALSE
};

alSourcei(source.into(), openal_sys::AL_LOOPING, looping as ALint);

Ok(())
}
}

fn source_get_clip(&self, source: SourceId) -> Option<ClipId> {
unsafe {
let source = source.into();
let mut buffer: ALint = 0;

alGetSourcei(source, openal_sys::AL_BUFFER, &mut buffer as *mut _);
alGetSourcei(source.into(), openal_sys::AL_BUFFER, &mut buffer as *mut _);

Some(ClipId::from(buffer as u32))
}
}

fn source_set_clip(&self, source: SourceId, clip: ClipId) -> Result<(), SourceError> {
unsafe {
let source = source.into();
let clip = clip.into();

alSourcei(source, openal_sys::AL_BUFFER, clip);
alSourcei(source.into(), openal_sys::AL_BUFFER, clip);

Ok(())
}
}

fn source_play(&self, source: SourceId) -> Result<(), SourceError> {
unsafe {
let source = source.into();

openal_sys::alSourcePlay(source);
alSourcePlay(source.into());

Ok(())
}
Expand Down
38 changes: 35 additions & 3 deletions crates/audio/src/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,43 @@ impl AudioBackend for HeadlessAudioBackend {
None
}

fn source_get_volume(&self, source: SourceId) -> Option<f32> {
None
fn source_get_gain(&self, source: SourceId) -> Option<f32> {
Some(1.0f32)
}

fn source_set_gain(&self, source: SourceId, gain: f32) -> Result<(), SourceError> {
Ok(())
}

fn source_get_pitch(&self, source: SourceId) -> Option<f32> {
Some(1.0f32)
}

fn source_set_pitch(&self, source: SourceId, pitch: f32) -> Result<(), SourceError> {
Ok(())
}

fn source_get_position(&self, source: SourceId) -> Option<Vec3> {
Some(Vec3::ZERO)
}

fn source_set_position(&self, source: SourceId, position: Vec3) -> Result<(), SourceError> {
Ok(())
}

fn source_set_velocity(&self, source: SourceId, velocity: Vec3) -> Result<(), SourceError> {
Ok(())
}

fn source_get_velocity(&self, source: SourceId) -> Option<Vec3> {
Some(Vec3::ZERO)
}

fn source_is_looping(&self, source: SourceId) -> Option<bool> {
Some(false)
}

fn source_set_volume(&self, source: SourceId, volume: f32) -> Result<(), SourceError> {
fn source_set_looping(&self, source: SourceId, looping: bool) -> Result<(), SourceError> {
Ok(())
}

Expand Down
13 changes: 11 additions & 2 deletions crates/audio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

pub use buffers::*;
pub use clips::*;
use common::Vec3;
pub use sampling::*;
pub use sources::*;

Expand Down Expand Up @@ -66,8 +67,16 @@ pub trait AudioBackend {
// sources
fn source_create(&self) -> Result<SourceId, SourceError>;
fn source_is_playing(&self, source: SourceId) -> Option<bool>;
fn source_get_volume(&self, source: SourceId) -> Option<f32>;
fn source_set_volume(&self, source: SourceId, volume: f32) -> Result<(), SourceError>;
fn source_get_gain(&self, source: SourceId) -> Option<f32>;
fn source_set_gain(&self, source: SourceId, gain: f32) -> Result<(), SourceError>;
fn source_get_pitch(&self, source: SourceId) -> Option<f32>;
fn source_set_pitch(&self, source: SourceId, pitch: f32) -> Result<(), SourceError>;
fn source_get_position(&self, source: SourceId) -> Option<Vec3>;
fn source_set_position(&self, source: SourceId, position: Vec3) -> Result<(), SourceError>;
fn source_set_velocity(&self, source: SourceId, velocity: Vec3) -> Result<(), SourceError>;
fn source_get_velocity(&self, source: SourceId) -> Option<Vec3>;
fn source_is_looping(&self, source: SourceId) -> Option<bool>;
fn source_set_looping(&self, source: SourceId, looping: bool) -> Result<(), SourceError>;
fn source_get_clip(&self, source: SourceId) -> Option<ClipId>;
fn source_set_clip(&self, source: SourceId, clip: ClipId) -> Result<(), SourceError>;
fn source_play(&self, source: SourceId) -> Result<(), SourceError>;
Expand Down
81 changes: 71 additions & 10 deletions crates/audio/src/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,89 @@ impl AudioSource {
}
}

/// Returns the ID of this source.
/// Gets the ID of this source.
pub fn id(&self) -> SourceId {
self.id
}

/// Returns whether this source is currently playing.
/// Gets the position of this source.
pub fn position(&self) -> Vec3 {
audio().source_get_position(self.id).unwrap_or_default()
}

/// Sets the position of this source.
pub fn set_position(&mut self, position: Vec3) {
audio().source_set_position(self.id, position).unwrap();
}

/// Gets the velocity of this source.
pub fn velocity(&self) -> Vec3 {
audio().source_get_velocity(self.id).unwrap_or_default()
}

/// Sets the velocity of this source.
pub fn set_velocity(&mut self, velocity: Vec3) {
audio().source_set_velocity(self.id, velocity).unwrap();
}

/// Gets the volume of this source.
pub fn gain(&self) -> f32 {
audio().source_get_gain(self.id).unwrap_or_default()
}

/// Sets the gain of this source.
pub fn set_gain(&mut self, gain: f32) {
audio().source_set_gain(self.id, gain).unwrap();
}

/// Gets the pitch of this source.
pub fn pitch(&self) -> f32 {
audio().source_get_pitch(self.id).unwrap_or_default()
}

/// Sets the pitch of this source.
pub fn set_pitch(&mut self, pitch: f32) {
audio().source_set_pitch(self.id, pitch).unwrap();
}

/// Determines whether this source is looping.
pub fn is_looping(&self) -> bool {
audio().source_is_looping(self.id).unwrap_or_default()
}

/// Sets whether this source is looping.
pub fn set_looping(&mut self, looping: bool) {
audio().source_set_looping(self.id, looping).unwrap();
}

/// Gets whether this source is currently playing.
pub fn is_playing(&self) -> bool {
audio().source_is_playing(self.id).unwrap_or_default()
}

/// Returns the volume of this source.
pub fn volume(&self) -> f32 {
audio().source_get_volume(self.id).unwrap_or_default()
/// Plays this source.
pub fn play(&mut self) {
audio().source_play(self.id).unwrap();
}

/// Sets the volume of this source.
pub fn set_volume(&mut self, volume: f32) {
audio().source_set_volume(self.id, volume).unwrap();
/// Plays the given audio clip on this source with the current loop setting.
pub fn play_clip(&mut self, clip: &AudioClip) {
audio().source_set_clip(self.id, clip.id()).unwrap();
audio().source_play(self.id).unwrap();
}

/// Plays the given audio clip on this source.
pub fn play(&mut self, clip: &AudioClip) {
/// Plays the given audio clip on this source once-off.
pub fn play_once(&mut self, clip: &AudioClip) {
self.set_looping(false);

audio().source_set_clip(self.id, clip.id()).unwrap();
audio().source_play(self.id).unwrap()
}

/// Plays the given audio clip on this source in a loop.
pub fn play_looping(&mut self, clip: &AudioClip) {
self.set_looping(true);

audio().source_set_clip(self.id, clip.id()).unwrap();
audio().source_play(self.id).unwrap()
}
Expand Down

0 comments on commit 6d6407c

Please sign in to comment.