Reputation: 31
First ever stackoverflow question here so bear with me please! In the process of designing a larger audio program for MacOS, I'm trying to create a test application that can simply take audio from any system audio input and send it to any output. To accomplish this, I want to use AVAudioEngine to read the input and process it. However, I've been completely unable to get anything working at all despite hours of combing through this website and google. I've started with the absolute barebones code to try to read the incoming samples from the system microphone, but all of the input samples are showing up as zeros.
Here is the basic code:
import Cocoa
import AVFoundation
class ViewController: NSViewController {
var audioEngine = AVAudioEngine()
override func viewDidLoad() {
super.viewDidLoad()
let inputNode = audioEngine.inputNode
installSampleTap(input: inputNode)
let srate = inputNode.inputFormat(forBus: 0).sampleRate
print("sample rate = \(srate)")
if srate == 0 {
exit(0);
}
audioEngine.prepare()
do {
try audioEngine.start()
} catch {
print("error?")
}
}
func installSampleTap(input: AVAudioInputNode) {
input.installTap(onBus: 0, bufferSize: 1024, format: input.outputFormat(forBus: 0), block: {
[weak self] (buffer, when) in
let data = self?.PCMBufferToFloatArray(buffer)
guard let values = data else {return}
print("Channels: \(values.count), Samples: \(values[0].count)")
print("\(values[0][0]), \(values[1][0])")
})
}
...
The PCMBufferToFloatArray
function came from this apple developer thread and seems to work well, so I trust its accuracy.
I've made sure that "Audio Input" is enabled in the signing and capabilities section of Xcode, and I think that everything should be set up right, but I get this output when reading the samples from the input tap (repeated over and over with no change):
Channels: 2, Samples: 4800
0.0, 0.0
Something that might be related is that I get this output whenever I get audioEngine.inputNode
at the start of the program. I've checked to confirm that getting the input node causes it, although getting it multiple time only outputs the log once:
[plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x60000023ff00> F8BB1C28-BAE8-11D6-9C31-00039315CD46
HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
However, I've seen this output on multiple questions already, and the general consensus seems to be that it's harmless log output, and I think that's probably correct since I am able to tap the input node just fine.
I've tried changing the input source from the mic to Soundflower using Audio Midi Setup and sending audio that way just in case it was a microphone problem, but I get the same result, though with the correct channel count (64ch Soundflower says 64 channels).
Unfortunately, I feel like I've tried everything. I have no idea why the input node is only getting zeros. Any help at all would be hugely appreciated. It's likely I'm completely overlooking some small thing. Thanks for reading!
Upvotes: 3
Views: 1170
Reputation: 16966
In Info.plist
did you include the NSMicrophoneUsageDescription
entry? You'd think that enabling audio input in Xcode would take care of this but I don't think it automatically adds the required Info.plist
entry.
Something like
<key>NSMicrophoneUsageDescription</key>
<string>Microphone permission is used to capture Input Device and/or System Audio streams.</string>
will hopefully fix the problem.
Upvotes: 0