RustAudio / coreaudio-rs

A friendly rust interface to Apple's Core Audio API.
Apache License 2.0
203 stars 38 forks source link

Fix input and output scope and element usage. #104

Closed akhudek closed 3 months ago

akhudek commented 10 months ago

Getting input from a microphone needs to use the Output scope and Input Element, and sending audio to a speaker needs to use the Input Scope and Output Element. See Figure 1-3 in https://developer.apple.com/library/archive/documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/AudioUnitHostingFundamentals/AudioUnitHostingFundamentals.html

This PR also removes a bit of redundancy in the code by reusing input and output stream functions in the callback code.

HEnquist commented 3 months ago

Getting input from a microphone needs to use the Output scope and Input Element, and sending audio to a speaker needs to use the Input Scope and Output Element.

These changes look reasonable, but I'm a bit confused why things are working without them. I have done both playback and capture and not noticed any problems. What is it that does not work currently?

akhudek commented 3 months ago

I no longer have the test code I was using, but audio capture wasn't working for me without these changes. I was instantiating a device via its id rather than using the default capture device. This is on a 2021 macbook pro with Sonoma.

HEnquist commented 3 months ago

I tried modifying the feedback_interleaved example to test this.

I replaced the start of the main to get the device ids by name, like this:

fn main() -> Result<(), coreaudio::Error> {
    let input_device_id = get_device_id_from_name("MacBook Air Microphone").unwrap();
    let output_device_id = get_device_id_from_name("MacBook Air Speakers").unwrap();

This seems to work just fine on my M1 Air with the latest macOS. Do you remember if this is similar to your test code?

akhudek commented 3 months ago

I believe I was using set_stream_format along with input_stream_format. The feedback_interleaved example actually manually sets the scope and element as in this pr which is likely why it works:

https://github.com/RustAudio/coreaudio-rs/blob/master/examples/feedback.rs#L63

These changes make the stream format correct (which is why they can be used in render_callback.rs instead of manually getting the format with the correct scope and element as before).

HEnquist commented 3 months ago

Ah yes that makes sense! I set these manually in my code too, so this would explain why I haven't had any trouble.

Can some maintainer please merge this and publish a new version?

simlay commented 3 months ago

Can some maintainer please merge this and publish a new version?

That's me! Based on the changes here and in #109, these look like small breaking changes so I'll submit a PR bumping from 0.11.3 to 0.12.0.