Skip to content

Commit

Permalink
Fix iOS compilation error
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelHills committed Sep 30, 2020
1 parent 0cbf885 commit a65e643
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ script:
- cargo build --verbose
- cargo test --verbose
- cargo doc --verbose
- cargo build --verbose --target aarch64-apple-ios
- cargo test --verbose --target aarch64-apple-ios
after_success: |
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
Expand Down
40 changes: 40 additions & 0 deletions src/audio_unit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,29 @@ impl AudioUnit {
}
}

/// On successful initialization, the audio formats for input and output are valid
/// and the audio unit is ready to render. During initialization, an audio unit
/// allocates memory according to the maximum number of audio frames it can produce
/// in response to a single render call.
///
/// Usually, the state of an audio unit (such as its I/O formats and memory allocations)
/// cannot be changed while an audio unit is initialized.
pub fn initialize(&mut self) -> Result<(), Error> {
unsafe { try_os_status!(sys::AudioUnitInitialize(self.instance)); }
Ok(())
}

/// Before you change an initialize audio unit’s processing characteristics,
/// such as its input or output audio data format or its sample rate, you must
/// first uninitialize it. Calling this function deallocates the audio unit’s resources.
///
/// After calling this function, you can reconfigure the audio unit and then call
/// AudioUnitInitialize to reinitialize it.
pub fn uninitialize(&mut self) -> Result<(), Error> {
unsafe { try_os_status!(sys::AudioUnitUninitialize(self.instance)); }
Ok(())
}

/// Sets the value for some property of the **AudioUnit**.
///
/// To clear an audio unit property value, set the data paramater with `None::<()>`.
Expand Down Expand Up @@ -375,3 +398,20 @@ pub fn get_property<T>(
Ok(data)
}
}

#[cfg(target_os = "ios")]
pub fn audio_session_get_property<T>(
id: u32,
) -> Result<T, Error>
{
let mut size = ::std::mem::size_of::<T>() as u32;
unsafe {
let mut data: T = ::std::mem::uninitialized();
let data_ptr = &mut data as *mut _ as *mut c_void;
let size_ptr = &mut size as *mut _;
try_os_status!(
sys::AudioSessionGetProperty(id, size_ptr, data_ptr)
);
Ok(data)
}
}
25 changes: 20 additions & 5 deletions src/audio_unit/render_callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use sys;
pub use self::action_flags::ActionFlags;
pub use self::data::Data;

#[cfg(target_os = "ios")]
use audio_unit::audio_session_get_property;


/// When `set_render_callback` is called, a closure of this type will be used to wrap the given
/// render callback function.
Expand Down Expand Up @@ -398,7 +401,7 @@ impl AudioUnit {
// First, we'll retrieve the stream format so that we can ensure that the given callback
// format matches the audio unit's format.
let id = sys::kAudioUnitProperty_StreamFormat;
let asbd = try!(self.get_property(id, Scope::Output, Element::Output));
let asbd = try!(self.get_property(id, Scope::Input, Element::Output));
let stream_format = super::StreamFormat::from_asbd(asbd)?;

// If the stream format does not match, return an error indicating this.
Expand Down Expand Up @@ -471,7 +474,7 @@ impl AudioUnit {
// First, we'll retrieve the stream format so that we can ensure that the given callback
// format matches the audio unit's format.
let id = sys::kAudioUnitProperty_StreamFormat;
let asbd = self.get_property(id, Scope::Input, Element::Input)?;
let asbd = self.get_property(id, Scope::Output, Element::Input)?;
let stream_format = super::StreamFormat::from_asbd(asbd)?;

// If the stream format does not match, return an error indicating this.
Expand All @@ -482,8 +485,20 @@ impl AudioUnit {
// Pre-allocate a buffer list for input stream.
//
// First, get the current buffer size for pre-allocating the `AudioBuffer`s.
let id = sys::kAudioDevicePropertyBufferFrameSize;
let mut buffer_frame_size: u32 = self.get_property(id, Scope::Global, Element::Output)?;
#[cfg(target_os = "macos")]
let mut buffer_frame_size: u32 = {
let id = sys::kAudioDevicePropertyBufferFrameSize;
let buffer_frame_size: u32 = self.get_property(id, Scope::Global, Element::Output)?;
buffer_frame_size
};
#[cfg(target_os = "ios")]
let mut buffer_frame_size: u32 = {
let id = sys::kAudioSessionProperty_CurrentHardwareIOBufferDuration;
let seconds: f32 = super::audio_session_get_property(id)?;
let id = sys::kAudioSessionProperty_CurrentHardwareSampleRate;
let sample_rate: f64 = super::audio_session_get_property(id)?;
(sample_rate * seconds as f64).round() as u32
};
let mut data: Vec<u8> = vec![];
let sample_bytes = stream_format.sample_format.size_in_bytes();
let n_channels = stream_format.channels_per_frame;
Expand Down Expand Up @@ -525,7 +540,7 @@ impl AudioUnit {
unsafe {
// Retrieve the up-to-date stream format.
let id = sys::kAudioUnitProperty_StreamFormat;
let asbd = match super::get_property(audio_unit, id, Scope::Input, Element::Output) {
let asbd = match super::get_property(audio_unit, id, Scope::Output, Element::Input) {
Err(err) => return err.to_os_status(),
Ok(asbd) => asbd,
};
Expand Down

0 comments on commit a65e643

Please sign in to comment.