From a021a6497b786348d7b2116cdfbccf2d00970093 Mon Sep 17 00:00:00 2001 From: letz Date: Tue, 23 Aug 2005 07:30:39 +0000 Subject: [PATCH] Remove get_device_id_from_num, use get_default_device instead. If the -n option is not used or the device name cannot be found, the default device is used. Note: the default device can be used only if both default input and default output are the same. git-svn-id: svn+ssh://jackaudio.org/trunk/jack@919 0c269be4-1314-0410-8aa9-9f06e86f4224 --- drivers/coreaudio/coreaudio_driver.c | 164 ++++++++++++++++----------- 1 file changed, 100 insertions(+), 64 deletions(-) diff --git a/drivers/coreaudio/coreaudio_driver.c b/drivers/coreaudio/coreaudio_driver.c index e3aeaef..9cbb134 100755 --- a/drivers/coreaudio/coreaudio_driver.c +++ b/drivers/coreaudio/coreaudio_driver.c @@ -38,11 +38,9 @@ Jun 06, 2005: S.Letz: Remove the "-I" parameter, change the semantic of "-n" parameter : -n (driver name) now correctly uses the PropertyDeviceUID (persistent accross reboot...) as the identifier for the used coreaudio driver. Jun 14, 2005: S.Letz: Since the "-I" parameter is not used anymore, rename the "systemic" latencies management parametes "-I" and "-O" like for the ALSA driver. - + Aug 16, 2005: S.Letz: Remove get_device_id_from_num, use get_default_device instead. If the -n option is not used or the device name cannot + be found, the default device is used. Note: the default device can be used only if both default input and default output are the same. - TODO: - - fix cpu load behavior. - - multiple-device processing. */ #include @@ -100,15 +98,15 @@ static void printError1(OSStatus err) JCALog("error code : kAudioDevicePermissionsError\n"); break; default: - JCALog("error code : unknown\n"); + JCALog("error code : unknown %ld\n", err); break; } #endif } -static OSStatus get_device_name_from_id(AudioDeviceID id, char name[60]) +static OSStatus get_device_name_from_id(AudioDeviceID id, char name[256]) { - UInt32 size = sizeof(char) * 60; + UInt32 size = sizeof(char) * 256; OSStatus res = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, @@ -126,27 +124,35 @@ static OSStatus get_device_id_from_uid(char* UID, AudioDeviceID* id) } else { OSStatus res = AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &value); CFRelease(inIUD); - return res; + JCALog("get_device_id_from_uid %s %ld \n", UID, *id); + return (*id == kAudioDeviceUnknown) ? kAudioHardwareBadDeviceError : res; } } -static OSStatus get_device_id_from_num(int i, AudioDeviceID * id) +static OSStatus get_default_device(AudioDeviceID * id) { - OSStatus theStatus; - UInt32 theSize; - int nDevices; - AudioDeviceID* theDeviceList; - - theStatus = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, - &theSize, NULL); - nDevices = theSize / sizeof(AudioDeviceID); - theDeviceList = - (AudioDeviceID*) malloc(nDevices * sizeof(AudioDeviceID)); - theStatus = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, - &theSize, theDeviceList); - - *id = theDeviceList[i]; - return theStatus; + OSStatus res; + UInt32 theSize = sizeof(UInt32); + AudioDeviceID inDefault; + AudioDeviceID outDefault; + + if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, + &theSize, &inDefault)) != noErr) + return res; + + if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, + &theSize, &outDefault)) != noErr) + return res; + + JCALog("get_default_device: input %ld output %ld\n", inDefault, outDefault); + + // Get the device only if default input and ouput are the same + if (inDefault == outDefault) { + *id = inDefault; + return noErr; + } else { + return kAudioHardwareBadDeviceError; + } } static OSStatus render(void *inRefCon, @@ -259,8 +265,6 @@ coreaudio_driver_attach(coreaudio_driver_t * driver, */ for (chn = 0; chn < driver->capture_nchannels; chn++) { - //snprintf (buf, sizeof(buf) - 1, "capture_%lu", chn+1); - err = AudioDeviceGetPropertyInfo(driver->device_id, chn + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable); if (err == noErr && size > 0) { err = AudioDeviceGetProperty(driver->device_id, chn + 1, true, kAudioDevicePropertyChannelName, &size, channel_name); @@ -295,8 +299,6 @@ coreaudio_driver_attach(coreaudio_driver_t * driver, port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for (chn = 0; chn < driver->playback_nchannels; chn++) { - //snprintf (buf, sizeof(buf) - 1, "playback_%lu", chn+1); - err = AudioDeviceGetPropertyInfo(driver->device_id, chn + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable); if (err == noErr && size > 0) { err = AudioDeviceGetProperty(driver->device_id, chn + 1, false, kAudioDevicePropertyChannelName, &size, channel_name); @@ -430,8 +432,9 @@ static jack_driver_t *coreaudio_driver_new(char* name, ComponentResult err1; UInt32 outSize; Boolean isWritable; - AudioStreamBasicDescription srcFormat, dstFormat, sampleRate; + AudioStreamBasicDescription srcFormat, dstFormat; int in_nChannels, out_nChannels, i; + Float64 nominalSampleRate; driver = (coreaudio_driver_t *) calloc(1, sizeof(coreaudio_driver_t)); jack_driver_init((jack_driver_t *) driver); @@ -461,14 +464,17 @@ static jack_driver_t *coreaudio_driver_new(char* name, driver->playback_frame_latency = playback_latency; if (driver_uid) { - if (get_device_id_from_uid(driver_uid, &driver->device_id) != noErr) - return NULL; + if (get_device_id_from_uid(driver_uid, &driver->device_id) != noErr) { + if (get_default_device(&driver->device_id) != noErr) + goto error; + } } else { - get_device_id_from_num(0, &driver->device_id); // takes a default value (first device) + if (get_default_device(&driver->device_id) != noErr) + goto error; } if (get_device_name_from_id(driver->device_id, driver->driver_name) != noErr) - return NULL; + goto error; driver->client = client; driver->period_usecs = @@ -483,31 +489,42 @@ static jack_driver_t *coreaudio_driver_new(char* name, err = AudioDeviceSetProperty(driver->device_id, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &frames_per_cycle); if (err != noErr) { - jack_error("Cannot set buffer size %ld\n", frames_per_cycle); + JCALog("Cannot set buffer size %ld\n", frames_per_cycle); printError1(err); - return NULL; + goto error; } - - // Setting sample rate - outSize = sizeof(AudioStreamBasicDescription); + + outSize = sizeof(Float64); err = AudioDeviceGetProperty(driver->device_id, 0, false, - kAudioDevicePropertyStreamFormat, &outSize, &sampleRate); + kAudioDevicePropertyNominalSampleRate, &outSize, &nominalSampleRate); if (err != noErr) { - jack_error("Cannot get sample rate\n"); + JCALog("Cannot get sample rate\n"); printError1(err); - return NULL; - } + goto error; + } else { + JCALog("Read nominalSampleRate %f\n", nominalSampleRate); + } - if (rate != (unsigned long)sampleRate.mSampleRate) { - sampleRate.mSampleRate = (Float64)rate; + if (rate != (jack_nframes_t)nominalSampleRate) { + nominalSampleRate = (Float64)rate; err = AudioDeviceSetProperty(driver->device_id, NULL, 0, - false, kAudioDevicePropertyStreamFormat, outSize, &sampleRate); + false, kAudioDevicePropertyNominalSampleRate, outSize, &nominalSampleRate); if (err != noErr) { - jack_error("Cannot set sample rate %ld\n", rate); + JCALog("Cannot set sample rate %ld\n", rate); printError1(err); - return NULL; + goto error; } } + + err = AudioDeviceGetProperty(driver->device_id, 0, false, + kAudioDevicePropertyNominalSampleRate, &outSize, &nominalSampleRate); + if (err != noErr) { + JCALog("Cannot get sample rate\n"); + printError1(err); + goto error; + } else { + JCALog("Read again nominalSampleRate %f\n", nominalSampleRate); + } // AUHAL ComponentDescription cd = {kAudioUnitType_Output, @@ -518,22 +535,18 @@ static jack_driver_t *coreaudio_driver_new(char* name, if (err1 != noErr) goto error; - err1 = AudioUnitSetProperty(driver->au_hal, kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Global, 0, &driver->device_id, sizeof(AudioDeviceID)); - if (err1 != noErr) { - JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n"); - return NULL; - } - err1 = AudioUnitInitialize(driver->au_hal); - if (err1 != noErr) + if (err1 != noErr) { + printError1(err1); goto error; + } outSize = 1; err1 = AudioUnitSetProperty(driver->au_hal, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &outSize, sizeof(outSize)); if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output\n"); + printError1(err1); goto error; } @@ -543,28 +556,42 @@ static jack_driver_t *coreaudio_driver_new(char* name, kAudioUnitScope_Input, 1, &outSize, sizeof(outSize)); if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Input\n"); + printError1(err1); goto error; } } + err1 = AudioUnitSetProperty(driver->au_hal, kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, 0, &driver->device_id, sizeof(AudioDeviceID)); + if (err1 != noErr) { + JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n"); + printError1(err1); + goto error; + } + err1 = AudioUnitSetProperty(driver->au_hal, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&frames_per_cycle, sizeof(UInt32)); if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n"); + printError1(err1); goto error; } err1 = AudioUnitGetPropertyInfo(driver->au_hal, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, &outSize, &isWritable); - if (err1 != noErr) + if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 1\n"); + printError1(err1); + } in_nChannels = outSize / sizeof(SInt32); err1 = AudioUnitGetPropertyInfo(driver->au_hal, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, &outSize, &isWritable); - if (err1 != noErr) + if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 0\n"); + printError1(err1); + } out_nChannels = outSize / sizeof(SInt32); @@ -578,7 +605,7 @@ static jack_driver_t *coreaudio_driver_new(char* name, } if (chan_out < out_nChannels) { - SInt32 chanArr[out_nChannels]; // ??? + SInt32 chanArr[out_nChannels]; for (i = 0;i < out_nChannels; i++) { chanArr[i] = -1; } @@ -587,8 +614,10 @@ static jack_driver_t *coreaudio_driver_new(char* name, } err1 = AudioUnitSetProperty(driver->au_hal, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels); - if (err1 != noErr) + if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0\n"); + printError1(err1); + } } if (chan_in < in_nChannels) { @@ -601,8 +630,10 @@ static jack_driver_t *coreaudio_driver_new(char* name, } AudioUnitSetProperty(driver->au_hal, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels); - if (err1 != noErr) + if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1\n"); + printError1(err1); + } } srcFormat.mSampleRate = rate; @@ -619,8 +650,10 @@ static jack_driver_t *coreaudio_driver_new(char* name, err1 = AudioUnitSetProperty(driver->au_hal, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) + if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n"); + printError1(err1); + } dstFormat.mSampleRate = rate; dstFormat.mFormatID = kAudioFormatLinearPCM; @@ -636,8 +669,10 @@ static jack_driver_t *coreaudio_driver_new(char* name, err1 = AudioUnitSetProperty(driver->au_hal, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) + if (err1 != noErr) { JCALog("error: calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n"); + printError1(err1); + } if (chan_in > 0 && chan_out== 0) { AURenderCallbackStruct output; @@ -647,6 +682,7 @@ static jack_driver_t *coreaudio_driver_new(char* name, kAudioUnitScope_Output, 1, &output, sizeof(output)); if (err1 != noErr) { JCALog("AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n"); + printError1(err1); goto error; } } else { @@ -657,6 +693,7 @@ static jack_driver_t *coreaudio_driver_new(char* name, kAudioUnitScope_Input, 0, &output, sizeof(output)); if (err1 != noErr) { JCALog("AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n"); + printError1(err1); goto error; } } @@ -691,7 +728,7 @@ static jack_driver_t *coreaudio_driver_new(char* name, error: AudioUnitUninitialize(driver->au_hal); CloseComponent(driver->au_hal); - jack_error("Cannot open the coreaudio driver\n"); + jack_error("Cannot open the coreaudio driver"); free(driver); return NULL; } @@ -883,7 +920,6 @@ jack_driver_t *driver_initialize(jack_client_t * client, } /* duplex is the default */ - if (!capture && !playback) { capture = TRUE; playback = TRUE;