Skip to content

Commit a65e643

Browse files
committed
Fix iOS compilation error
1 parent 0cbf885 commit a65e643

File tree

3 files changed

+62
-5
lines changed

3 files changed

+62
-5
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ script:
2020
- cargo build --verbose
2121
- cargo test --verbose
2222
- cargo doc --verbose
23+
- cargo build --verbose --target aarch64-apple-ios
24+
- cargo test --verbose --target aarch64-apple-ios
2325
after_success: |
2426
[ $TRAVIS_BRANCH = master ] &&
2527
[ $TRAVIS_PULL_REQUEST = false ] &&

src/audio_unit/mod.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,29 @@ impl AudioUnit {
171171
}
172172
}
173173

174+
/// On successful initialization, the audio formats for input and output are valid
175+
/// and the audio unit is ready to render. During initialization, an audio unit
176+
/// allocates memory according to the maximum number of audio frames it can produce
177+
/// in response to a single render call.
178+
///
179+
/// Usually, the state of an audio unit (such as its I/O formats and memory allocations)
180+
/// cannot be changed while an audio unit is initialized.
181+
pub fn initialize(&mut self) -> Result<(), Error> {
182+
unsafe { try_os_status!(sys::AudioUnitInitialize(self.instance)); }
183+
Ok(())
184+
}
185+
186+
/// Before you change an initialize audio unit’s processing characteristics,
187+
/// such as its input or output audio data format or its sample rate, you must
188+
/// first uninitialize it. Calling this function deallocates the audio unit’s resources.
189+
///
190+
/// After calling this function, you can reconfigure the audio unit and then call
191+
/// AudioUnitInitialize to reinitialize it.
192+
pub fn uninitialize(&mut self) -> Result<(), Error> {
193+
unsafe { try_os_status!(sys::AudioUnitUninitialize(self.instance)); }
194+
Ok(())
195+
}
196+
174197
/// Sets the value for some property of the **AudioUnit**.
175198
///
176199
/// To clear an audio unit property value, set the data paramater with `None::<()>`.
@@ -375,3 +398,20 @@ pub fn get_property<T>(
375398
Ok(data)
376399
}
377400
}
401+
402+
#[cfg(target_os = "ios")]
403+
pub fn audio_session_get_property<T>(
404+
id: u32,
405+
) -> Result<T, Error>
406+
{
407+
let mut size = ::std::mem::size_of::<T>() as u32;
408+
unsafe {
409+
let mut data: T = ::std::mem::uninitialized();
410+
let data_ptr = &mut data as *mut _ as *mut c_void;
411+
let size_ptr = &mut size as *mut _;
412+
try_os_status!(
413+
sys::AudioSessionGetProperty(id, size_ptr, data_ptr)
414+
);
415+
Ok(data)
416+
}
417+
}

src/audio_unit/render_callback.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ use sys;
88
pub use self::action_flags::ActionFlags;
99
pub use self::data::Data;
1010

11+
#[cfg(target_os = "ios")]
12+
use audio_unit::audio_session_get_property;
13+
1114

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

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

477480
// If the stream format does not match, return an error indicating this.
@@ -482,8 +485,20 @@ impl AudioUnit {
482485
// Pre-allocate a buffer list for input stream.
483486
//
484487
// First, get the current buffer size for pre-allocating the `AudioBuffer`s.
485-
let id = sys::kAudioDevicePropertyBufferFrameSize;
486-
let mut buffer_frame_size: u32 = self.get_property(id, Scope::Global, Element::Output)?;
488+
#[cfg(target_os = "macos")]
489+
let mut buffer_frame_size: u32 = {
490+
let id = sys::kAudioDevicePropertyBufferFrameSize;
491+
let buffer_frame_size: u32 = self.get_property(id, Scope::Global, Element::Output)?;
492+
buffer_frame_size
493+
};
494+
#[cfg(target_os = "ios")]
495+
let mut buffer_frame_size: u32 = {
496+
let id = sys::kAudioSessionProperty_CurrentHardwareIOBufferDuration;
497+
let seconds: f32 = super::audio_session_get_property(id)?;
498+
let id = sys::kAudioSessionProperty_CurrentHardwareSampleRate;
499+
let sample_rate: f64 = super::audio_session_get_property(id)?;
500+
(sample_rate * seconds as f64).round() as u32
501+
};
487502
let mut data: Vec<u8> = vec![];
488503
let sample_bytes = stream_format.sample_format.size_in_bytes();
489504
let n_channels = stream_format.channels_per_frame;
@@ -525,7 +540,7 @@ impl AudioUnit {
525540
unsafe {
526541
// Retrieve the up-to-date stream format.
527542
let id = sys::kAudioUnitProperty_StreamFormat;
528-
let asbd = match super::get_property(audio_unit, id, Scope::Input, Element::Output) {
543+
let asbd = match super::get_property(audio_unit, id, Scope::Output, Element::Input) {
529544
Err(err) => return err.to_os_status(),
530545
Ok(asbd) => asbd,
531546
};

0 commit comments

Comments
 (0)