На Mac вы должны указать AudioUnit
, какое аудиоустройство использовать. В моем случае мне пришлось отключить выход динамика на устройстве - вероятно, потому что устройство ввода по умолчанию на моем Mac делает только вход.
В C (я полагаю, версии Rust понадобится несколько as *const _ as *const _
с и as u32
с):
// disable output (needed, otherwise I can't set device)
flag = 0;
err = AudioUnitSetProperty(au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &flag, sizeof(flag));
assert(noErr == err);
// get default input device
AudioObjectPropertyAddress propAddr = {
.mSelector = kAudioHardwarePropertyDefaultInputDevice,
.mScope = kAudioObjectPropertyScopeGlobal,
.mElement = kAudioObjectPropertyElementMaster
};
AudioDeviceID deviceID;
UInt32 propertySize = sizeof(deviceID);
err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propAddr, 0, NULL, &propertySize, &deviceID);
assert(noErr == err);
// set audio unit current device
err = AudioUnitSetProperty(au, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceID, sizeof(deviceID));
assert(noErr == err);
В целом:
static OSStatus
AUInputCallback(
void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData)
{
printf("poot\n");
return noErr;
}
int
main(int argc, char **argv) {
AudioComponentDescription desc = {
.componentType = kAudioUnitType_Output,
.componentSubType = kAudioUnitSubType_HALOutput,
.componentManufacturer = kAudioUnitManufacturer_Apple,
.componentFlags = 0,
.componentFlagsMask = 0
};
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
assert(comp);
AudioUnit au;
OSStatus err = AudioComponentInstanceNew(comp, &au);
assert(noErr == err);
// enable input
UInt32 flag = 1;
err = AudioUnitSetProperty(au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flag, sizeof(flag));
assert(noErr == err);
// disable output (needed, otherwise I can't set device)
flag = 0;
err = AudioUnitSetProperty(au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &flag, sizeof(flag));
assert(noErr == err);
AURenderCallbackStruct cb;
cb.inputProc = AUInputCallback;
cb.inputProcRefCon = NULL;
err = AudioUnitSetProperty(au, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &cb, sizeof(cb));
assert(noErr == err);
// set audio unit device to default input device
AudioObjectPropertyAddress propAddr = {
.mSelector = kAudioHardwarePropertyDefaultInputDevice,
.mScope = kAudioObjectPropertyScopeGlobal,
.mElement = kAudioObjectPropertyElementMaster
};
AudioDeviceID deviceID;
UInt32 propertySize = sizeof(deviceID);
err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propAddr, 0, NULL, &propertySize, &deviceID);
assert(noErr == err);
err = AudioUnitSetProperty(au, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceID, sizeof(deviceID));
assert(noErr == err);
err = AudioUnitInitialize(au);
assert(noErr == err);
err = AudioOutputUnitStart(au);
assert(noErr == err);
while (1) {}
return 0;
}