UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
coreaudio.m File Reference
#include <AVFoundation/AVFoundation.h>
#include <AudioUnit/AudioUnit.h>
#include <Availability.h>
#include <CoreAudio/AudioHardware.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "audio/audio_capture.h"
#include "audio/playback/coreaudio.h"
#include "audio/types.h"
#include "audio/utils.h"
#include "debug.h"
#include "host.h"
#include "lib_common.h"
#include "utils/color_out.h"
#include "utils/macos.h"
#include "utils/macros.h"
#include "utils/ring_buffer.h"
Include dependency graph for coreaudio.m:

Go to the source code of this file.

Classes

struct  state_ca_capture
 

Macros

#define CA_STRINGIFY(A)
 
#define CHECK_OK(cmd, msg, action_failed)
 
#define MOD_NAME   "[CoreAudio cap.] "
 
#define NOOP
 

Enumerations

enum  { CA_DIR = -1 }
 

Functions

static AudioBufferList * AllocateAudioBufferList (UInt32 numChannels, UInt32 size)
 
static void audio_cap_ca_done (void *state)
 
static void audio_cap_ca_help ()
 
static void * audio_cap_ca_init (struct module *parent, const char *cfg)
 
static void audio_cap_ca_probe (struct device_info **available_devices, int *count, void(**deleter)(void *))
 
static struct audio_frame * audio_cap_ca_read (void *state)
 
static void DestroyAudioBufferList (AudioBufferList *list)
 
static OSStatus InputProc (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
 
 REGISTER_MODULE (coreaudio, &acap_coreaudio_info, LIBRARY_CLASS_AUDIO_CAPTURE, AUDIO_CAPTURE_ABI_VERSION)
 

Variables

static const struct audio_capture_info acap_coreaudio_info
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file coreaudio.m.

Macro Definition Documentation

◆ CA_STRINGIFY

#define CA_STRINGIFY ( A)
Value:
#A

Definition at line 184 of file coreaudio.m.

◆ CHECK_OK

#define CHECK_OK ( cmd,
msg,
action_failed )
Value:
do { OSStatus ret = cmd; if (ret != noErr) {\
log_msg(strlen(CA_STRINGIFY(action_failed)) == 0 ? LOG_LEVEL_WARNING : LOG_LEVEL_ERROR, MOD_NAME "%s: %s\n", (msg), get_osstatus_str(ret));\
action_failed;\
}\
} while(0)
#define MOD_NAME
Definition coreaudio.m:63
#define CA_STRINGIFY(A)
Definition coreaudio.m:184
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
const char * get_osstatus_str(OSStatus err)
Definition macos.m:106

Definition at line 186 of file coreaudio.m.

186#define CHECK_OK(cmd, msg, action_failed) do { OSStatus ret = cmd; if (ret != noErr) {\
187 log_msg(strlen(CA_STRINGIFY(action_failed)) == 0 ? LOG_LEVEL_WARNING : LOG_LEVEL_ERROR, MOD_NAME "%s: %s\n", (msg), get_osstatus_str(ret));\
188 action_failed;\
189}\
190} while(0)

Referenced by audio_cap_ca_init().

◆ MOD_NAME

#define MOD_NAME   "[CoreAudio cap.] "

Definition at line 63 of file coreaudio.m.

Referenced by audio_cap_ca_init(), and InputProc().

◆ NOOP

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
CA_DIR 

Definition at line 65 of file coreaudio.m.

65 {
66 CA_DIR = -1,
67};
@ CA_DIR
Definition coreaudio.m:66

Function Documentation

◆ AllocateAudioBufferList()

static AudioBufferList * AllocateAudioBufferList ( UInt32 numChannels,
UInt32 size )
static

Definition at line 93 of file coreaudio.m.

94{
95 AudioBufferList* list;
96 UInt32 i;
97
98 list = (AudioBufferList*)calloc(1, sizeof(AudioBufferList) + numChannels * sizeof(AudioBuffer));
99 if(list == NULL)
100 return NULL;
101
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) {
109 return NULL;
110 }
111 }
112 return list;
113}
static void DestroyAudioBufferList(AudioBufferList *list)
Definition coreaudio.m:116

References DestroyAudioBufferList().

Referenced by audio_cap_ca_init().

Here is the call graph for this function:

◆ audio_cap_ca_done()

static void audio_cap_ca_done ( void * state)
static

Definition at line 431 of file coreaudio.m.

432{
433 struct state_ca_capture *s = (struct state_ca_capture *) state;
434
435 if(!s)
436 return;
437
438 pthread_mutex_destroy(&s->lock);
439 pthread_cond_destroy(&s->cv);
441 free(s->frame.data);
443 free(s->tmp);
444
445 free(s);
446}
void ** state
void ring_buffer_destroy(struct ring_buffer *ring)
char * data
Definition types.h:102
pthread_cond_t cv
Definition coreaudio.m:78
struct ring_buffer * buffer
Definition coreaudio.m:73
struct audio_frame frame
Definition coreaudio.m:71
pthread_mutex_t lock
Definition coreaudio.m:77
AudioBufferList * theBufferList
Definition coreaudio.m:75

References state_ca_capture::buffer, state_ca_capture::cv, audio_frame::data, DestroyAudioBufferList(), state_ca_capture::frame, state_ca_capture::lock, ring_buffer_destroy(), state, state_ca_capture::theBufferList, and state_ca_capture::tmp.

Here is the call graph for this function:

◆ audio_cap_ca_help()

static void audio_cap_ca_help ( )
static

Definition at line 171 of file coreaudio.m.

172{
173 struct device_info *available_devices;
174 int count;
175 void (*deleter)(void *) = NULL;
176 audio_cap_ca_probe(&available_devices, &count, &deleter);
177
178 for (int i = 0; i < count; ++i) {
179 color_printf("\t" TBOLD("coreaudio%-4s") ": %s\n", available_devices[i].dev, available_devices[i].name);
180 }
181 deleter ? deleter(available_devices) : free(available_devices);
182}
int void(** deleter)(void *))
int color_printf(const char *format,...)
#define TBOLD(x)
Definition color_out.h:70
static void audio_cap_ca_probe(struct device_info **available_devices, int *count, void(**deleter)(void *))
Definition coreaudio.m:165
int count
Definition hd-rum.c:44
char name[1024]
human readable name of the device
Definition types.h:385
char dev[1024]
Definition types.h:383

References audio_cap_ca_probe(), color_printf(), count, deleter, device_info::dev, name, and TBOLD.

Referenced by audio_cap_ca_init().

Here is the call graph for this function:

◆ audio_cap_ca_init()

static void * audio_cap_ca_init ( struct module * parent,
const char * cfg )
static

Definition at line 206 of file coreaudio.m.

207{
208 UNUSED(parent);
209 if (strcmp(cfg, "help") == 0) {
210 printf("Core Audio capture usage:\n");
211 color_printf(TBOLD(TRED("\t-s coreaudio") "[:<index>|:<name>]") "\n");
212 color_printf("where\n\t" TBOLD("<name>") " - device name substring (case sensitive)\n\n");
213 printf("Available Core Audio capture devices:\n");
215 return INIT_NOERR;
216 }
217 OSStatus ret = noErr;
218 AudioComponentDescription desc;
219 AudioDeviceID device;
220 UInt32 size = sizeof device;
221
222 if (strlen(cfg) > 0) {
223 char *endptr = NULL;
224 device = strtol(cfg, &endptr, 0);
225 if (*endptr != '\0') {
226 device = audio_ca_get_device_by_name(cfg, CA_DIR);
227 if (device == UINT_MAX) {
228 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Wrong device index or unrecognized name \"%s\"!\n", cfg);
229 return NULL;
230 }
231 }
232 } else {
233 AudioObjectPropertyAddress propertyAddress;
234 propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
235 propertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
236 propertyAddress.mElement = kAudioObjectPropertyElementMain;
237 if ((ret = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &device)) != 0) {
238 log_msg(LOG_LEVEL_ERROR, "Error finding default input device: %s.\n", get_osstatus_str(ret));
239 return NULL;
240 }
241 }
242 char device_name[128];
243 audio_ca_get_device_name(device, sizeof device_name, device_name);
244 log_msg(LOG_LEVEL_INFO, MOD_NAME "Using device: %s\n", device_name);
245
246#ifdef __MAC_10_14
247 AVAuthorizationStatus authorization_status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
248 if (authorization_status == AVAuthorizationStatusRestricted ||
249 authorization_status == AVAuthorizationStatusDenied) {
250 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Application is not authorized to capture audio input!\n");
251 return NULL;
252 }
253 if (authorization_status == AVAuthorizationStatusNotDetermined) {
254 [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:cb];
255 }
256#endif // defined __MAC_10_14
257
258 double rate = 0.0;
259 size = sizeof(double);
260 AudioObjectPropertyAddress propertyAddress;
261 propertyAddress.mSelector = kAudioDevicePropertyNominalSampleRate;
262 propertyAddress.mScope = kAudioDevicePropertyScopeInput;
263 propertyAddress.mElement = kAudioObjectPropertyElementMain;
264 ret = AudioObjectGetPropertyData(device, &propertyAddress, 0, NULL, &size, &rate);
265 if (ret != noErr || rate == 0.0) {
266 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unable to get sample rate: %s. Wrong device index?\n", get_osstatus_str(ret));
267 return NULL;
268 }
270 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Requested sample rate %u, got %lf!\n", audio_capture_sample_rate, rate);
271 }
272
273 struct state_ca_capture *s = (struct state_ca_capture *) calloc(1, sizeof(struct state_ca_capture));
274 pthread_mutex_init(&s->lock, NULL);
275 pthread_cond_init(&s->cv, NULL);
276 s->boss_waiting = FALSE;
277 s->data_ready = FALSE;
280
281 s->frame.sample_rate = rate;
283 int nonres_channel_size = s->frame.bps * s->frame.sample_rate;
284
285 s->theBufferList = AllocateAudioBufferList(s->frame.ch_count, nonres_channel_size);
286 s->tmp = (char *) malloc(nonres_channel_size * s->frame.ch_count);
287
289 s->frame.data = (char *) malloc(s->frame.max_size);
290
291 //There are several different types of Audio Units.
292 //Some audio units serve as Outputs, Mixers, or DSP
293 //units. See AUComponent.h for listing
294 desc.componentType = kAudioUnitType_Output;
295
296 //Every Component has a subType, which will give a clearer picture
297 //of what this components function will be.
298 //desc.componentSubType = kAudioUnitSubType_DefaultOutput;
299 desc.componentSubType = kAudioUnitSubType_HALOutput;
300
301 //all Audio Units in AUComponent.h must use
302 //"kAudioUnitManufacturer_Apple" as the Manufacturer
303 desc.componentManufacturer = kAudioUnitManufacturer_Apple;
304 desc.componentFlags = 0;
305 desc.componentFlagsMask = 0;
306
307 bool failed = true;
308 do {
309 AudioComponent comp = AudioComponentFindNext(NULL, &desc);
310 if(!comp) {
311 fprintf(stderr, "Error finding AUHAL component.\n");
312 break;
313 }
314 CHECK_OK(AudioComponentInstanceNew(comp, &s->auHALComponentInstance),
315 "Error opening AUHAL component",
316 break);
317
318 //When using AudioUnitSetProperty the 4th parameter in the method
319 //refer to an AudioUnitElement. When using an AudioOutputUnit
320 //the input element will be '1' and the output element will be '0'.
321
322 UInt32 enableIO = 1;
323 CHECK_OK(AudioUnitSetProperty(s->auHALComponentInstance,
324 kAudioOutputUnitProperty_EnableIO,
325 kAudioUnitScope_Input,
326 1, // input element
327 &enableIO,
328 sizeof(enableIO)),
329 "Error enabling input on AUHAL", break);
330
331 enableIO = 0;
332 CHECK_OK(AudioUnitSetProperty(s->auHALComponentInstance,
333 kAudioOutputUnitProperty_EnableIO,
334 kAudioUnitScope_Output,
335 0, //output element
336 &enableIO,
337 sizeof(enableIO)),
338 "Error disabling output on AUHAL", break);
339
340 size=sizeof(device);
341 CHECK_OK(AudioUnitSetProperty(s->auHALComponentInstance,
342 kAudioOutputUnitProperty_CurrentDevice,
343 kAudioUnitScope_Global,
344 0,
345 &device,
346 sizeof(device)),
347 "Error setting device to AUHAL instance", break);
348
349 AudioStreamBasicDescription desc;
350
351 size = sizeof(desc);
352 CHECK_OK(AudioUnitGetProperty(s->auHALComponentInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,
353 1, &desc, &size), "Error getting default device properties", break);
354
355 desc.mChannelsPerFrame = s->frame.ch_count;
356 desc.mSampleRate = (double) s->frame.sample_rate;
357 desc.mFormatID = kAudioFormatLinearPCM;
358 desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
359 if (desc.mFormatID == kAudioFormatLinearPCM && s->frame.ch_count == 1)
360 desc.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
361
362/*#if __BIG_ENDIAN__
363 desc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
364#endif */
365 desc.mBitsPerChannel = s->frame.bps * 8;
366 desc.mBytesPerFrame = desc.mBitsPerChannel / 8;
367 desc.mFramesPerPacket = 1;
368 desc.mBytesPerPacket = desc.mBytesPerFrame;
369 s->audio_packet_size = desc.mBytesPerPacket;
370
371 CHECK_OK(AudioUnitSetProperty(s->auHALComponentInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output,
372 1, &desc, sizeof(desc)), "Error setting device properties", break);
373
374 AURenderCallbackStruct input;
375 input.inputProc = InputProc;
376 input.inputProcRefCon = s;
377 CHECK_OK(AudioUnitSetProperty(s->auHALComponentInstance, kAudioOutputUnitProperty_SetInputCallback,
378 kAudioUnitScope_Global, 0, &input, sizeof(input)),
379 "Error setting input callback", break);
380 uint32_t numFrames = 128;
381 if (get_commandline_param("audio-cap-frames")) {
382 numFrames = atoi(get_commandline_param("audio-cap-frames"));
383 }
384 CHECK_OK(AudioUnitSetProperty(s->auHALComponentInstance, kAudioDevicePropertyBufferFrameSize,
385 kAudioUnitScope_Global, 0, &numFrames, sizeof(numFrames)),
386 "Error setting frames", NOOP);
387
388 CHECK_OK(AudioUnitInitialize(s->auHALComponentInstance), "Error initializing device", break);
389 CHECK_OK(AudioOutputUnitStart(s->auHALComponentInstance), "Error starting device", break);
390 failed = false;
391 } while(0);
392
393 if (!failed) {
394 return s;
395 }
396
397 // error accured
398 pthread_mutex_destroy(&s->lock);
399 pthread_cond_destroy(&s->cv);
401 free(s->frame.data);
403 free(s->tmp);
404 free(s);
405 return NULL;
406}
#define UNUSED(x)
struct video_desc desc
#define TRED(x)
Definition color_out.h:75
#define FALSE
AudioDeviceID audio_ca_get_device_by_name(const char *name, int dir)
void audio_ca_get_device_name(AudioDeviceID dev_id, size_t namebuf_len, char *namebuf)
#define CHECK_OK(cmd, msg, action_failed)
Definition coreaudio.m:186
static void audio_cap_ca_help()
Definition coreaudio.m:171
static AudioBufferList * AllocateAudioBufferList(UInt32 numChannels, UInt32 size)
Definition coreaudio.m:93
#define NOOP
Definition coreaudio.m:191
static OSStatus InputProc(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
Definition coreaudio.m:129
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
unsigned int audio_capture_bps
Definition host.cpp:164
const char * get_commandline_param(const char *key)
Definition host.cpp:894
unsigned int audio_capture_sample_rate
Definition host.cpp:165
unsigned int audio_capture_channels
Definition host.cpp:163
#define DEFAULT_AUDIO_CAPTURE_CHANNELS
Definition host.h:89
#define INIT_NOERR
Definition host.h:73
#define kAudioObjectPropertyElementMain
Definition macos.h:50
struct ring_buffer * ring_buffer_init(int size)
const char * parent
Definition settings.cpp:198
int sample_rate
Definition types.h:101
int ch_count
Definition types.h:104
int bps
Definition types.h:100
int max_size
Definition types.h:105
volatile int boss_waiting
Definition coreaudio.m:79
volatile int data_ready
Definition coreaudio.m:80
AudioComponentInstance auHALComponentInstance
Definition coreaudio.m:70

References AllocateAudioBufferList(), audio_ca_get_device_by_name(), audio_ca_get_device_name(), audio_cap_ca_help(), audio_capture_bps, audio_capture_channels, audio_capture_sample_rate, state_ca_capture::audio_packet_size, state_ca_capture::auHALComponentInstance, state_ca_capture::boss_waiting, audio_frame::bps, state_ca_capture::buffer, CA_DIR, audio_frame::ch_count, CHECK_OK, color_printf(), state_ca_capture::cv, audio_frame::data, state_ca_capture::data_ready, DEFAULT_AUDIO_CAPTURE_CHANNELS, desc, DestroyAudioBufferList(), FALSE, state_ca_capture::frame, get_commandline_param(), get_osstatus_str(), INIT_NOERR, InputProc(), kAudioObjectPropertyElementMain, state_ca_capture::lock, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, log_msg(), audio_frame::max_size, MOD_NAME, NOOP, parent, ring_buffer_destroy(), ring_buffer_init(), audio_frame::sample_rate, TBOLD, state_ca_capture::theBufferList, state_ca_capture::tmp, TRED, and UNUSED.

Here is the call graph for this function:

◆ audio_cap_ca_probe()

static void audio_cap_ca_probe ( struct device_info ** available_devices,
int * count,
void(** deleter )(void *) )
static

Definition at line 165 of file coreaudio.m.

166{
167 *deleter = free;
168 audio_ca_probe(available_devices, count, -1);
169}
void audio_ca_probe(struct device_info **available_devices, int *count, int dir)

References audio_ca_probe(), count, and deleter.

Referenced by audio_cap_ca_help().

Here is the call graph for this function:

◆ audio_cap_ca_read()

static struct audio_frame * audio_cap_ca_read ( void * state)
static

Definition at line 408 of file coreaudio.m.

409{
410 struct state_ca_capture *s = (struct state_ca_capture *) state;
411 int ret = FALSE;
412
413 pthread_mutex_lock(&s->lock);
415 if(!ret) {
416 s->boss_waiting = TRUE;
417 while(!s->data_ready) {
418 pthread_cond_wait(&s->cv, &s->lock);
419 }
420 s->boss_waiting = FALSE;
422 s->data_ready = FALSE;
423 }
424 pthread_mutex_unlock(&s->lock);
425
426 s->frame.data_len = ret;
427
428 return &s->frame;
429}
#define TRUE
int ring_buffer_read(struct ring_buffer *ring, char *out, int max_len)
int data_len
Definition types.h:103

References state_ca_capture::boss_waiting, state_ca_capture::buffer, state_ca_capture::cv, audio_frame::data, audio_frame::data_len, state_ca_capture::data_ready, FALSE, state_ca_capture::frame, state_ca_capture::lock, audio_frame::max_size, ring_buffer_read(), state, and TRUE.

Here is the call graph for this function:

◆ DestroyAudioBufferList()

static void DestroyAudioBufferList ( AudioBufferList * list)
static

Definition at line 116 of file coreaudio.m.

117{
118 UInt32 i;
119
120 if(list) {
121 for(i = 0; i < list->mNumberBuffers; i++) {
122 if(list->mBuffers[i].mData)
123 free(list->mBuffers[i].mData);
124 }
125 free(list);
126 }
127}

Referenced by AllocateAudioBufferList(), audio_cap_ca_done(), and audio_cap_ca_init().

◆ InputProc()

static OSStatus InputProc ( void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData )
static

Definition at line 129 of file coreaudio.m.

135{
136 UNUSED(ioData);
137 struct state_ca_capture * s = (struct state_ca_capture *) inRefCon;
138
139 OSStatus err =noErr;
140
141 err= AudioUnitRender(s->auHALComponentInstance, ioActionFlags, inTimeStamp, inBusNumber, //will be '1' for input data
142 inNumberFrames, //# of frames requested
143 s->theBufferList);
144
145 if(err == noErr) {
146 int i;
147 int len = inNumberFrames * s->audio_packet_size;
148 for(i = 0; i < s->frame.ch_count; ++i)
149 mux_channel(s->tmp, s->theBufferList->mBuffers[i].mData, s->frame.bps, len, s->frame.ch_count, i, 1.0);
150 uint32_t write_bytes = len * s->frame.ch_count;
151
152 pthread_mutex_lock(&s->lock);
153 ring_buffer_write(s->buffer, s->tmp, write_bytes);
154 s->data_ready = TRUE;
155 if(s->boss_waiting)
156 pthread_cond_signal(&s->cv);
157 pthread_mutex_unlock(&s->lock);
158 } else {
159 log_msg(LOG_LEVEL_ERROR, MOD_NAME "writing buffer caused error %s.\n", get_osstatus_str(err));
160 }
161
162 return err;
163}
struct video_frame * frame
int void size_t * len
void ring_buffer_write(struct ring_buffer *ring, const char *in, int len)
void mux_channel(char *out, const char *in, int bps, int in_len, int out_stream_channels, int pos_in_stream, double scale)
Definition utils.cpp:371

References state_ca_capture::audio_packet_size, state_ca_capture::auHALComponentInstance, state_ca_capture::boss_waiting, audio_frame::bps, state_ca_capture::buffer, audio_frame::ch_count, state_ca_capture::cv, state_ca_capture::data_ready, state_ca_capture::frame, get_osstatus_str(), len, state_ca_capture::lock, LOG_LEVEL_ERROR, log_msg(), MOD_NAME, mux_channel(), ring_buffer_write(), state_ca_capture::theBufferList, state_ca_capture::tmp, TRUE, and UNUSED.

Referenced by audio_cap_ca_init().

Here is the call graph for this function:

◆ REGISTER_MODULE()

REGISTER_MODULE ( coreaudio ,
& acap_coreaudio_info,
LIBRARY_CLASS_AUDIO_CAPTURE ,
AUDIO_CAPTURE_ABI_VERSION  )

Variable Documentation

◆ acap_coreaudio_info

const struct audio_capture_info acap_coreaudio_info
static
Initial value:
= {
}
static void audio_cap_ca_done(void *state)
Definition coreaudio.m:431
static void * audio_cap_ca_init(struct module *parent, const char *cfg)
Definition coreaudio.m:206
static struct audio_frame * audio_cap_ca_read(void *state)
Definition coreaudio.m:408

Definition at line 448 of file coreaudio.m.