00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef WIN32
00021 #pragma warning (disable : 4786)
00022 #endif
00023
00024 #ifdef __APPLE__
00025 #include "JackMachThread.h"
00026 #endif
00027
00028 #include "pa_asio.h"
00029 #include "JackDriverLoader.h"
00030 #include "driver_interface.h"
00031
00032 #include "JackPortAudioDriver.h"
00033 #include "JackEngineControl.h"
00034 #include "JackGraphManager.h"
00035 #include "JackError.h"
00036 #include "JackClientControl.h"
00037 #include "JackGlobals.h"
00038 #include <iostream>
00039
00040 namespace Jack
00041 {
00042
00043 void JackPortAudioDriver::PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters)
00044 {
00045 static double standardSampleRates[] = {
00046 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
00047 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1
00048 };
00049 int i, printCount;
00050 PaError err;
00051
00052 printCount = 0;
00053 for (i = 0; standardSampleRates[i] > 0; i++) {
00054 err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]);
00055 if (err == paFormatIsSupported) {
00056 if (printCount == 0) {
00057 printf("\t%8.2f", standardSampleRates[i]);
00058 printCount = 1;
00059 } else if (printCount == 4) {
00060 printf(",\n\t%8.2f", standardSampleRates[i]);
00061 printCount = 1;
00062 } else {
00063 printf(", %8.2f", standardSampleRates[i]);
00064 ++printCount;
00065 }
00066 }
00067 }
00068 if (!printCount)
00069 printf("None\n");
00070 else
00071 printf("\n");
00072 }
00073
00074 bool JackPortAudioDriver::GetInputDeviceFromName(const char* name, PaDeviceIndex* device, int* in_max)
00075 {
00076 const PaDeviceInfo* deviceInfo;
00077 PaDeviceIndex numDevices = Pa_GetDeviceCount();
00078
00079 for (int i = 0; i < numDevices; i++) {
00080 deviceInfo = Pa_GetDeviceInfo(i);
00081 if (strcmp(name, deviceInfo->name) == 0) {
00082 *device = i;
00083 *in_max = deviceInfo->maxInputChannels;
00084 return true;
00085 }
00086 }
00087
00088 return false;
00089 }
00090
00091 bool JackPortAudioDriver::GetOutputDeviceFromName(const char* name, PaDeviceIndex* device, int* out_max)
00092 {
00093 const PaDeviceInfo* deviceInfo;
00094 PaDeviceIndex numDevices = Pa_GetDeviceCount();
00095
00096 for (int i = 0; i < numDevices; i++) {
00097 deviceInfo = Pa_GetDeviceInfo(i);
00098 if (strcmp(name, deviceInfo->name) == 0) {
00099 *device = i;
00100 *out_max = deviceInfo->maxOutputChannels;
00101 return true;
00102 }
00103 }
00104
00105 return false;
00106 }
00107
00108 static void DisplayDeviceNames()
00109 {
00110 PaError err;
00111 const PaDeviceInfo* deviceInfo;
00112 PaStreamParameters inputParameters, outputParameters;
00113 int defaultDisplayed;
00114
00115 err = Pa_Initialize();
00116 if (err != paNoError)
00117 return ;
00118
00119 PaDeviceIndex numDevices = Pa_GetDeviceCount();
00120 printf("Number of devices = %d\n", numDevices);
00121
00122 for (int i = 0; i < numDevices; i++) {
00123 deviceInfo = Pa_GetDeviceInfo(i);
00124 printf( "--------------------------------------- device #%d\n", i );
00125
00126
00127 defaultDisplayed = 0;
00128 if (i == Pa_GetDefaultInputDevice()) {
00129 printf("[ Default Input");
00130 defaultDisplayed = 1;
00131 } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
00132 const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
00133 printf("[ Default %s Input", hostInfo->name);
00134 defaultDisplayed = 1;
00135 }
00136
00137 if (i == Pa_GetDefaultOutputDevice()) {
00138 printf((defaultDisplayed ? "," : "["));
00139 printf(" Default Output");
00140 defaultDisplayed = 1;
00141 } else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
00142 const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
00143 printf((defaultDisplayed ? "," : "["));
00144 printf(" Default %s Output", hostInfo->name);
00145 defaultDisplayed = 1;
00146 }
00147
00148 if (defaultDisplayed)
00149 printf(" ]\n");
00150
00151
00152 printf("Name = %s\n", deviceInfo->name);
00153 printf("Host API = %s\n", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
00154 printf("Max inputs = %d", deviceInfo->maxInputChannels);
00155 printf(", Max outputs = %d\n", deviceInfo->maxOutputChannels);
00156
00157
00158
00159
00160
00161
00162
00163 #ifdef WIN32
00164 #ifndef PA_NO_ASIO
00165
00166 if (Pa_GetHostApiInfo(deviceInfo->hostApi)->type == paASIO) {
00167 long minLatency, maxLatency, preferredLatency, granularity;
00168
00169 err = PaAsio_GetAvailableLatencyValues(i, &minLatency, &maxLatency, &preferredLatency, &granularity);
00170
00171 printf("ASIO minimum buffer size = %ld\n", minLatency);
00172 printf("ASIO maximum buffer size = %ld\n", maxLatency);
00173 printf("ASIO preferred buffer size = %ld\n", preferredLatency);
00174
00175 if (granularity == -1)
00176 printf("ASIO buffer granularity = power of 2\n");
00177 else
00178 printf("ASIO buffer granularity = %ld\n", granularity);
00179 }
00180 #endif
00181 #endif
00182
00183 printf("Default sample rate = %8.2f\n", deviceInfo->defaultSampleRate);
00184
00185
00186 inputParameters.device = i;
00187 inputParameters.channelCount = deviceInfo->maxInputChannels;
00188 inputParameters.sampleFormat = paInt16;
00189 inputParameters.suggestedLatency = 0;
00190 inputParameters.hostApiSpecificStreamInfo = NULL;
00191
00192 outputParameters.device = i;
00193 outputParameters.channelCount = deviceInfo->maxOutputChannels;
00194 outputParameters.sampleFormat = paInt16;
00195 outputParameters.suggestedLatency = 0;
00196 outputParameters.hostApiSpecificStreamInfo = NULL;
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 }
00216
00217 Pa_Terminate();
00218 }
00219
00220 int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer,
00221 unsigned long framesPerBuffer,
00222 const PaStreamCallbackTimeInfo* timeInfo,
00223 PaStreamCallbackFlags statusFlags,
00224 void* userData)
00225 {
00226 JackPortAudioDriver* driver = (JackPortAudioDriver*)userData;
00227 driver->fLastWaitUst = GetMicroSeconds();
00228 driver->fInputBuffer = (float**)inputBuffer;
00229 driver->fOutputBuffer = (float**)outputBuffer;
00230 return (driver->Process() == 0) ? paContinue : paAbort;
00231 }
00232
00233 int JackPortAudioDriver::Read()
00234 {
00235 for (int i = 0; i < fCaptureChannels; i++) {
00236 memcpy(GetInputBuffer(i), fInputBuffer[i], sizeof(float) * fEngineControl->fBufferSize);
00237 }
00238 return 0;
00239 }
00240
00241 int JackPortAudioDriver::Write()
00242 {
00243 for (int i = 0; i < fPlaybackChannels; i++) {
00244 memcpy(fOutputBuffer[i], GetOutputBuffer(i), sizeof(float) * fEngineControl->fBufferSize);
00245 }
00246 return 0;
00247 }
00248
00249 int JackPortAudioDriver::Open(jack_nframes_t nframes,
00250 jack_nframes_t samplerate,
00251 int capturing,
00252 int playing,
00253 int inchannels,
00254 int outchannels,
00255 bool monitor,
00256 const char* capture_driver_uid,
00257 const char* playback_driver_uid,
00258 jack_nframes_t capture_latency,
00259 jack_nframes_t playback_latency)
00260 {
00261 PaError err;
00262 PaStreamParameters inputParameters;
00263 PaStreamParameters outputParameters;
00264 const PaDeviceInfo* deviceInfo;
00265 int in_max = 0;
00266 int out_max = 0;
00267
00268 JackLog("JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld\n",
00269 nframes, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate);
00270
00271
00272 if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) {
00273 return -1;
00274 }
00275
00276 err = Pa_Initialize();
00277 if (err != paNoError) {
00278 jack_error("JackPortAudioDriver::Pa_Initialize error = %s\n", Pa_GetErrorText(err));
00279 goto error;
00280 }
00281
00282 JackLog("JackPortAudioDriver::Pa_GetDefaultInputDevice %ld\n", Pa_GetDefaultInputDevice());
00283 JackLog("JackPortAudioDriver::Pa_GetDefaultOutputDevice %ld\n", Pa_GetDefaultOutputDevice());
00284
00285 if (capturing) {
00286 if (!GetInputDeviceFromName(capture_driver_uid, &fInputDevice, &in_max)) {
00287 JackLog("JackPortAudioDriver::GetInputDeviceFromName cannot open %s\n", capture_driver_uid);
00288 fInputDevice = Pa_GetDefaultInputDevice();
00289 deviceInfo = Pa_GetDeviceInfo(fInputDevice);
00290 in_max = deviceInfo->maxInputChannels;
00291 capture_driver_uid = strdup(deviceInfo->name);
00292 }
00293 }
00294
00295 if (inchannels > in_max) {
00296 jack_error("This device hasn't required input channels inchannels = %ld in_max = %ld", inchannels, in_max);
00297 goto error;
00298 }
00299
00300 if (playing) {
00301 if (!GetOutputDeviceFromName(playback_driver_uid, &fOutputDevice, &out_max)) {
00302 JackLog("JackPortAudioDriver::GetOutputDeviceFromName cannot open %s\n", playback_driver_uid);
00303 fOutputDevice = Pa_GetDefaultOutputDevice();
00304 deviceInfo = Pa_GetDeviceInfo(fOutputDevice);
00305 out_max = deviceInfo->maxOutputChannels;
00306 playback_driver_uid = strdup(deviceInfo->name);
00307 }
00308 }
00309
00310 if (outchannels > out_max) {
00311 jack_error("This device hasn't required output channels outchannels = %ld out_max = %ld", outchannels, out_max);
00312 goto error;
00313 }
00314
00315 if (inchannels == 0) {
00316 JackLog("JackPortAudioDriver::Open setup max in channels = %ld\n", in_max);
00317 inchannels = in_max;
00318 }
00319
00320 if (outchannels == 0) {
00321 JackLog("JackPortAudioDriver::Open setup max out channels = %ld\n", out_max);
00322 outchannels = out_max;
00323 }
00324
00325 inputParameters.device = fInputDevice;
00326 inputParameters.channelCount = inchannels;
00327 inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
00328 inputParameters.suggestedLatency = (fInputDevice != paNoDevice)
00329 ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency
00330 : 0;
00331 inputParameters.hostApiSpecificStreamInfo = NULL;
00332
00333 outputParameters.device = fOutputDevice;
00334 outputParameters.channelCount = outchannels;
00335 outputParameters.sampleFormat = paFloat32 | paNonInterleaved;
00336 outputParameters.suggestedLatency = (fOutputDevice != paNoDevice)
00337 ? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency
00338 : 0;
00339 outputParameters.hostApiSpecificStreamInfo = NULL;
00340
00341 err = Pa_OpenStream(&fStream,
00342 (fInputDevice == paNoDevice) ? 0 : &inputParameters,
00343 (fOutputDevice == paNoDevice) ? 0 : &outputParameters,
00344 samplerate,
00345 nframes,
00346 paNoFlag,
00347 Render,
00348 this);
00349 if (err != paNoError) {
00350 jack_error("Pa_OpenStream error = %s\n", Pa_GetErrorText(err));
00351 goto error;
00352 }
00353
00354 #ifdef __APPLE__
00355 fEngineControl->fPeriod = fEngineControl->fPeriodUsecs * 1000;
00356 fEngineControl->fComputation = 500 * 1000;
00357 fEngineControl->fConstraint = fEngineControl->fPeriodUsecs * 1000;
00358 #endif
00359
00360
00361 fCaptureChannels = inchannels;
00362 fPlaybackChannels = outchannels;
00363
00364 assert(strlen(capture_driver_uid) < JACK_CLIENT_NAME_SIZE);
00365 assert(strlen(playback_driver_uid) < JACK_CLIENT_NAME_SIZE);
00366
00367 strcpy(fCaptureDriverName, capture_driver_uid);
00368 strcpy(fPlaybackDriverName, playback_driver_uid);
00369
00370 return 0;
00371
00372 error:
00373 Pa_Terminate();
00374 return -1;
00375 }
00376
00377 int JackPortAudioDriver::Close()
00378 {
00379 JackAudioDriver::Close();
00380 JackLog("JackPortAudioDriver::Close\n");
00381 Pa_CloseStream(fStream);
00382 Pa_Terminate();
00383 return 0;
00384 }
00385
00386 int JackPortAudioDriver::Start()
00387 {
00388 JackLog("JackPortAudioDriver::Start\n");
00389 JackAudioDriver::Start();
00390 PaError err = Pa_StartStream(fStream);
00391 return (err == paNoError) ? 0 : -1;
00392 }
00393
00394 int JackPortAudioDriver::Stop()
00395 {
00396 JackLog("JackPortAudioDriver::Stop\n");
00397 PaError err = Pa_StopStream(fStream);
00398 return (err == paNoError) ? 0 : -1;
00399 }
00400
00401 int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size)
00402 {
00403 PaError err;
00404 PaStreamParameters inputParameters;
00405 PaStreamParameters outputParameters;
00406
00407 if ((err = Pa_CloseStream(fStream)) != paNoError) {
00408 jack_error("Pa_CloseStream error = %s\n", Pa_GetErrorText(err));
00409 return -1;
00410 }
00411
00412 inputParameters.device = fInputDevice;
00413 inputParameters.channelCount = fCaptureChannels;
00414 inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
00415 inputParameters.suggestedLatency = (fInputDevice != paNoDevice)
00416 ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency
00417 : 0;
00418 inputParameters.hostApiSpecificStreamInfo = NULL;
00419
00420 outputParameters.device = fOutputDevice;
00421 outputParameters.channelCount = fPlaybackChannels;
00422 outputParameters.sampleFormat = paFloat32 | paNonInterleaved;
00423 outputParameters.suggestedLatency = (fOutputDevice != paNoDevice)
00424 ? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency
00425 : 0;
00426 outputParameters.hostApiSpecificStreamInfo = NULL;
00427
00428 err = Pa_OpenStream(&fStream,
00429 (fInputDevice == paNoDevice) ? 0 : &inputParameters,
00430 (fOutputDevice == paNoDevice) ? 0 : &outputParameters,
00431 fEngineControl->fSampleRate,
00432 buffer_size,
00433 paNoFlag,
00434 Render,
00435 this);
00436 if (err != paNoError) {
00437 jack_error("Pa_OpenStream error = %s\n", Pa_GetErrorText(err));
00438 return -1;
00439 } else {
00440
00441 fEngineControl->fBufferSize = buffer_size;
00442 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize);
00443 return 0;
00444 }
00445 }
00446
00447 void JackPortAudioDriver::PrintState()
00448 {
00449 int i;
00450 std::cout << "JackPortAudioDriver state" << std::endl;
00451
00452 jack_port_id_t port_index;
00453
00454 std::cout << "Input ports" << std::endl;
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 }
00474
00475 }
00476
00477 #ifdef __cplusplus
00478 extern "C"
00479 {
00480 #endif
00481
00482 #include "JackExports.h"
00483
00484 EXPORT jack_driver_desc_t* driver_get_descriptor() {
00485 jack_driver_desc_t *desc;
00486 unsigned int i;
00487 desc = (jack_driver_desc_t*)calloc(1, sizeof(jack_driver_desc_t));
00488
00489 strcpy(desc->name, "portaudio");
00490
00491 desc->nparams = 13;
00492 desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
00493
00494 i = 0;
00495 strcpy(desc->params[i].name, "channels");
00496 desc->params[i].character = 'c';
00497 desc->params[i].type = JackDriverParamInt;
00498 desc->params[i].value.ui = 0;
00499 strcpy(desc->params[i].short_desc, "Maximum number of channels");
00500 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00501
00502 i++;
00503 strcpy(desc->params[i].name, "inchannels");
00504 desc->params[i].character = 'i';
00505 desc->params[i].type = JackDriverParamInt;
00506 desc->params[i].value.ui = 0;
00507 strcpy(desc->params[i].short_desc, "Maximum number of input channels");
00508 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00509
00510 i++;
00511 strcpy(desc->params[i].name, "outchannels");
00512 desc->params[i].character = 'o';
00513 desc->params[i].type = JackDriverParamInt;
00514 desc->params[i].value.ui = 0;
00515 strcpy(desc->params[i].short_desc, "Maximum number of output channels");
00516 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00517
00518 i++;
00519 strcpy(desc->params[i].name, "capture");
00520 desc->params[i].character = 'C';
00521 desc->params[i].type = JackDriverParamString;
00522 strcpy(desc->params[i].value.str, "will take default PortAudio input device");
00523 strcpy(desc->params[i].short_desc, "Provide capture ports. Optionally set PortAudio device name");
00524 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00525
00526 i++;
00527 strcpy(desc->params[i].name, "playback");
00528 desc->params[i].character = 'P';
00529 desc->params[i].type = JackDriverParamString;
00530 strcpy(desc->params[i].value.str, "will take default PortAudio output device");
00531 strcpy(desc->params[i].short_desc, "Provide playback ports. Optionally set PortAudio device name");
00532 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00533
00534 i++;
00535 strcpy (desc->params[i].name, "monitor");
00536 desc->params[i].character = 'm';
00537 desc->params[i].type = JackDriverParamBool;
00538 desc->params[i].value.i = 0;
00539 strcpy(desc->params[i].short_desc, "Provide monitor ports for the output");
00540 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00541
00542 i++;
00543 strcpy(desc->params[i].name, "duplex");
00544 desc->params[i].character = 'D';
00545 desc->params[i].type = JackDriverParamBool;
00546 desc->params[i].value.i = TRUE;
00547 strcpy(desc->params[i].short_desc, "Provide both capture and playback ports");
00548 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00549
00550 i++;
00551 strcpy(desc->params[i].name, "rate");
00552 desc->params[i].character = 'r';
00553 desc->params[i].type = JackDriverParamUInt;
00554 desc->params[i].value.ui = 44100U;
00555 strcpy(desc->params[i].short_desc, "Sample rate");
00556 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00557
00558 i++;
00559 strcpy(desc->params[i].name, "period");
00560 desc->params[i].character = 'p';
00561 desc->params[i].type = JackDriverParamUInt;
00562 desc->params[i].value.ui = 128U;
00563 strcpy(desc->params[i].short_desc, "Frames per period");
00564 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00565
00566 i++;
00567 strcpy(desc->params[i].name, "device");
00568 desc->params[i].character = 'd';
00569 desc->params[i].type = JackDriverParamString;
00570 desc->params[i].value.ui = 128U;
00571 strcpy(desc->params[i].value.str, "will take default PortAudio device name");
00572 strcpy(desc->params[i].short_desc, "PortAudio device name");
00573 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00574
00575 i++;
00576 strcpy(desc->params[i].name, "input-latency");
00577 desc->params[i].character = 'I';
00578 desc->params[i].type = JackDriverParamUInt;
00579 desc->params[i].value.i = 0;
00580 strcpy(desc->params[i].short_desc, "Extra input latency");
00581 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00582
00583 i++;
00584 strcpy(desc->params[i].name, "output-latency");
00585 desc->params[i].character = 'O';
00586 desc->params[i].type = JackDriverParamUInt;
00587 desc->params[i].value.i = 0;
00588 strcpy(desc->params[i].short_desc, "Extra output latency");
00589 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00590
00591 i++;
00592 strcpy(desc->params[i].name, "list-devices");
00593 desc->params[i].character = 'l';
00594 desc->params[i].type = JackDriverParamBool;
00595 desc->params[i].value.i = TRUE;
00596 strcpy(desc->params[i].short_desc, "Display available PortAudio devices");
00597 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00598
00599 return desc;
00600 }
00601
00602 EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackEngine* engine, Jack::JackSynchro** table, const JSList* params) {
00603 jack_nframes_t srate = 44100;
00604 jack_nframes_t frames_per_interrupt = 512;
00605 int capture = FALSE;
00606 int playback = FALSE;
00607 int chan_in = 0;
00608 int chan_out = 0;
00609 bool monitor = false;
00610 char* capture_pcm_name = "winmme";
00611 char* playback_pcm_name = "winmme";
00612 const JSList *node;
00613 const jack_driver_param_t *param;
00614 jack_nframes_t systemic_input_latency = 0;
00615 jack_nframes_t systemic_output_latency = 0;
00616
00617 for (node = params; node; node = jack_slist_next(node)) {
00618 param = (const jack_driver_param_t *) node->data;
00619
00620 switch (param->character) {
00621
00622 case 'd':
00623 capture_pcm_name = strdup(param->value.str);
00624 playback_pcm_name = strdup(param->value.str);
00625 break;
00626
00627 case 'D':
00628 capture = TRUE;
00629 playback = TRUE;
00630 break;
00631
00632 case 'c':
00633 chan_in = chan_out = (int) param->value.ui;
00634 break;
00635
00636 case 'i':
00637 chan_in = (int) param->value.ui;
00638 break;
00639
00640 case 'o':
00641 chan_out = (int) param->value.ui;
00642 break;
00643
00644 case 'C':
00645 capture = TRUE;
00646 if (strcmp(param->value.str, "none") != 0) {
00647 capture_pcm_name = strdup(param->value.str);
00648 }
00649 break;
00650
00651 case 'P':
00652 playback = TRUE;
00653 if (strcmp(param->value.str, "none") != 0) {
00654 playback_pcm_name = strdup(param->value.str);
00655 }
00656 break;
00657
00658 case 'm':
00659 monitor = param->value.i;
00660 break;
00661
00662 case 'r':
00663 srate = param->value.ui;
00664 break;
00665
00666 case 'p':
00667 frames_per_interrupt = (unsigned int) param->value.ui;
00668 break;
00669
00670 case 'I':
00671 systemic_input_latency = param->value.ui;
00672 break;
00673
00674 case 'O':
00675 systemic_output_latency = param->value.ui;
00676 break;
00677
00678 case 'l':
00679 Jack::DisplayDeviceNames();
00680 break;
00681 }
00682 }
00683
00684
00685 if (!capture && !playback) {
00686 capture = TRUE;
00687 playback = TRUE;
00688 }
00689
00690 Jack::JackDriverClientInterface* driver = new Jack::JackPortAudioDriver("portaudio", engine, table);
00691 if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency) == 0) {
00692 return driver;
00693 } else {
00694 delete driver;
00695 return NULL;
00696 }
00697 }
00698
00699 #ifdef __cplusplus
00700 }
00701 #endif