diff options
Diffstat (limited to 'drivers/portaudio/portaudio_driver.c')
-rw-r--r-- | drivers/portaudio/portaudio_driver.c | 847 |
1 files changed, 442 insertions, 405 deletions
diff --git a/drivers/portaudio/portaudio_driver.c b/drivers/portaudio/portaudio_driver.c index f7b78bf..5735bea 100644 --- a/drivers/portaudio/portaudio_driver.c +++ b/drivers/portaudio/portaudio_driver.c @@ -18,24 +18,24 @@ Grame Research Laboratory, 9, rue du Garet 69001 Lyon - France grame@rd.grame.fr - + 02-09-03 : Modify jack port naming : add the name of the used driver Add the -n option to load a specific driver using it's name 04-09-03 : Correct bug in -n option management : input and ouput have to be treated separately 08-09-03 : More robust driver loading code : new portaudio_load_default and portaudio_load_driver functions. 24-09-03 : Does not tries to load default device if the required one is not found, returns and error. 14-10-03 : After jack port name size extension, does not use fixed length for CoreAudio driver name anymore - 09-01-04 : Handle different value for channel in and channel out (using -i and -o) - 12-01-04 : Connect port names (inverse "in" and "out") - 13-01-04 : Correct the length of jack port : use JACK_PORT_NAME_SIZE - 22-03-04 : Remove jack_init_time, rename input and ouput ports using "capture" and "playback" + 09-01-04 : Handle different value for channel in and channel out (using -i and -o) + 12-01-04 : Connect port names (inverse "in" and "out") + 13-01-04 : Correct the length of jack port : use JACK_PORT_NAME_SIZE + 22-03-04 : Remove jack_init_time, rename input and ouput ports using "capture" and "playback" 10-11-04 : S. Letz: Add management of -I option for use with JackPilot. - 17-11-04 : S. Letz: Better debug code. - 03-02-05 : S. Letz: fix several driver detection bugs on OSX. - 06-08-05 : S.Letz: Remove the "-I" parameter, change the semantic of "-n" parameter on OSX : -n (driver name) now correctly uses the PropertyDeviceUID - (persistent accross reboot...) as the identifier for the used coreaudio driver. + 17-11-04 : S. Letz: Better debug code. + 03-02-05 : S. Letz: fix several driver detection bugs on OSX. + 06-08-05 : S.Letz: Remove the "-I" parameter, change the semantic of "-n" parameter on OSX : -n (driver name) now correctly uses the PropertyDeviceUID + (persistent accross reboot...) as the identifier for the used coreaudio driver. -*/ + */ #include <stdio.h> #include <errno.h> @@ -50,47 +50,49 @@ #include <CoreAudio/CoreAudio.h> #include <CoreFoundation/CFString.h> -static OSStatus get_device_name_from_id(AudioDeviceID id, char name[60]) +static OSStatus get_device_name_from_id (AudioDeviceID id, char name[60]) { - UInt32 size = sizeof(char) * 60; - OSStatus stat = AudioDeviceGetProperty(id, 0, false, - kAudioDevicePropertyDeviceName, - &size, - &name[0]); - return stat; + UInt32 size = sizeof(char) * 60; + OSStatus stat = AudioDeviceGetProperty (id, 0, false, + kAudioDevicePropertyDeviceName, + &size, + &name[0]); + + return stat; } -static OSStatus get_device_id_from_num(int i, AudioDeviceID * id) +static OSStatus get_device_id_from_num (int i, 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 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; } -static OSStatus get_device_id_from_uid(char* UID, AudioDeviceID* id) +static OSStatus get_device_id_from_uid (char* UID, AudioDeviceID* id) { UInt32 size = sizeof(AudioValueTranslation); - CFStringRef inIUD = CFStringCreateWithCString(NULL, UID, CFStringGetSystemEncoding()); + CFStringRef inIUD = CFStringCreateWithCString (NULL, UID, CFStringGetSystemEncoding ()); AudioValueTranslation value = { &inIUD, sizeof(CFStringRef), id, sizeof(AudioDeviceID) }; + if (inIUD == NULL) { return kAudioHardwareUnspecifiedError; } else { - OSStatus res = AudioHardwareGetProperty(kAudioHardwarePropertyDeviceForUID, &size, &value); - CFRelease(inIUD); + OSStatus res = AudioHardwareGetProperty (kAudioHardwarePropertyDeviceForUID, &size, &value); + CFRelease (inIUD); return res; } } @@ -101,28 +103,28 @@ typedef unsigned int AudioDeviceID; #define PRINTDEBUG 1 -void PALog(char *fmt, ...) +void PALog (char *fmt, ...) { #ifdef PRINTDEBUG - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "JCA: "); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_list ap; + va_start (ap, fmt); + fprintf (stderr, "JCA: "); + vfprintf (stderr, fmt, ap); + va_end (ap); #endif } static int -paCallback(void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData) +paCallback (void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData) { portaudio_driver_t * driver = (portaudio_driver_t*)userData; driver->inPortAudio = (float*)inputBuffer; driver->outPortAudio = (float*)outputBuffer; - driver->last_wait_ust = driver->engine->get_microseconds(); - return driver->engine->run_cycle(driver->engine, framesPerBuffer, 0); + driver->last_wait_ust = driver->engine->get_microseconds (); + return driver->engine->run_cycle (driver->engine, framesPerBuffer, 0); } static int @@ -133,61 +135,61 @@ portaudio_driver_attach (portaudio_driver_t *driver, jack_engine_t *engine) channel_t chn; char buf[JACK_PORT_NAME_SIZE]; jack_latency_range_t range; - + driver->engine = engine; - + if (driver->engine->set_buffer_size (engine, driver->frames_per_cycle)) { jack_error ("portaudio: cannot set engine buffer size to %d (check MIDI)", driver->frames_per_cycle); return -1; } driver->engine->set_sample_rate (engine, driver->frame_rate); - - port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal; + + port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; /* - if (driver->has_hw_monitoring) { - port_flags |= JackPortCanMonitor; - } - */ + if (driver->has_hw_monitoring) { + port_flags |= JackPortCanMonitor; + } + */ for (chn = 0; chn < driver->capture_nchannels; chn++) { - //snprintf (buf, sizeof(buf) - 1, "%s:capture%lu", driver->driver_name, chn+1); - snprintf (buf, sizeof(buf) - 1, "%s:out%lu", driver->driver_name, chn+1); + //snprintf (buf, sizeof(buf) - 1, "%s:capture%lu", driver->driver_name, chn+1); + snprintf (buf, sizeof(buf) - 1, "%s:out%lu", driver->driver_name, chn + 1); - if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) { - jack_error ("portaudio: cannot register port for %s", buf); - break; - } + if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) { + jack_error ("portaudio: cannot register port for %s", buf); + break; + } - /* XXX fix this so that it can handle: systemic (external) latency - */ + /* XXX fix this so that it can handle: systemic (external) latency + */ - range.min = range.max = driver->frames_per_cycle; - jack_port_set_latency_range (port, JackCaptureLatency, &range); - driver->capture_ports = jack_slist_append (driver->capture_ports, port); + range.min = range.max = driver->frames_per_cycle; + jack_port_set_latency_range (port, JackCaptureLatency, &range); + driver->capture_ports = jack_slist_append (driver->capture_ports, port); } - - port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal; + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for (chn = 0; chn < driver->playback_nchannels; chn++) { - //snprintf (buf, sizeof(buf) - 1, "%s:playback%lu", driver->driver_name, chn+1); - snprintf (buf, sizeof(buf) - 1, "%s:in%lu", driver->driver_name, chn+1); + //snprintf (buf, sizeof(buf) - 1, "%s:playback%lu", driver->driver_name, chn+1); + snprintf (buf, sizeof(buf) - 1, "%s:in%lu", driver->driver_name, chn + 1); - if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) { - jack_error ("portaudio: cannot register port for %s", buf); - break; - } - - /* XXX fix this so that it can handle: systemic (external) latency - */ - - range.min = range.max = driver->frames_per_cycle; - jack_port_set_latency_range (port, JackPlaybackLatency, &range); - driver->playback_ports = jack_slist_append (driver->playback_ports, port); + if ((port = jack_port_register (driver->client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0)) == NULL) { + jack_error ("portaudio: cannot register port for %s", buf); + break; + } + + /* XXX fix this so that it can handle: systemic (external) latency + */ + + range.min = range.max = driver->frames_per_cycle; + jack_port_set_latency_range (port, JackPlaybackLatency, &range); + driver->playback_ports = jack_slist_append (driver->playback_ports, port); } jack_activate (driver->client); - return 0; + return 0; } static int @@ -196,31 +198,29 @@ portaudio_driver_detach (portaudio_driver_t *driver, jack_engine_t *engine) JSList *node; if (driver->engine == 0) { - return -1; + return -1; } - for (node = driver->capture_ports; node; node = jack_slist_next (node)) { - jack_port_unregister (driver->client, ((jack_port_t *) node->data)); - } + for (node = driver->capture_ports; node; node = jack_slist_next (node)) + jack_port_unregister (driver->client, ((jack_port_t*)node->data)); jack_slist_free (driver->capture_ports); driver->capture_ports = 0; - - for (node = driver->playback_ports; node; node = jack_slist_next (node)) { - jack_port_unregister (driver->client, ((jack_port_t *) node->data)); - } + + for (node = driver->playback_ports; node; node = jack_slist_next (node)) + jack_port_unregister (driver->client, ((jack_port_t*)node->data)); jack_slist_free (driver->playback_ports); driver->playback_ports = 0; - + driver->engine = 0; - return 0; + return 0; } static int portaudio_driver_null_cycle (portaudio_driver_t* driver, jack_nframes_t nframes) { - memset(driver->outPortAudio, 0, (driver->playback_nchannels * nframes * sizeof(float))); + memset (driver->outPortAudio, 0, (driver->playback_nchannels * nframes * sizeof(float))); return 0; } @@ -234,22 +234,22 @@ portaudio_driver_read (portaudio_driver_t *driver, jack_nframes_t nframes) int i; for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) { - - port = (jack_port_t *)node->data; - - if (jack_port_connected (port) && (driver->inPortAudio != NULL)) { - int channels = driver->capture_nchannels; - float* in = driver->inPortAudio; - buf = jack_port_get_buffer (port, nframes); - for (i = 0; i< nframes; i++) buf[i] = in[channels*i+chn]; - } + + port = (jack_port_t*)node->data; + + if (jack_port_connected (port) && (driver->inPortAudio != NULL)) { + int channels = driver->capture_nchannels; + float* in = driver->inPortAudio; + buf = jack_port_get_buffer (port, nframes); + for (i = 0; i < nframes; i++) buf[i] = in[channels * i + chn]; + } } - + driver->engine->transport_cycle_start (driver->engine, - driver->engine->get_microseconds ()); + driver->engine->get_microseconds ()); return 0; -} +} static int @@ -259,70 +259,72 @@ portaudio_driver_write (portaudio_driver_t *driver, jack_nframes_t nframes) channel_t chn; jack_port_t *port; JSList *node; - int i,bytes = nframes*sizeof(float); - + int i, bytes = nframes * sizeof(float); + /* Clear in case of nothing is connected */ - memset(driver->outPortAudio, 0, driver->playback_nchannels*bytes); - + memset (driver->outPortAudio, 0, driver->playback_nchannels * bytes); + for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) { - - port = (jack_port_t *)node->data; - - if (jack_port_connected (port) && (driver->outPortAudio != NULL)) { - int channels = driver->playback_nchannels; - float* out = driver->outPortAudio; - buf = jack_port_get_buffer (port, nframes); - for (i = 0; i< nframes; i++) out[channels*i+chn] = buf[i]; - } + + port = (jack_port_t*)node->data; + + if (jack_port_connected (port) && (driver->outPortAudio != NULL)) { + int channels = driver->playback_nchannels; + float* out = driver->outPortAudio; + buf = jack_port_get_buffer (port, nframes); + for (i = 0; i < nframes; i++) out[channels * i + chn] = buf[i]; + } } - + return 0; } static int portaudio_driver_audio_start (portaudio_driver_t *driver) { - PaError err = Pa_StartStream(driver->stream); + PaError err = Pa_StartStream (driver->stream); + return (err != paNoError) ? -1 : 0; } static int portaudio_driver_audio_stop (portaudio_driver_t *driver) { - PaError err = Pa_StopStream(driver->stream); + PaError err = Pa_StopStream (driver->stream); + return (err != paNoError) ? -1 : 0; } static int portaudio_driver_set_parameters (portaudio_driver_t* driver, - jack_nframes_t nframes, - jack_nframes_t rate) + jack_nframes_t nframes, + jack_nframes_t rate) { int capturing = driver->capturing; int playing = driver->playing; - int err = Pa_OpenStream( + int err = Pa_OpenStream ( &driver->stream, - ((capturing) ? Pa_GetDefaultInputDeviceID() : paNoDevice), - ((capturing) ? driver->capture_nchannels : 0), - paFloat32, /* 32-bit float input */ + ((capturing) ? Pa_GetDefaultInputDeviceID () : paNoDevice), + ((capturing) ? driver->capture_nchannels : 0), + paFloat32, /* 32-bit float input */ NULL, - ((playing) ? Pa_GetDefaultOutputDeviceID() : paNoDevice), - ((playing) ? driver->playback_nchannels : 0), - paFloat32, /* 32-bit float output */ + ((playing) ? Pa_GetDefaultOutputDeviceID () : paNoDevice), + ((playing) ? driver->playback_nchannels : 0), + paFloat32, /* 32-bit float output */ NULL, - rate, /* sample rate */ - nframes, /* frames per buffer */ - 0, /* number of buffers = default min */ - paClipOff, /* we won't output out of - * range samples so don't - * bother clipping them */ + rate, /* sample rate */ + nframes, /* frames per buffer */ + 0, /* number of buffers = default min */ + paClipOff, /* we won't output out of + * range samples so don't + * bother clipping them */ paCallback, driver); - + if (err == paNoError) { - - driver->period_usecs = (((float) driver->frames_per_cycle) + + driver->period_usecs = (((float)driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f; driver->frame_rate = rate; driver->frames_per_cycle = nframes; @@ -334,17 +336,17 @@ portaudio_driver_set_parameters (portaudio_driver_t* driver, jack_error ("portaudio: cannot set engine buffer size to %d (check MIDI)", driver->frames_per_cycle); return -1; } - + } return 0; - } else { + } else { // JOQ: this driver is dead. How do we terminate it? - Pa_Terminate(); - jack_error("Unable to set portaudio parameters"); - jack_error("Error number: %d", err); - jack_error("Error message: %s", Pa_GetErrorText(err)); + Pa_Terminate (); + jack_error ("Unable to set portaudio parameters"); + jack_error ("Error number: %d", err); + jack_error ("Error message: %s", Pa_GetErrorText (err)); return EIO; } } @@ -354,13 +356,13 @@ portaudio_driver_reset_parameters (portaudio_driver_t* driver, jack_nframes_t nframes, jack_nframes_t rate) { - if (!jack_power_of_two(nframes)) { - jack_error("PA: frames must be a power of two " - "(64, 512, 1024, ...)"); + if (!jack_power_of_two (nframes)) { + jack_error ("PA: frames must be a power of two " + "(64, 512, 1024, ...)"); return EINVAL; } - Pa_CloseStream(driver->stream); + Pa_CloseStream (driver->stream); return portaudio_driver_set_parameters (driver, nframes, rate); } @@ -391,166 +393,190 @@ portaudio_driver_bufsize (portaudio_driver_t* driver, jack_nframes_t nframes) //== instance creation/destruction ============================================= -static int portaudio_load_default (portaudio_driver_t *driver, - int numDevices, - int capturing, - int playing, - int* inputDeviceID, - int* outputDeviceID) +static int portaudio_load_default (portaudio_driver_t *driver, + int numDevices, + int capturing, + int playing, + int* inputDeviceID, + int* outputDeviceID) { - const PaDeviceInfo *pdi; - int i,j; - int found = 0; - - PALog("Look for default driver\n"); - - *inputDeviceID = Pa_GetDefaultInputDeviceID(); - *outputDeviceID = Pa_GetDefaultOutputDeviceID(); - - for(i=0; i<numDevices; i++) - { - pdi = Pa_GetDeviceInfo(i); - PALog("---------------------------------------------- #%d\n", i); - - if (i == Pa_GetDefaultInputDeviceID()) { - driver->capture_nchannels = (capturing) ? pdi->maxInputChannels : 0; - strcpy (driver->driver_name,pdi->name); - found = 1; - } - - if (i == Pa_GetDefaultOutputDeviceID()){ - driver->playback_nchannels = (playing) ? pdi->maxOutputChannels : 0; - strcpy (driver->driver_name,pdi->name); - found = 1; - } - - PALog("\nName = %s\n", pdi->name); - PALog("Max Inputs = %d ", pdi->maxInputChannels); - PALog("Max Outputs = %d\n", pdi->maxOutputChannels); - if( pdi->numSampleRates == -1 ){ - PALog("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1]); - }else{ - PALog("Sample Rates ="); - for(j=0; j<pdi->numSampleRates; j++){ - PALog(" %8.2f,", pdi->sampleRates[j]); - } - PALog("\n"); - } - - PALog("Native Sample Formats = "); - if (pdi->nativeSampleFormats & paInt8) PALog("paInt8, "); - if (pdi->nativeSampleFormats & paUInt8) PALog("paUInt8, "); - if (pdi->nativeSampleFormats & paInt16) PALog("paInt16, "); - if (pdi->nativeSampleFormats & paInt32) PALog("paInt32, "); - if (pdi->nativeSampleFormats & paFloat32) PALog("paFloat32, "); - if (pdi->nativeSampleFormats & paInt24) PALog("paInt24, "); - if (pdi->nativeSampleFormats & paPackedInt24) PALog("paPackedInt24, "); - PALog("\n"); - } - - return found; + const PaDeviceInfo *pdi; + int i, j; + int found = 0; + + PALog ("Look for default driver\n"); + + *inputDeviceID = Pa_GetDefaultInputDeviceID (); + *outputDeviceID = Pa_GetDefaultOutputDeviceID (); + + for (i = 0; i < numDevices; i++) { + pdi = Pa_GetDeviceInfo (i); + PALog ("---------------------------------------------- #%d\n", i); + + if (i == Pa_GetDefaultInputDeviceID ()) { + driver->capture_nchannels = (capturing) ? pdi->maxInputChannels : 0; + strcpy (driver->driver_name, pdi->name); + found = 1; + } + + if (i == Pa_GetDefaultOutputDeviceID ()) { + driver->playback_nchannels = (playing) ? pdi->maxOutputChannels : 0; + strcpy (driver->driver_name, pdi->name); + found = 1; + } + + PALog ("\nName = %s\n", pdi->name); + PALog ("Max Inputs = %d ", pdi->maxInputChannels); + PALog ("Max Outputs = %d\n", pdi->maxOutputChannels); + if ( pdi->numSampleRates == -1 ) { + PALog ("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1]); + } else { + PALog ("Sample Rates ="); + for (j = 0; j < pdi->numSampleRates; j++) + PALog (" %8.2f,", pdi->sampleRates[j]); + PALog ("\n"); + } + + PALog ("Native Sample Formats = "); + if (pdi->nativeSampleFormats & paInt8) { + PALog ("paInt8, "); + } + if (pdi->nativeSampleFormats & paUInt8) { + PALog ("paUInt8, "); + } + if (pdi->nativeSampleFormats & paInt16) { + PALog ("paInt16, "); + } + if (pdi->nativeSampleFormats & paInt32) { + PALog ("paInt32, "); + } + if (pdi->nativeSampleFormats & paFloat32) { + PALog ("paFloat32, "); + } + if (pdi->nativeSampleFormats & paInt24) { + PALog ("paInt24, "); + } + if (pdi->nativeSampleFormats & paPackedInt24) { + PALog ("paPackedInt24, "); + } + PALog ("\n"); + } + + return found; } -static int portaudio_load_driver (portaudio_driver_t *driver, - int numDevices, - int capturing, - int playing, - int* inputDeviceID, - int* outputDeviceID, - char* driver_name) +static int portaudio_load_driver (portaudio_driver_t *driver, + int numDevices, + int capturing, + int playing, + int* inputDeviceID, + int* outputDeviceID, + char* driver_name) { - const PaDeviceInfo *pdi; - int found = 0; - int i,j; - - PALog("Look for %s driver\n",driver_name); - - for(i=0; i<numDevices; i++) - { - pdi = Pa_GetDeviceInfo(i); - PALog("---------------------------------------------- #%d\n", i); - + const PaDeviceInfo *pdi; + int found = 0; + int i, j; + + PALog ("Look for %s driver\n", driver_name); + + for (i = 0; i < numDevices; i++) { + pdi = Pa_GetDeviceInfo (i); + PALog ("---------------------------------------------- #%d\n", i); + // compare the first character if (strncmp (driver_name, pdi->name, - JACK_DRIVER_PARAM_STRING_MAX) == 0) { - if (pdi->maxInputChannels > 0) { - *inputDeviceID = i; - driver->capture_nchannels = - (capturing) ? pdi->maxInputChannels : 0; - strcpy(driver->driver_name,pdi->name); - PALog("Found input driver = %s\n", driver_name); - found = 1; + JACK_DRIVER_PARAM_STRING_MAX) == 0) { + if (pdi->maxInputChannels > 0) { + *inputDeviceID = i; + driver->capture_nchannels = + (capturing) ? pdi->maxInputChannels : 0; + strcpy (driver->driver_name, pdi->name); + PALog ("Found input driver = %s\n", driver_name); + found = 1; + } + if (pdi->maxOutputChannels > 0) { + *outputDeviceID = i; + driver->playback_nchannels = + (playing) ? pdi->maxOutputChannels : 0; + strcpy (driver->driver_name, pdi->name); + PALog ("Found output driver = %s\n", driver_name); + found = 1; + } else { + PALog ("Found driver without input or ouput = %s\n", + driver_name); + } } - if (pdi->maxOutputChannels > 0) { - *outputDeviceID = i; - driver->playback_nchannels = - (playing) ? pdi->maxOutputChannels : 0; - strcpy (driver->driver_name,pdi->name); - PALog("Found output driver = %s\n", driver_name); - found = 1; + + PALog ("\nName = %s\n", pdi->name); + PALog ("Max Inputs = %d ", pdi->maxInputChannels); + PALog ("Max Outputs = %d\n", pdi->maxOutputChannels); + if ( pdi->numSampleRates == -1 ) { + PALog ("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], + pdi->sampleRates[1]); } else { - PALog("Found driver without input or ouput = %s\n", - driver_name); - } - } - - PALog("\nName = %s\n", pdi->name); - PALog("Max Inputs = %d ", pdi->maxInputChannels); - PALog("Max Outputs = %d\n", pdi->maxOutputChannels); - if( pdi->numSampleRates == -1 ){ - PALog("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], - pdi->sampleRates[1]); - }else{ - PALog("Sample Rates ="); - for(j=0; j<pdi->numSampleRates; j++){ - PALog(" %8.2f,", pdi->sampleRates[j]); - } - PALog("\n"); - } - - PALog("Native Sample Formats = "); - if (pdi->nativeSampleFormats & paInt8) PALog("paInt8, "); - if (pdi->nativeSampleFormats & paUInt8) PALog("paUInt8, "); - if (pdi->nativeSampleFormats & paInt16) PALog("paInt16, "); - if (pdi->nativeSampleFormats & paInt32) PALog("paInt32, "); - if (pdi->nativeSampleFormats & paFloat32) PALog("paFloat32, "); - if (pdi->nativeSampleFormats & paInt24) PALog("paInt24, "); - if (pdi->nativeSampleFormats & paPackedInt24) PALog("paPackedInt24, "); - PALog("\n"); - } - - return found; + PALog ("Sample Rates ="); + for (j = 0; j < pdi->numSampleRates; j++) + PALog (" %8.2f,", pdi->sampleRates[j]); + PALog ("\n"); + } + + PALog ("Native Sample Formats = "); + if (pdi->nativeSampleFormats & paInt8) { + PALog ("paInt8, "); + } + if (pdi->nativeSampleFormats & paUInt8) { + PALog ("paUInt8, "); + } + if (pdi->nativeSampleFormats & paInt16) { + PALog ("paInt16, "); + } + if (pdi->nativeSampleFormats & paInt32) { + PALog ("paInt32, "); + } + if (pdi->nativeSampleFormats & paFloat32) { + PALog ("paFloat32, "); + } + if (pdi->nativeSampleFormats & paInt24) { + PALog ("paInt24, "); + } + if (pdi->nativeSampleFormats & paPackedInt24) { + PALog ("paPackedInt24, "); + } + PALog ("\n"); + } + + return found; } /** create a new driver instance */ static jack_driver_t * -portaudio_driver_new (char *name, - jack_client_t* client, - jack_nframes_t frames_per_cycle, - jack_nframes_t rate, - int capturing, - int playing, - int chan_in, - int chan_out, - DitherAlgorithm dither, - char* driver_name) +portaudio_driver_new (char *name, + jack_client_t* client, + jack_nframes_t frames_per_cycle, + jack_nframes_t rate, + int capturing, + int playing, + int chan_in, + int chan_out, + DitherAlgorithm dither, + char* driver_name) { portaudio_driver_t *driver; PaError err = paNoError; int numDevices; - int inputDeviceID,outputDeviceID; + int inputDeviceID, outputDeviceID; int found; - - PALog("portaudio driver version : %d\n", kVersion); - PALog("creating portaudio driver ... %" PRIu32 "|%" PRIu32 "\n", - frames_per_cycle, rate); - driver = (portaudio_driver_t *) calloc (1, sizeof (portaudio_driver_t)); + PALog ("portaudio driver version : %d\n", kVersion); + PALog ("creating portaudio driver ... %" PRIu32 "|%" PRIu32 "\n", + frames_per_cycle, rate); + + driver = (portaudio_driver_t*)calloc (1, sizeof(portaudio_driver_t)); - jack_driver_init ((jack_driver_t *) driver); + jack_driver_init ((jack_driver_t*)driver); - if (!jack_power_of_two(frames_per_cycle)) { + if (!jack_power_of_two (frames_per_cycle)) { jack_error ("PA: -p must be a power of two."); goto error; } @@ -560,113 +586,123 @@ portaudio_driver_new (char *name, driver->capturing = capturing; driver->playing = playing; - driver->attach = (JackDriverAttachFunction) portaudio_driver_attach; - driver->detach = (JackDriverDetachFunction) portaudio_driver_detach; - driver->read = (JackDriverReadFunction) portaudio_driver_read; - driver->write = (JackDriverReadFunction) portaudio_driver_write; - driver->null_cycle = (JackDriverNullCycleFunction) portaudio_driver_null_cycle; - driver->bufsize = (JackDriverBufSizeFunction) portaudio_driver_bufsize; - driver->start = (JackDriverStartFunction) portaudio_driver_audio_start; - driver->stop = (JackDriverStopFunction) portaudio_driver_audio_stop; + driver->attach = (JackDriverAttachFunction)portaudio_driver_attach; + driver->detach = (JackDriverDetachFunction)portaudio_driver_detach; + driver->read = (JackDriverReadFunction)portaudio_driver_read; + driver->write = (JackDriverReadFunction)portaudio_driver_write; + driver->null_cycle = (JackDriverNullCycleFunction)portaudio_driver_null_cycle; + driver->bufsize = (JackDriverBufSizeFunction)portaudio_driver_bufsize; + driver->start = (JackDriverStartFunction)portaudio_driver_audio_start; + driver->stop = (JackDriverStopFunction)portaudio_driver_audio_stop; driver->stream = NULL; -#ifdef JACK_USE_MACH_THREADS +#ifdef JACK_USE_MACH_THREADS AudioDeviceID device_id; if (driver_name) { - if (get_device_id_from_uid(driver_name, &device_id) != noErr) + if (get_device_id_from_uid (driver_name, &device_id) != noErr) { goto error; - if (get_device_name_from_id(device_id, driver->driver_name) != noErr) + } + if (get_device_name_from_id (device_id, driver->driver_name) != noErr) { goto error; + } } else { - if (get_device_id_from_num(0, &device_id) != noErr) - goto error; - if (get_device_name_from_id(device_id, driver->driver_name) != noErr) + if (get_device_id_from_num (0, &device_id) != noErr) { + goto error; + } + if (get_device_name_from_id (device_id, driver->driver_name) != noErr) { goto error; + } } #endif - - err = Pa_Initialize(); - PALog("Pa_Initialize OK \n"); - - PALog("Driver name required %s\n",driver->driver_name); - numDevices = Pa_CountDevices(); - - if( numDevices < 0 ){ - PALog("ERROR: Pa_CountDevices returned 0x%x\n", numDevices); + + err = Pa_Initialize (); + PALog ("Pa_Initialize OK \n"); + + PALog ("Driver name required %s\n", driver->driver_name); + numDevices = Pa_CountDevices (); + + if ( numDevices < 0 ) { + PALog ("ERROR: Pa_CountDevices returned 0x%x\n", numDevices); err = numDevices; goto error; } - - PALog("Number of devices = %d\n", numDevices); - if (strcmp(driver->driver_name,"") == 0) { - found = portaudio_load_default(driver,numDevices,capturing,playing,&inputDeviceID,&outputDeviceID); + PALog ("Number of devices = %d\n", numDevices); + + if (strcmp (driver->driver_name, "") == 0) { + found = portaudio_load_default (driver, numDevices, capturing, playing, &inputDeviceID, &outputDeviceID); if (!found) { - PALog("ERROR : default driver has not been found\n"); + PALog ("ERROR : default driver has not been found\n"); err = paHostError; goto error; } - }else{ - found = portaudio_load_driver(driver,numDevices,capturing,playing,&inputDeviceID,&outputDeviceID,driver->driver_name); + } else { + found = portaudio_load_driver (driver, numDevices, capturing, playing, &inputDeviceID, &outputDeviceID, driver->driver_name); if (!found) { - PALog("ERROR : driver %s has not been found \n",driver->driver_name); - err = paHostError; - goto error; + PALog ("ERROR : driver %s has not been found \n", driver->driver_name); + err = paHostError; + goto error; } } - if (err != paNoError) goto error; - - PALog("Pa_GetDefaultOutputDeviceID() %ld\n", (long)Pa_GetDefaultOutputDeviceID()); - PALog("Pa_GetDefaultInputDeviceID() %ld\n", (long)Pa_GetDefaultInputDeviceID()); - - PALog("--------------------------------------------------\n"); - PALog("CoreAudio driver %s will be loaded\n", driver->driver_name); - PALog("inputDeviceID %ld\n", (long)inputDeviceID); - PALog("outputDeviceID %ld\n", (long)outputDeviceID); - PALog("driver->capture_nchannels %ld\n", driver->capture_nchannels); - PALog("driver->playback_nchannels %ld\n", driver->playback_nchannels); - - PALog("chan_in, chan_out %ld %ld\n", (long)chan_in, (long)chan_out); - - if (chan_in > 0) + if (err != paNoError) { + goto error; + } + + PALog ("Pa_GetDefaultOutputDeviceID() %ld\n", (long)Pa_GetDefaultOutputDeviceID ()); + PALog ("Pa_GetDefaultInputDeviceID() %ld\n", (long)Pa_GetDefaultInputDeviceID ()); + + PALog ("--------------------------------------------------\n"); + PALog ("CoreAudio driver %s will be loaded\n", driver->driver_name); + PALog ("inputDeviceID %ld\n", (long)inputDeviceID); + PALog ("outputDeviceID %ld\n", (long)outputDeviceID); + PALog ("driver->capture_nchannels %ld\n", driver->capture_nchannels); + PALog ("driver->playback_nchannels %ld\n", driver->playback_nchannels); + + PALog ("chan_in, chan_out %ld %ld\n", (long)chan_in, (long)chan_out); + + if (chan_in > 0) { driver->capture_nchannels = (driver->capture_nchannels < chan_in) ? driver->capture_nchannels : chan_in; - - if (chan_out > 0) + } + + if (chan_out > 0) { driver->playback_nchannels = (driver->playback_nchannels < chan_out) ? driver->playback_nchannels : chan_out; - - PALog("driver->capture_nchannels %ld\n", driver->capture_nchannels); - PALog("driver->playback_nchannels %ld\n", driver->playback_nchannels); - - err = Pa_OpenStream(&driver->stream, - ((capturing && (driver->capture_nchannels > 0)) ? inputDeviceID : paNoDevice), - ((capturing) ? driver->capture_nchannels : 0), - paFloat32, // 32 bit floating point input - NULL, - ((playing && (driver->playback_nchannels > 0)) ? outputDeviceID : paNoDevice), - ((playing) ? driver->playback_nchannels : 0), - paFloat32, // 32 bit floating point output - NULL, - rate, - frames_per_cycle, // frames per buffer - 0, // number of buffers, if zero then use default minimum - paClipOff, // we won't output out of range samples so don't bother clipping them - paCallback, - driver); - - if (err != paNoError) goto error; - - driver->client = client; - driver->period_usecs = (((float) driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f; - return((jack_driver_t *) driver); + } + + PALog ("driver->capture_nchannels %ld\n", driver->capture_nchannels); + PALog ("driver->playback_nchannels %ld\n", driver->playback_nchannels); + + err = Pa_OpenStream (&driver->stream, + ((capturing && (driver->capture_nchannels > 0)) ? inputDeviceID : paNoDevice), + ((capturing) ? driver->capture_nchannels : 0), + paFloat32, // 32 bit floating point input + NULL, + ((playing && (driver->playback_nchannels > 0)) ? outputDeviceID : paNoDevice), + ((playing) ? driver->playback_nchannels : 0), + paFloat32, // 32 bit floating point output + NULL, + rate, + frames_per_cycle, // frames per buffer + 0, // number of buffers, if zero then use default minimum + paClipOff, // we won't output out of range samples so don't bother clipping them + paCallback, + driver); + + if (err != paNoError) { + goto error; + } + + driver->client = client; + driver->period_usecs = (((float)driver->frames_per_cycle) / driver->frame_rate) * 1000000.0f; + return (jack_driver_t*)driver; error: - Pa_Terminate(); - jack_error("An error occured while using the portaudio stream"); - jack_error("Error number: %d", err); - jack_error("Error message: %s", Pa_GetErrorText(err)); - free(driver); + Pa_Terminate (); + jack_error ("An error occured while using the portaudio stream"); + jack_error ("Error number: %d", err); + jack_error ("Error message: %s", Pa_GetErrorText (err)); + free (driver); return NULL; } @@ -676,9 +712,9 @@ static void portaudio_driver_delete (portaudio_driver_t *driver) { /* Close PortAudio stream and terminate */ - Pa_CloseStream(driver->stream); - Pa_Terminate(); - free(driver); + Pa_CloseStream (driver->stream); + Pa_Terminate (); + free (driver); } //== driver "plugin" interface ================================================= @@ -690,12 +726,13 @@ driver_get_descriptor () { jack_driver_desc_t * desc; unsigned int i; - desc = calloc (1, sizeof (jack_driver_desc_t)); + + desc = calloc (1, sizeof(jack_driver_desc_t)); strcpy (desc->name, "portaudio"); desc->nparams = 10; desc->params = calloc (desc->nparams, - sizeof (jack_driver_param_desc_t)); + sizeof(jack_driver_param_desc_t)); i = 0; strcpy (desc->params[i].name, "channel"); @@ -704,7 +741,7 @@ driver_get_descriptor () desc->params[i].value.ui = 0; strcpy (desc->params[i].short_desc, "Maximum number of channels"); strcpy (desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy (desc->params[i].name, "channelin"); desc->params[i].character = 'i'; @@ -760,7 +797,7 @@ driver_get_descriptor () desc->params[i].value.ui = 1024U; strcpy (desc->params[i].short_desc, "Frames per period"); strcpy (desc->params[i].long_desc, desc->params[i].short_desc); - + i++; strcpy (desc->params[i].name, "name"); desc->params[i].character = 'n'; @@ -781,8 +818,8 @@ driver_get_descriptor () " t : triangular\n" " s : shaped\n" " - : no dithering"); - - return desc; + + return desc; } const char driver_client_name[] = "portaudio"; @@ -802,42 +839,42 @@ driver_initialize (jack_client_t *client, const JSList * params) const jack_driver_param_t * param; char *name = NULL; -#ifdef JACK_USE_MACH_THREADS - get_device_id_from_num(0,&deviceID); // takes a default value (first device) +#ifdef JACK_USE_MACH_THREADS + get_device_id_from_num (0, &deviceID); // takes a default value (first device) #endif - + for (node = params; node; node = jack_slist_next (node)) { - param = (const jack_driver_param_t *) node->data; + param = (const jack_driver_param_t*)node->data; switch (param->character) { - + case 'n': - name = (char *) param->value.str; - PALog("Driver name found %s\n",name); + name = (char*)param->value.str; + PALog ("Driver name found %s\n", name); break; - + case 'D': capture = TRUE; playback = TRUE; break; - + case 'c': - chan_in = (int) param->value.ui; - chan_out = (int) param->value.ui; + chan_in = (int)param->value.ui; + chan_out = (int)param->value.ui; break; - + case 'i': - chan_in = (int) param->value.ui; + chan_in = (int)param->value.ui; break; - + case 'o': - chan_out = (int) param->value.ui; + chan_out = (int)param->value.ui; break; - + case 'C': capture = param->value.i; break; - + case 'P': playback = param->value.i; break; @@ -845,25 +882,25 @@ driver_initialize (jack_client_t *client, const JSList * params) case 'r': srate = param->value.ui; break; - + case 'p': - frames_per_interrupt = (unsigned int) param->value.ui; + frames_per_interrupt = (unsigned int)param->value.ui; break; - + case 'z': - switch ((int) param->value.c) { + switch ((int)param->value.c) { case '-': dither = None; break; - + case 'r': dither = Rectangular; break; - + case 's': dither = Shaped; break; - + case 't': default: dither = Triangular; @@ -887,6 +924,6 @@ driver_initialize (jack_client_t *client, const JSList * params) void driver_finish (jack_driver_t *driver) { - portaudio_driver_delete ((portaudio_driver_t *) driver); + portaudio_driver_delete ((portaudio_driver_t*)driver); } |