95 AudioBufferList* list;
98 list = (AudioBufferList*)calloc(1,
sizeof(AudioBufferList) + numChannels *
sizeof(AudioBuffer));
102 list->mNumberBuffers = numChannels;
103 for(i = 0; i < numChannels; ++i) {
104 list->mBuffers[i].mNumberChannels = 1;
105 list->mBuffers[i].mDataByteSize = size;
106 list->mBuffers[i].mData = malloc(size);
107 if(list->mBuffers[i].mData == NULL) {
209 if (strcmp(cfg,
"help") == 0) {
210 printf(
"Core Audio capture usage:\n");
212 color_printf(
"where\n\t" TBOLD(
"<name>")
" - device name substring (case sensitive)\n\n");
213 printf(
"Available Core Audio capture devices:\n");
217 OSStatus ret = noErr;
218 AudioComponentDescription
desc;
219 AudioDeviceID device;
220 UInt32 size =
sizeof device;
222 if (strlen(cfg) > 0) {
224 device = strtol(cfg, &endptr, 0);
225 if (*endptr !=
'\0') {
227 if (device == UINT_MAX) {
233 AudioObjectPropertyAddress propertyAddress;
234 propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
235 propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
237 if ((ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &device)) != 0) {
242 char device_name[128];
247 AVAuthorizationStatus authorization_status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
248 if (authorization_status == AVAuthorizationStatusRestricted ||
249 authorization_status == AVAuthorizationStatusDenied) {
253 if (authorization_status == AVAuthorizationStatusNotDetermined) {
254 [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:cb];
259 size =
sizeof(double);
260 AudioObjectPropertyAddress propertyAddress;
261 propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
262 propertyAddress.mScope = kAudioDevicePropertyScopeInput;
264 ret = AudioObjectGetPropertyData(device, &propertyAddress, 0, NULL, &size, &rate);
265 if (ret != noErr || rate == 0.0) {
274 pthread_mutex_init(&s->
lock, NULL);
275 pthread_cond_init(&s->
cv, NULL);
294 desc.componentType = kAudioUnitType_Output;
299 desc.componentSubType = kAudioUnitSubType_HALOutput;
303 desc.componentManufacturer = kAudioUnitManufacturer_Apple;
304 desc.componentFlags = 0;
305 desc.componentFlagsMask = 0;
309 AudioComponent comp = AudioComponentFindNext(NULL, &
desc);
311 fprintf(stderr,
"Error finding AUHAL component.\n");
315 "Error opening AUHAL component",
324 kAudioOutputUnitProperty_EnableIO,
325 kAudioUnitScope_Input,
329 "Error enabling input on AUHAL",
break);
333 kAudioOutputUnitProperty_EnableIO,
334 kAudioUnitScope_Output,
338 "Error disabling output on AUHAL",
break);
342 kAudioOutputUnitProperty_CurrentDevice,
343 kAudioUnitScope_Global,
347 "Error setting device to AUHAL instance",
break);
349 AudioStreamBasicDescription
desc;
353 1, &
desc, &size),
"Error getting default device properties",
break);
357 desc.mFormatID = kAudioFormatLinearPCM;
358 desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
360 desc.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
366 desc.mBytesPerFrame =
desc.mBitsPerChannel / 8;
367 desc.mFramesPerPacket = 1;
368 desc.mBytesPerPacket =
desc.mBytesPerFrame;
372 1, &
desc,
sizeof(
desc)),
"Error setting device properties",
break);
374 AURenderCallbackStruct input;
376 input.inputProcRefCon = s;
378 kAudioUnitScope_Global, 0, &input,
sizeof(input)),
379 "Error setting input callback",
break);
380 uint32_t numFrames = 128;
385 kAudioUnitScope_Global, 0, &numFrames,
sizeof(numFrames)),
386 "Error setting frames",
NOOP);
398 pthread_mutex_destroy(&s->
lock);
399 pthread_cond_destroy(&s->
cv);