AVAudioSinkNode with non-default, but still device-native sample rates
Asked Answered
T

1

5

I've configured AVAudioSinkNode attached to AVAudioEngine's inputNode like so:

let sinkNode = AVAudioSinkNode() { (timestamp, frames, audioBufferList) -> OSStatus in
    print("SINK: \(timestamp.pointee.mHostTime) - \(frames) - \(audioBufferList.pointee.mNumberBuffers)")
    return noErr
}

audioEngine.attach(sinkNode)
audioEngine.connect(audioEngine.inputNode, to: sinkNode, format: nil)
audioEngine.prepare()

do {
    try audioEngine.start()
    print("AudioEngine started.")
} catch {
    print("AudioEngine did not start!")
}

I've separately configured it to use the "Built-in Microphone" device (which I am sure it does use).

If I set sample rate 44100 for the mic (using "Audio MIDI Setup" app provided by Apple on all Macs), everything works as expected:

AudioEngine started.
SINK: 692312319180567 - 512 - 2
SINK: 692312348024104 - 512 - 2
SINK: 692312359634082 - 512 - 2
SINK: 692312371244059 - 512 - 2
SINK: 692312382854036 - 512 - 2
...

However, if I use "Audio MIDI Setup" app (provided by Apple on all Macs), and change the mic's sample rate to anything other than 44100 (say 48000), then the sink node doesn't seem to do anything (doesn't print anything).

Of course, originally I was trying to modify the mic's sample rate programmatically. But later on I discovered that the same happens when I just change the device sample rate via the standard "Audio MIDI Setup" app. Therefore, the code I have for setting the sample rate is unnecessary to post here.

Does anyone know if AVAudioSinkNode has allowed sample rate hard-coded into it?

I cannot find any other explanation...

Truthvalue answered 24/3, 2020 at 18:41 Comment(0)
K
3

I've been toying around with AVAudioSinkNodes and it doesn't appear to me to be restricted to a 44100 sampling rate.

In my case, when I check the sampling rate of my input and sink nodes after attaching them, I get the following:

Input node sample rates: 
    IF <AVAudioFormat 0x600002527700:  2 ch,  48000 Hz, Float32, non-inter> 
    OF <AVAudioFormat 0x60000250fac0:  2 ch,  48000 Hz, Float32, non-inter>

Sink node sample rates: 
    IF <AVAudioFormat 0x60000250fbb0:  2 ch,  44100 Hz, Float32, non-inter> 
    OF <AVAudioFormat 0x60000250fb60:  2 ch,  44100 Hz, Float32, non-inter>

But once I connected them together, I got the following:

Input node sample rates: 
    IF <AVAudioFormat 0x600002527980:  1 ch,  48000 Hz, Float32> 
    OF <AVAudioFormat 0x600002506760:  2 ch,  48000 Hz, Float32, non-inter>

Sink node sample rates: 
    IF <AVAudioFormat 0x600002506710:  2 ch,  48000 Hz, Float32, non-inter> 
    OF <AVAudioFormat 0x600002505db0:  2 ch,  48000 Hz, Float32, non-inter>

I'm new to working with audio frameworks, but this does seem to suggest that the sink node's sample rate isn't hardcoded.

Your connection,

audioEngine.connect(audioEngine.inputNode, to: sinkNode, format: nil)

seems to differ from mine. Rightly or wrongly, I explicitly specified the format as audioEngine.inputNode.outputFormat(forBus: 0) which led to the settings shown. Not sure if that makes a difference.

Kalong answered 5/9, 2020 at 11:17 Comment(1)
Thanks this put me on the right track, but I needed to use audioEngine.inputNode.inputFormat(forBus: 0) (rather than outputFormat) as my mic sample rate was different than my output device sample rate.Renewal

© 2022 - 2024 — McMap. All rights reserved.