pa_jack.c (63346B)
1 /* 2 * $Id$ 3 * PortAudio Portable Real-Time Audio Library 4 * Latest Version at: http://www.portaudio.com 5 * JACK Implementation by Joshua Haberman 6 * 7 * Copyright (c) 2004 Stefan Westerfeld <stefan@space.twc.de> 8 * Copyright (c) 2004 Arve Knudsen <aknuds-1@broadpark.no> 9 * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com> 10 * 11 * Based on the Open Source API proposed by Ross Bencina 12 * Copyright (c) 1999-2002 Ross Bencina, Phil Burk 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining 15 * a copy of this software and associated documentation files 16 * (the "Software"), to deal in the Software without restriction, 17 * including without limitation the rights to use, copy, modify, merge, 18 * publish, distribute, sublicense, and/or sell copies of the Software, 19 * and to permit persons to whom the Software is furnished to do so, 20 * subject to the following conditions: 21 * 22 * The above copyright notice and this permission notice shall be 23 * included in all copies or substantial portions of the Software. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 28 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 29 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 30 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 31 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 */ 33 34 /* 35 * The text above constitutes the entire PortAudio license; however, 36 * the PortAudio community also makes the following non-binding requests: 37 * 38 * Any person wishing to distribute modifications to the Software is 39 * requested to send the modifications to the original developer so that 40 * they can be incorporated into the canonical version. It is also 41 * requested that these non-binding requests be included along with the 42 * license above. 43 */ 44 45 /** 46 @file 47 @ingroup hostapi_src 48 */ 49 50 #include <string.h> 51 #include <regex.h> 52 #include <stdlib.h> 53 #include <stdio.h> 54 #include <assert.h> 55 #include <sys/types.h> 56 #include <unistd.h> 57 #include <errno.h> /* EBUSY */ 58 #include <signal.h> /* sig_atomic_t */ 59 #include <math.h> 60 #include <semaphore.h> 61 62 #include <jack/types.h> 63 #include <jack/jack.h> 64 65 #include "pa_util.h" 66 #include "pa_hostapi.h" 67 #include "pa_stream.h" 68 #include "pa_process.h" 69 #include "pa_allocation.h" 70 #include "pa_cpuload.h" 71 #include "pa_ringbuffer.h" 72 #include "pa_debugprint.h" 73 74 static pthread_t mainThread_; 75 static char *jackErr_ = NULL; 76 static const char* clientName_ = "PortAudio"; 77 78 #define STRINGIZE_HELPER(expr) #expr 79 #define STRINGIZE(expr) STRINGIZE_HELPER(expr) 80 81 /* Check PaError */ 82 #define ENSURE_PA(expr) \ 83 do { \ 84 PaError paErr; \ 85 if( (paErr = (expr)) < paNoError ) \ 86 { \ 87 if( (paErr) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ 88 { \ 89 const char *err = jackErr_; \ 90 if (! err ) err = "unknown error"; \ 91 PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \ 92 } \ 93 PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ 94 result = paErr; \ 95 goto error; \ 96 } \ 97 } while( 0 ) 98 99 #define UNLESS(expr, code) \ 100 do { \ 101 if( (expr) == 0 ) \ 102 { \ 103 if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ 104 { \ 105 const char *err = jackErr_; \ 106 if (!err) err = "unknown error"; \ 107 PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \ 108 } \ 109 PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ 110 result = (code); \ 111 goto error; \ 112 } \ 113 } while( 0 ) 114 115 #define ASSERT_CALL(expr, success) \ 116 do { \ 117 int err = (expr); \ 118 assert( err == success ); \ 119 } while( 0 ) 120 121 /* 122 * Functions that directly map to the PortAudio stream interface 123 */ 124 125 static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); 126 static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, 127 const PaStreamParameters *inputParameters, 128 const PaStreamParameters *outputParameters, 129 double sampleRate ); 130 static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, 131 PaStream** s, 132 const PaStreamParameters *inputParameters, 133 const PaStreamParameters *outputParameters, 134 double sampleRate, 135 unsigned long framesPerBuffer, 136 PaStreamFlags streamFlags, 137 PaStreamCallback *streamCallback, 138 void *userData ); 139 static PaError CloseStream( PaStream* stream ); 140 static PaError StartStream( PaStream *stream ); 141 static PaError StopStream( PaStream *stream ); 142 static PaError AbortStream( PaStream *stream ); 143 static PaError IsStreamStopped( PaStream *s ); 144 static PaError IsStreamActive( PaStream *stream ); 145 /*static PaTime GetStreamInputLatency( PaStream *stream );*/ 146 /*static PaTime GetStreamOutputLatency( PaStream *stream );*/ 147 static PaTime GetStreamTime( PaStream *stream ); 148 static double GetStreamCpuLoad( PaStream* stream ); 149 150 151 /* 152 * Data specific to this API 153 */ 154 155 struct PaJackStream; 156 157 typedef struct 158 { 159 PaUtilHostApiRepresentation commonHostApiRep; 160 PaUtilStreamInterface callbackStreamInterface; 161 PaUtilStreamInterface blockingStreamInterface; 162 163 PaUtilAllocationGroup *deviceInfoMemory; 164 165 jack_client_t *jack_client; 166 int jack_buffer_size; 167 PaHostApiIndex hostApiIndex; 168 169 pthread_mutex_t mtx; 170 pthread_cond_t cond; 171 unsigned long inputBase, outputBase; 172 173 /* For dealing with the process thread */ 174 volatile int xrun; /* Received xrun notification from JACK? */ 175 struct PaJackStream * volatile toAdd, * volatile toRemove; 176 struct PaJackStream *processQueue; 177 volatile sig_atomic_t jackIsDown; 178 } 179 PaJackHostApiRepresentation; 180 181 /* PaJackStream - a stream data structure specifically for this implementation */ 182 183 typedef struct PaJackStream 184 { 185 PaUtilStreamRepresentation streamRepresentation; 186 PaUtilBufferProcessor bufferProcessor; 187 PaUtilCpuLoadMeasurer cpuLoadMeasurer; 188 PaJackHostApiRepresentation *hostApi; 189 190 /* our input and output ports */ 191 jack_port_t **local_input_ports; 192 jack_port_t **local_output_ports; 193 194 /* the input and output ports of the client we are connecting to */ 195 jack_port_t **remote_input_ports; 196 jack_port_t **remote_output_ports; 197 198 int num_incoming_connections; 199 int num_outgoing_connections; 200 201 jack_client_t *jack_client; 202 203 /* The stream is running if it's still producing samples. 204 * The stream is active if samples it produced are still being heard. 205 */ 206 volatile sig_atomic_t is_running; 207 volatile sig_atomic_t is_active; 208 /* Used to signal processing thread that stream should start or stop, respectively */ 209 volatile sig_atomic_t doStart, doStop, doAbort; 210 211 jack_nframes_t t0; 212 213 PaUtilAllocationGroup *stream_memory; 214 215 /* These are useful in the process callback */ 216 217 int callbackResult; 218 int isSilenced; 219 int xrun; 220 221 /* These are useful for the blocking API */ 222 223 int isBlockingStream; 224 PaUtilRingBuffer inFIFO; 225 PaUtilRingBuffer outFIFO; 226 volatile sig_atomic_t data_available; 227 sem_t data_semaphore; 228 int bytesPerFrame; 229 int samplesPerFrame; 230 231 struct PaJackStream *next; 232 } 233 PaJackStream; 234 235 /* In calls to jack_get_ports() this filter expression is used instead of "" 236 * to prevent any other types (eg Midi ports etc) being listed */ 237 #define JACK_PORT_TYPE_FILTER "audio" 238 239 #define TRUE 1 240 #define FALSE 0 241 242 /* 243 * Functions specific to this API 244 */ 245 246 static int JackCallback( jack_nframes_t frames, void *userData ); 247 248 249 /* 250 * 251 * Implementation 252 * 253 */ 254 255 /* ---- blocking emulation layer ---- */ 256 257 /* Allocate buffer. */ 258 static PaError BlockingInitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame ) 259 { 260 long numBytes = numFrames * bytesPerFrame; 261 char *buffer = (char *) malloc( numBytes ); 262 if( buffer == NULL ) return paInsufficientMemory; 263 memset( buffer, 0, numBytes ); 264 return (PaError) PaUtil_InitializeRingBuffer( rbuf, 1, numBytes, buffer ); 265 } 266 267 /* Free buffer. */ 268 static PaError BlockingTermFIFO( PaUtilRingBuffer *rbuf ) 269 { 270 if( rbuf->buffer ) free( rbuf->buffer ); 271 rbuf->buffer = NULL; 272 return paNoError; 273 } 274 275 static int 276 BlockingCallback( const void *inputBuffer, 277 void *outputBuffer, 278 unsigned long framesPerBuffer, 279 const PaStreamCallbackTimeInfo* timeInfo, 280 PaStreamCallbackFlags statusFlags, 281 void *userData ) 282 { 283 struct PaJackStream *stream = (PaJackStream *)userData; 284 long numBytes = stream->bytesPerFrame * framesPerBuffer; 285 286 /* This may get called with NULL inputBuffer during initial setup. */ 287 if( inputBuffer != NULL ) 288 { 289 PaUtil_WriteRingBuffer( &stream->inFIFO, inputBuffer, numBytes ); 290 } 291 if( outputBuffer != NULL ) 292 { 293 int numRead = PaUtil_ReadRingBuffer( &stream->outFIFO, outputBuffer, numBytes ); 294 /* Zero out remainder of buffer if we run out of data. */ 295 memset( (char *)outputBuffer + numRead, 0, numBytes - numRead ); 296 } 297 298 if( !stream->data_available ) 299 { 300 stream->data_available = 1; 301 sem_post( &stream->data_semaphore ); 302 } 303 return paContinue; 304 } 305 306 static PaError 307 BlockingBegin( PaJackStream *stream, int minimum_buffer_size ) 308 { 309 long doRead = 0; 310 long doWrite = 0; 311 PaError result = paNoError; 312 long numFrames; 313 314 doRead = stream->local_input_ports != NULL; 315 doWrite = stream->local_output_ports != NULL; 316 /* <FIXME> */ 317 stream->samplesPerFrame = 2; 318 stream->bytesPerFrame = sizeof(float) * stream->samplesPerFrame; 319 /* </FIXME> */ 320 numFrames = 32; 321 while (numFrames < minimum_buffer_size) 322 numFrames *= 2; 323 324 if( doRead ) 325 { 326 ENSURE_PA( BlockingInitFIFO( &stream->inFIFO, numFrames, stream->bytesPerFrame ) ); 327 } 328 if( doWrite ) 329 { 330 long numBytes; 331 332 ENSURE_PA( BlockingInitFIFO( &stream->outFIFO, numFrames, stream->bytesPerFrame ) ); 333 334 /* Make Write FIFO appear full initially. */ 335 numBytes = PaUtil_GetRingBufferWriteAvailable( &stream->outFIFO ); 336 PaUtil_AdvanceRingBufferWriteIndex( &stream->outFIFO, numBytes ); 337 } 338 339 stream->data_available = 0; 340 sem_init( &stream->data_semaphore, 0, 0 ); 341 342 error: 343 return result; 344 } 345 346 static void 347 BlockingEnd( PaJackStream *stream ) 348 { 349 BlockingTermFIFO( &stream->inFIFO ); 350 BlockingTermFIFO( &stream->outFIFO ); 351 352 sem_destroy( &stream->data_semaphore ); 353 } 354 355 static PaError BlockingReadStream( PaStream* s, void *data, unsigned long numFrames ) 356 { 357 PaError result = paNoError; 358 PaJackStream *stream = (PaJackStream *)s; 359 360 long bytesRead; 361 char *p = (char *) data; 362 long numBytes = stream->bytesPerFrame * numFrames; 363 while( numBytes > 0 ) 364 { 365 bytesRead = PaUtil_ReadRingBuffer( &stream->inFIFO, p, numBytes ); 366 numBytes -= bytesRead; 367 p += bytesRead; 368 if( numBytes > 0 ) 369 { 370 /* see write for an explanation */ 371 if( stream->data_available ) 372 stream->data_available = 0; 373 else 374 sem_wait( &stream->data_semaphore ); 375 } 376 } 377 378 return result; 379 } 380 381 static PaError BlockingWriteStream( PaStream* s, const void *data, unsigned long numFrames ) 382 { 383 PaError result = paNoError; 384 PaJackStream *stream = (PaJackStream *)s; 385 long bytesWritten; 386 char *p = (char *) data; 387 long numBytes = stream->bytesPerFrame * numFrames; 388 while( numBytes > 0 ) 389 { 390 bytesWritten = PaUtil_WriteRingBuffer( &stream->outFIFO, p, numBytes ); 391 numBytes -= bytesWritten; 392 p += bytesWritten; 393 if( numBytes > 0 ) 394 { 395 /* we use the following algorithm: 396 * (1) write data 397 * (2) if some data didn't fit into the ringbuffer, set data_available to 0 398 * to indicate to the audio that if space becomes available, we want to know 399 * (3) retry to write data (because it might be that between (1) and (2) 400 * new space in the buffer became available) 401 * (4) if this failed, we are sure that the buffer is really empty and 402 * we will definitely receive a notification when it becomes available 403 * thus we can safely sleep 404 * 405 * if the algorithm bailed out in step (3) before, it leaks a count of 1 406 * on the semaphore; however, it doesn't matter, because if we block in (4), 407 * we also do it in a loop 408 */ 409 if( stream->data_available ) 410 stream->data_available = 0; 411 else 412 sem_wait( &stream->data_semaphore ); 413 } 414 } 415 416 return result; 417 } 418 419 static signed long 420 BlockingGetStreamReadAvailable( PaStream* s ) 421 { 422 PaJackStream *stream = (PaJackStream *)s; 423 424 int bytesFull = PaUtil_GetRingBufferReadAvailable( &stream->inFIFO ); 425 return bytesFull / stream->bytesPerFrame; 426 } 427 428 static signed long 429 BlockingGetStreamWriteAvailable( PaStream* s ) 430 { 431 PaJackStream *stream = (PaJackStream *)s; 432 433 int bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &stream->outFIFO ); 434 return bytesEmpty / stream->bytesPerFrame; 435 } 436 437 static PaError 438 BlockingWaitEmpty( PaStream *s ) 439 { 440 PaJackStream *stream = (PaJackStream *)s; 441 442 while( PaUtil_GetRingBufferReadAvailable( &stream->outFIFO ) > 0 ) 443 { 444 stream->data_available = 0; 445 sem_wait( &stream->data_semaphore ); 446 } 447 return 0; 448 } 449 450 /* ---- jack driver ---- */ 451 452 /* BuildDeviceList(): 453 * 454 * The process of determining a list of PortAudio "devices" from 455 * JACK's client/port system is fairly involved, so it is separated 456 * into its own routine. 457 */ 458 459 static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi ) 460 { 461 /* Utility macros for the repetitive process of allocating memory */ 462 463 /* JACK has no concept of a device. To JACK, there are clients 464 * which have an arbitrary number of ports. To make this 465 * intelligible to PortAudio clients, we will group each JACK client 466 * into a device, and make each port of that client a channel */ 467 468 PaError result = paNoError; 469 PaUtilHostApiRepresentation *commonApi = &jackApi->commonHostApiRep; 470 471 const char **jack_ports = NULL; 472 char **client_names = NULL; 473 char *regex_pattern = NULL; 474 int port_index, client_index, i; 475 double globalSampleRate; 476 regex_t port_regex; 477 unsigned long numClients = 0, numPorts = 0; 478 char *tmp_client_name = NULL; 479 480 commonApi->info.defaultInputDevice = paNoDevice; 481 commonApi->info.defaultOutputDevice = paNoDevice; 482 commonApi->info.deviceCount = 0; 483 484 /* Parse the list of ports, using a regex to grab the client names */ 485 ASSERT_CALL( regcomp( &port_regex, "^[^:]*", REG_EXTENDED ), 0 ); 486 487 /* since we are rebuilding the list of devices, free all memory 488 * associated with the previous list */ 489 PaUtil_FreeAllAllocations( jackApi->deviceInfoMemory ); 490 491 regex_pattern = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, jack_client_name_size() + 3 ); 492 tmp_client_name = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, jack_client_name_size() ); 493 494 /* We can only retrieve the list of clients indirectly, by first 495 * asking for a list of all ports, then parsing the port names 496 * according to the client_name:port_name convention (which is 497 * enforced by jackd) 498 * A: If jack_get_ports returns NULL, there's nothing for us to do */ 499 UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", JACK_PORT_TYPE_FILTER, 0 )) && jack_ports[0], paNoError ); 500 /* Find number of ports */ 501 while( jack_ports[numPorts] ) 502 ++numPorts; 503 /* At least there will be one port per client :) */ 504 UNLESS( client_names = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, numPorts * 505 sizeof (char *) ), paInsufficientMemory ); 506 507 /* Build a list of clients from the list of ports */ 508 for( numClients = 0, port_index = 0; jack_ports[port_index] != NULL; port_index++ ) 509 { 510 int client_seen = FALSE; 511 regmatch_t match_info; 512 const char *port = jack_ports[port_index]; 513 514 /* extract the client name from the port name, using a regex 515 * that parses the clientname:portname syntax */ 516 UNLESS( !regexec( &port_regex, port, 1, &match_info, 0 ), paInternalError ); 517 assert(match_info.rm_eo - match_info.rm_so < jack_client_name_size()); 518 memcpy( tmp_client_name, port + match_info.rm_so, 519 match_info.rm_eo - match_info.rm_so ); 520 tmp_client_name[match_info.rm_eo - match_info.rm_so] = '\0'; 521 522 /* do we know about this port's client yet? */ 523 for( i = 0; i < numClients; i++ ) 524 { 525 if( strcmp( tmp_client_name, client_names[i] ) == 0 ) 526 client_seen = TRUE; 527 } 528 529 if (client_seen) 530 continue; /* A: Nothing to see here, move along */ 531 532 UNLESS( client_names[numClients] = (char*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, 533 strlen(tmp_client_name) + 1), paInsufficientMemory ); 534 535 /* The alsa_pcm client should go in spot 0. If this 536 * is the alsa_pcm client AND we are NOT about to put 537 * it in spot 0 put it in spot 0 and move whatever 538 * was already in spot 0 to the end. */ 539 if( strcmp( "alsa_pcm", tmp_client_name ) == 0 && numClients > 0 ) 540 { 541 /* alsa_pcm goes in spot 0 */ 542 strcpy( client_names[ numClients ], client_names[0] ); 543 strcpy( client_names[0], tmp_client_name ); 544 } 545 else 546 { 547 /* put the new client at the end of the client list */ 548 strcpy( client_names[ numClients ], tmp_client_name ); 549 } 550 ++numClients; 551 } 552 553 /* Now we have a list of clients, which will become the list of 554 * PortAudio devices. */ 555 556 /* there is one global sample rate all clients must conform to */ 557 558 globalSampleRate = jack_get_sample_rate( jackApi->jack_client ); 559 UNLESS( commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, 560 sizeof(PaDeviceInfo*) * numClients ), paInsufficientMemory ); 561 562 assert( commonApi->info.deviceCount == 0 ); 563 564 /* Create a PaDeviceInfo structure for every client */ 565 for( client_index = 0; client_index < numClients; client_index++ ) 566 { 567 PaDeviceInfo *curDevInfo; 568 const char **clientPorts = NULL; 569 570 UNLESS( curDevInfo = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, 571 sizeof(PaDeviceInfo) ), paInsufficientMemory ); 572 UNLESS( curDevInfo->name = (char*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, 573 strlen(client_names[client_index]) + 1 ), paInsufficientMemory ); 574 strcpy( (char *)curDevInfo->name, client_names[client_index] ); 575 576 curDevInfo->structVersion = 2; 577 curDevInfo->hostApi = jackApi->hostApiIndex; 578 579 /* JACK is very inflexible: there is one sample rate the whole 580 * system must run at, and all clients must speak IEEE float. */ 581 curDevInfo->defaultSampleRate = globalSampleRate; 582 583 /* To determine how many input and output channels are available, 584 * we re-query jackd with more specific parameters. */ 585 586 sprintf( regex_pattern, "%s:.*", client_names[client_index] ); 587 588 /* ... what are your output ports (that we could input from)? */ 589 clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, 590 JACK_PORT_TYPE_FILTER, JackPortIsOutput); 591 curDevInfo->maxInputChannels = 0; 592 curDevInfo->defaultLowInputLatency = 0.; 593 curDevInfo->defaultHighInputLatency = 0.; 594 if( clientPorts ) 595 { 596 jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] ); 597 curDevInfo->defaultLowInputLatency = curDevInfo->defaultHighInputLatency = 598 jack_port_get_latency( p ) / globalSampleRate; 599 600 for( i = 0; clientPorts[i] != NULL; i++) 601 { 602 /* The number of ports returned is the number of output channels. 603 * We don't care what they are, we just care how many */ 604 curDevInfo->maxInputChannels++; 605 } 606 free(clientPorts); 607 } 608 609 /* ... what are your input ports (that we could output to)? */ 610 clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, 611 JACK_PORT_TYPE_FILTER, JackPortIsInput); 612 curDevInfo->maxOutputChannels = 0; 613 curDevInfo->defaultLowOutputLatency = 0.; 614 curDevInfo->defaultHighOutputLatency = 0.; 615 if( clientPorts ) 616 { 617 jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] ); 618 curDevInfo->defaultLowOutputLatency = curDevInfo->defaultHighOutputLatency = 619 jack_port_get_latency( p ) / globalSampleRate; 620 621 for( i = 0; clientPorts[i] != NULL; i++) 622 { 623 /* The number of ports returned is the number of input channels. 624 * We don't care what they are, we just care how many */ 625 curDevInfo->maxOutputChannels++; 626 } 627 free(clientPorts); 628 } 629 630 /* Add this client to the list of devices */ 631 commonApi->deviceInfos[client_index] = curDevInfo; 632 ++commonApi->info.deviceCount; 633 if( commonApi->info.defaultInputDevice == paNoDevice && curDevInfo->maxInputChannels > 0 ) 634 commonApi->info.defaultInputDevice = client_index; 635 if( commonApi->info.defaultOutputDevice == paNoDevice && curDevInfo->maxOutputChannels > 0 ) 636 commonApi->info.defaultOutputDevice = client_index; 637 } 638 639 error: 640 regfree( &port_regex ); 641 free( jack_ports ); 642 return result; 643 } 644 645 static void UpdateSampleRate( PaJackStream *stream, double sampleRate ) 646 { 647 /* XXX: Maybe not the cleanest way of going about this? */ 648 stream->cpuLoadMeasurer.samplingPeriod = stream->bufferProcessor.samplePeriod = 1. / sampleRate; 649 stream->streamRepresentation.streamInfo.sampleRate = sampleRate; 650 } 651 652 static void JackErrorCallback( const char *msg ) 653 { 654 if( pthread_self() == mainThread_ ) 655 { 656 assert( msg ); 657 jackErr_ = realloc( jackErr_, strlen( msg ) + 1 ); 658 strcpy( jackErr_, msg ); 659 } 660 } 661 662 static void JackOnShutdown( void *arg ) 663 { 664 PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg; 665 PaJackStream *stream = jackApi->processQueue; 666 667 PA_DEBUG(( "%s: JACK server is shutting down\n", __FUNCTION__ )); 668 for( ; stream; stream = stream->next ) 669 { 670 stream->is_active = 0; 671 } 672 673 /* Make sure that the main thread doesn't get stuck waiting on the condition */ 674 ASSERT_CALL( pthread_mutex_lock( &jackApi->mtx ), 0 ); 675 jackApi->jackIsDown = 1; 676 ASSERT_CALL( pthread_cond_signal( &jackApi->cond ), 0 ); 677 ASSERT_CALL( pthread_mutex_unlock( &jackApi->mtx ), 0 ); 678 679 } 680 681 static int JackSrCb( jack_nframes_t nframes, void *arg ) 682 { 683 PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg; 684 double sampleRate = (double)nframes; 685 PaJackStream *stream = jackApi->processQueue; 686 687 /* Update all streams in process queue */ 688 PA_DEBUG(( "%s: Acting on change in JACK samplerate: %f\n", __FUNCTION__, sampleRate )); 689 for( ; stream; stream = stream->next ) 690 { 691 if( stream->streamRepresentation.streamInfo.sampleRate != sampleRate ) 692 { 693 PA_DEBUG(( "%s: Updating samplerate\n", __FUNCTION__ )); 694 UpdateSampleRate( stream, sampleRate ); 695 } 696 } 697 698 return 0; 699 } 700 701 static int JackXRunCb(void *arg) { 702 PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)arg; 703 assert( hostApi ); 704 hostApi->xrun = TRUE; 705 PA_DEBUG(( "%s: JACK signalled xrun\n", __FUNCTION__ )); 706 return 0; 707 } 708 709 PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, 710 PaHostApiIndex hostApiIndex ) 711 { 712 PaError result = paNoError; 713 PaJackHostApiRepresentation *jackHostApi; 714 int activated = 0; 715 jack_status_t jackStatus = 0; 716 *hostApi = NULL; /* Initialize to NULL */ 717 718 UNLESS( jackHostApi = (PaJackHostApiRepresentation*) 719 PaUtil_AllocateMemory( sizeof(PaJackHostApiRepresentation) ), paInsufficientMemory ); 720 UNLESS( jackHostApi->deviceInfoMemory = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); 721 722 mainThread_ = pthread_self(); 723 ASSERT_CALL( pthread_mutex_init( &jackHostApi->mtx, NULL ), 0 ); 724 ASSERT_CALL( pthread_cond_init( &jackHostApi->cond, NULL ), 0 ); 725 726 /* Try to become a client of the JACK server. If we cannot do 727 * this, then this API cannot be used. 728 * 729 * Without the JackNoStartServer option, the jackd server is started 730 * automatically which we do not want. 731 */ 732 733 jackHostApi->jack_client = jack_client_open( clientName_, JackNoStartServer, &jackStatus ); 734 if( !jackHostApi->jack_client ) 735 { 736 /* the V19 development docs say that if an implementation 737 * detects that it cannot be used, it should return a NULL 738 * interface and paNoError */ 739 PA_DEBUG(( "%s: Couldn't connect to JACK, status: %d\n", __FUNCTION__, jackStatus )); 740 result = paNoError; 741 goto error; 742 } 743 744 jackHostApi->hostApiIndex = hostApiIndex; 745 746 *hostApi = &jackHostApi->commonHostApiRep; 747 (*hostApi)->info.structVersion = 1; 748 (*hostApi)->info.type = paJACK; 749 (*hostApi)->info.name = "JACK Audio Connection Kit"; 750 751 /* Build a device list by querying the JACK server */ 752 ENSURE_PA( BuildDeviceList( jackHostApi ) ); 753 754 /* Register functions */ 755 756 (*hostApi)->Terminate = Terminate; 757 (*hostApi)->OpenStream = OpenStream; 758 (*hostApi)->IsFormatSupported = IsFormatSupported; 759 760 PaUtil_InitializeStreamInterface( &jackHostApi->callbackStreamInterface, 761 CloseStream, StartStream, 762 StopStream, AbortStream, 763 IsStreamStopped, IsStreamActive, 764 GetStreamTime, GetStreamCpuLoad, 765 PaUtil_DummyRead, PaUtil_DummyWrite, 766 PaUtil_DummyGetReadAvailable, 767 PaUtil_DummyGetWriteAvailable ); 768 769 PaUtil_InitializeStreamInterface( &jackHostApi->blockingStreamInterface, CloseStream, StartStream, 770 StopStream, AbortStream, IsStreamStopped, IsStreamActive, 771 GetStreamTime, PaUtil_DummyGetCpuLoad, 772 BlockingReadStream, BlockingWriteStream, 773 BlockingGetStreamReadAvailable, BlockingGetStreamWriteAvailable ); 774 775 jackHostApi->inputBase = jackHostApi->outputBase = 0; 776 jackHostApi->xrun = 0; 777 jackHostApi->toAdd = jackHostApi->toRemove = NULL; 778 jackHostApi->processQueue = NULL; 779 jackHostApi->jackIsDown = 0; 780 781 jack_on_shutdown( jackHostApi->jack_client, JackOnShutdown, jackHostApi ); 782 jack_set_error_function( JackErrorCallback ); 783 jackHostApi->jack_buffer_size = jack_get_buffer_size ( jackHostApi->jack_client ); 784 /* Don't check for error, may not be supported (deprecated in at least jackdmp) */ 785 jack_set_sample_rate_callback( jackHostApi->jack_client, JackSrCb, jackHostApi ); 786 UNLESS( !jack_set_xrun_callback( jackHostApi->jack_client, JackXRunCb, jackHostApi ), paUnanticipatedHostError ); 787 UNLESS( !jack_set_process_callback( jackHostApi->jack_client, JackCallback, jackHostApi ), paUnanticipatedHostError ); 788 UNLESS( !jack_activate( jackHostApi->jack_client ), paUnanticipatedHostError ); 789 activated = 1; 790 791 return result; 792 793 error: 794 if( activated ) 795 ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 ); 796 797 if( jackHostApi ) 798 { 799 if( jackHostApi->jack_client ) 800 ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 ); 801 802 if( jackHostApi->deviceInfoMemory ) 803 { 804 PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory ); 805 PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory ); 806 } 807 808 PaUtil_FreeMemory( jackHostApi ); 809 } 810 return result; 811 } 812 813 814 static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) 815 { 816 PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi; 817 818 /* note: this automatically disconnects all ports, since a deactivated 819 * client is not allowed to have any ports connected */ 820 ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 ); 821 822 ASSERT_CALL( pthread_mutex_destroy( &jackHostApi->mtx ), 0 ); 823 ASSERT_CALL( pthread_cond_destroy( &jackHostApi->cond ), 0 ); 824 825 ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 ); 826 827 if( jackHostApi->deviceInfoMemory ) 828 { 829 PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory ); 830 PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory ); 831 } 832 833 PaUtil_FreeMemory( jackHostApi ); 834 835 free( jackErr_ ); 836 jackErr_ = NULL; 837 } 838 839 static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, 840 const PaStreamParameters *inputParameters, 841 const PaStreamParameters *outputParameters, 842 double sampleRate ) 843 { 844 int inputChannelCount = 0, outputChannelCount = 0; 845 PaSampleFormat inputSampleFormat, outputSampleFormat; 846 847 if( inputParameters ) 848 { 849 inputChannelCount = inputParameters->channelCount; 850 inputSampleFormat = inputParameters->sampleFormat; 851 852 /* unless alternate device specification is supported, reject the use of 853 paUseHostApiSpecificDeviceSpecification */ 854 855 if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) 856 return paInvalidDevice; 857 858 /* check that input device can support inputChannelCount */ 859 if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) 860 return paInvalidChannelCount; 861 862 /* validate inputStreamInfo */ 863 if( inputParameters->hostApiSpecificStreamInfo ) 864 return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ 865 } 866 else 867 { 868 inputChannelCount = 0; 869 } 870 871 if( outputParameters ) 872 { 873 outputChannelCount = outputParameters->channelCount; 874 outputSampleFormat = outputParameters->sampleFormat; 875 876 /* unless alternate device specification is supported, reject the use of 877 paUseHostApiSpecificDeviceSpecification */ 878 879 if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) 880 return paInvalidDevice; 881 882 /* check that output device can support inputChannelCount */ 883 if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) 884 return paInvalidChannelCount; 885 886 /* validate outputStreamInfo */ 887 if( outputParameters->hostApiSpecificStreamInfo ) 888 return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ 889 } 890 else 891 { 892 outputChannelCount = 0; 893 } 894 895 /* 896 The following check is not necessary for JACK. 897 898 - if a full duplex stream is requested, check that the combination 899 of input and output parameters is supported 900 901 902 Because the buffer adapter handles conversion between all standard 903 sample formats, the following checks are only required if paCustomFormat 904 is implemented, or under some other unusual conditions. 905 906 - check that input device can support inputSampleFormat, or that 907 we have the capability to convert from outputSampleFormat to 908 a native format 909 910 - check that output device can support outputSampleFormat, or that 911 we have the capability to convert from outputSampleFormat to 912 a native format 913 */ 914 915 /* check that the device supports sampleRate */ 916 917 #define ABS(x) ( (x) > 0 ? (x) : -(x) ) 918 if( ABS(sampleRate - jack_get_sample_rate(((PaJackHostApiRepresentation *) hostApi)->jack_client )) > 1 ) 919 return paInvalidSampleRate; 920 #undef ABS 921 922 return paFormatIsSupported; 923 } 924 925 /* Basic stream initialization */ 926 static PaError InitializeStream( PaJackStream *stream, PaJackHostApiRepresentation *hostApi, int numInputChannels, 927 int numOutputChannels ) 928 { 929 PaError result = paNoError; 930 assert( stream ); 931 932 memset( stream, 0, sizeof (PaJackStream) ); 933 UNLESS( stream->stream_memory = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); 934 stream->jack_client = hostApi->jack_client; 935 stream->hostApi = hostApi; 936 937 if( numInputChannels > 0 ) 938 { 939 UNLESS( stream->local_input_ports = 940 (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ), 941 paInsufficientMemory ); 942 memset( stream->local_input_ports, 0, sizeof(jack_port_t*) * numInputChannels ); 943 UNLESS( stream->remote_output_ports = 944 (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ), 945 paInsufficientMemory ); 946 memset( stream->remote_output_ports, 0, sizeof(jack_port_t*) * numInputChannels ); 947 } 948 if( numOutputChannels > 0 ) 949 { 950 UNLESS( stream->local_output_ports = 951 (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ), 952 paInsufficientMemory ); 953 memset( stream->local_output_ports, 0, sizeof(jack_port_t*) * numOutputChannels ); 954 UNLESS( stream->remote_input_ports = 955 (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ), 956 paInsufficientMemory ); 957 memset( stream->remote_input_ports, 0, sizeof(jack_port_t*) * numOutputChannels ); 958 } 959 960 stream->num_incoming_connections = numInputChannels; 961 stream->num_outgoing_connections = numOutputChannels; 962 963 error: 964 return result; 965 } 966 967 /*! 968 * Free resources associated with stream, and eventually stream itself. 969 * 970 * Frees allocated memory, and closes opened pcms. 971 */ 972 static void CleanUpStream( PaJackStream *stream, int terminateStreamRepresentation, int terminateBufferProcessor ) 973 { 974 int i; 975 assert( stream ); 976 977 if( stream->isBlockingStream ) 978 BlockingEnd( stream ); 979 980 for( i = 0; i < stream->num_incoming_connections; ++i ) 981 { 982 if( stream->local_input_ports[i] ) 983 ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_input_ports[i] ), 0 ); 984 } 985 for( i = 0; i < stream->num_outgoing_connections; ++i ) 986 { 987 if( stream->local_output_ports[i] ) 988 ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_output_ports[i] ), 0 ); 989 } 990 991 if( terminateStreamRepresentation ) 992 PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); 993 if( terminateBufferProcessor ) 994 PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); 995 996 if( stream->stream_memory ) 997 { 998 PaUtil_FreeAllAllocations( stream->stream_memory ); 999 PaUtil_DestroyAllocationGroup( stream->stream_memory ); 1000 } 1001 PaUtil_FreeMemory( stream ); 1002 } 1003 1004 static PaError WaitCondition( PaJackHostApiRepresentation *hostApi ) 1005 { 1006 PaError result = paNoError; 1007 int err = 0; 1008 PaTime pt = PaUtil_GetTime(); 1009 struct timespec ts; 1010 1011 ts.tv_sec = (time_t) floor( pt + 10 * 60 /* 10 minutes */ ); 1012 ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000); 1013 /* XXX: Best enclose in loop, in case of spurious wakeups? */ 1014 err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts ); 1015 1016 /* Make sure we didn't time out */ 1017 UNLESS( err != ETIMEDOUT, paTimedOut ); 1018 UNLESS( !err, paInternalError ); 1019 1020 error: 1021 return result; 1022 } 1023 1024 static PaError AddStream( PaJackStream *stream ) 1025 { 1026 PaError result = paNoError; 1027 PaJackHostApiRepresentation *hostApi = stream->hostApi; 1028 /* Add to queue of streams that should be processed */ 1029 ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 ); 1030 if( !hostApi->jackIsDown ) 1031 { 1032 hostApi->toAdd = stream; 1033 /* Unlock mutex and await signal from processing thread */ 1034 result = WaitCondition( stream->hostApi ); 1035 } 1036 ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); 1037 ENSURE_PA( result ); 1038 1039 UNLESS( !hostApi->jackIsDown, paDeviceUnavailable ); 1040 1041 error: 1042 return result; 1043 } 1044 1045 /* Remove stream from processing queue */ 1046 static PaError RemoveStream( PaJackStream *stream ) 1047 { 1048 PaError result = paNoError; 1049 PaJackHostApiRepresentation *hostApi = stream->hostApi; 1050 1051 /* Add to queue over streams that should be processed */ 1052 ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 ); 1053 if( !hostApi->jackIsDown ) 1054 { 1055 hostApi->toRemove = stream; 1056 /* Unlock mutex and await signal from processing thread */ 1057 result = WaitCondition( stream->hostApi ); 1058 } 1059 ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); 1060 ENSURE_PA( result ); 1061 1062 error: 1063 return result; 1064 } 1065 1066 /* Add stream to JACK callback processing queue */ 1067 static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, 1068 PaStream** s, 1069 const PaStreamParameters *inputParameters, 1070 const PaStreamParameters *outputParameters, 1071 double sampleRate, 1072 unsigned long framesPerBuffer, 1073 PaStreamFlags streamFlags, 1074 PaStreamCallback *streamCallback, 1075 void *userData ) 1076 { 1077 PaError result = paNoError; 1078 PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi; 1079 PaJackStream *stream = NULL; 1080 char *port_string = PaUtil_GroupAllocateMemory( jackHostApi->deviceInfoMemory, jack_port_name_size() ); 1081 unsigned long regexSz = jack_client_name_size() + 3; 1082 char *regex_pattern = PaUtil_GroupAllocateMemory( jackHostApi->deviceInfoMemory, regexSz ); 1083 const char **jack_ports = NULL; 1084 /* int jack_max_buffer_size = jack_get_buffer_size( jackHostApi->jack_client ); */ 1085 int i; 1086 int inputChannelCount, outputChannelCount; 1087 const double jackSr = jack_get_sample_rate( jackHostApi->jack_client ); 1088 PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; 1089 int bpInitialized = 0, srInitialized = 0; /* Initialized buffer processor and stream representation? */ 1090 unsigned long ofs; 1091 1092 /* validate platform specific flags */ 1093 if( (streamFlags & paPlatformSpecificFlags) != 0 ) 1094 return paInvalidFlag; /* unexpected platform specific flag */ 1095 if( (streamFlags & paPrimeOutputBuffersUsingStreamCallback) != 0 ) 1096 { 1097 streamFlags &= ~paPrimeOutputBuffersUsingStreamCallback; 1098 /*return paInvalidFlag;*/ /* This implementation does not support buffer priming */ 1099 } 1100 1101 if( framesPerBuffer != paFramesPerBufferUnspecified ) 1102 { 1103 /* Jack operates with power of two buffers, and we don't support non-integer buffer adaption (yet) */ 1104 /*UNLESS( !(framesPerBuffer & (framesPerBuffer - 1)), paBufferTooBig );*/ /* TODO: Add descriptive error code? */ 1105 } 1106 1107 /* Preliminary checks */ 1108 1109 if( inputParameters ) 1110 { 1111 inputChannelCount = inputParameters->channelCount; 1112 inputSampleFormat = inputParameters->sampleFormat; 1113 1114 /* unless alternate device specification is supported, reject the use of 1115 paUseHostApiSpecificDeviceSpecification */ 1116 1117 if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) 1118 return paInvalidDevice; 1119 1120 /* check that input device can support inputChannelCount */ 1121 if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) 1122 return paInvalidChannelCount; 1123 1124 /* validate inputStreamInfo */ 1125 if( inputParameters->hostApiSpecificStreamInfo ) 1126 return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ 1127 } 1128 else 1129 { 1130 inputChannelCount = 0; 1131 } 1132 1133 if( outputParameters ) 1134 { 1135 outputChannelCount = outputParameters->channelCount; 1136 outputSampleFormat = outputParameters->sampleFormat; 1137 1138 /* unless alternate device specification is supported, reject the use of 1139 paUseHostApiSpecificDeviceSpecification */ 1140 1141 if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) 1142 return paInvalidDevice; 1143 1144 /* check that output device can support inputChannelCount */ 1145 if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) 1146 return paInvalidChannelCount; 1147 1148 /* validate outputStreamInfo */ 1149 if( outputParameters->hostApiSpecificStreamInfo ) 1150 return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ 1151 } 1152 else 1153 { 1154 outputChannelCount = 0; 1155 } 1156 1157 /* ... check that the sample rate exactly matches the ONE acceptable rate 1158 * A: This rate isn't necessarily constant though? */ 1159 1160 #define ABS(x) ( (x) > 0 ? (x) : -(x) ) 1161 if( ABS(sampleRate - jackSr) > 1 ) 1162 return paInvalidSampleRate; 1163 #undef ABS 1164 1165 UNLESS( stream = (PaJackStream*)PaUtil_AllocateMemory( sizeof(PaJackStream) ), paInsufficientMemory ); 1166 ENSURE_PA( InitializeStream( stream, jackHostApi, inputChannelCount, outputChannelCount ) ); 1167 1168 /* the blocking emulation, if necessary */ 1169 stream->isBlockingStream = !streamCallback; 1170 if( stream->isBlockingStream ) 1171 { 1172 float latency = 0.001; /* 1ms is the absolute minimum we support */ 1173 int minimum_buffer_frames = 0; 1174 1175 if( inputParameters && inputParameters->suggestedLatency > latency ) 1176 latency = inputParameters->suggestedLatency; 1177 else if( outputParameters && outputParameters->suggestedLatency > latency ) 1178 latency = outputParameters->suggestedLatency; 1179 1180 /* the latency the user asked for indicates the minimum buffer size in frames */ 1181 minimum_buffer_frames = (int) (latency * jack_get_sample_rate( jackHostApi->jack_client )); 1182 1183 /* we also need to be able to store at least three full jack buffers to avoid dropouts */ 1184 if( jackHostApi->jack_buffer_size * 3 > minimum_buffer_frames ) 1185 minimum_buffer_frames = jackHostApi->jack_buffer_size * 3; 1186 1187 /* setup blocking API data structures (FIXME: can fail) */ 1188 BlockingBegin( stream, minimum_buffer_frames ); 1189 1190 /* install our own callback for the blocking API */ 1191 streamCallback = BlockingCallback; 1192 userData = stream; 1193 1194 PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, 1195 &jackHostApi->blockingStreamInterface, streamCallback, userData ); 1196 } 1197 else 1198 { 1199 PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, 1200 &jackHostApi->callbackStreamInterface, streamCallback, userData ); 1201 } 1202 srInitialized = 1; 1203 PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, jackSr ); 1204 1205 /* create the JACK ports. We cannot connect them until audio 1206 * processing begins */ 1207 1208 /* Register a unique set of ports for this stream 1209 * TODO: Robust allocation of new port names */ 1210 1211 ofs = jackHostApi->inputBase; 1212 for( i = 0; i < inputChannelCount; i++ ) 1213 { 1214 snprintf( port_string, jack_port_name_size(), "in_%lu", ofs + i ); 1215 UNLESS( stream->local_input_ports[i] = jack_port_register( 1216 jackHostApi->jack_client, port_string, 1217 JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ), paInsufficientMemory ); 1218 } 1219 jackHostApi->inputBase += inputChannelCount; 1220 1221 ofs = jackHostApi->outputBase; 1222 for( i = 0; i < outputChannelCount; i++ ) 1223 { 1224 snprintf( port_string, jack_port_name_size(), "out_%lu", ofs + i ); 1225 UNLESS( stream->local_output_ports[i] = jack_port_register( 1226 jackHostApi->jack_client, port_string, 1227 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ), paInsufficientMemory ); 1228 } 1229 jackHostApi->outputBase += outputChannelCount; 1230 1231 /* look up the jack_port_t's for the remote ports. We could do 1232 * this at stream start time, but doing it here ensures the 1233 * name lookup only happens once. */ 1234 1235 if( inputChannelCount > 0 ) 1236 { 1237 int err = 0; 1238 1239 /* Get output ports of our capture device */ 1240 snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name ); 1241 UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, 1242 JACK_PORT_TYPE_FILTER, JackPortIsOutput ), paUnanticipatedHostError ); 1243 for( i = 0; i < inputChannelCount && jack_ports[i]; i++ ) 1244 { 1245 if( (stream->remote_output_ports[i] = jack_port_by_name( 1246 jackHostApi->jack_client, jack_ports[i] )) == NULL ) 1247 { 1248 err = 1; 1249 break; 1250 } 1251 } 1252 free( jack_ports ); 1253 UNLESS( !err, paInsufficientMemory ); 1254 1255 /* Fewer ports than expected? */ 1256 UNLESS( i == inputChannelCount, paInternalError ); 1257 } 1258 1259 if( outputChannelCount > 0 ) 1260 { 1261 int err = 0; 1262 1263 /* Get input ports of our playback device */ 1264 snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name ); 1265 UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, 1266 JACK_PORT_TYPE_FILTER, JackPortIsInput ), paUnanticipatedHostError ); 1267 for( i = 0; i < outputChannelCount && jack_ports[i]; i++ ) 1268 { 1269 if( (stream->remote_input_ports[i] = jack_port_by_name( 1270 jackHostApi->jack_client, jack_ports[i] )) == 0 ) 1271 { 1272 err = 1; 1273 break; 1274 } 1275 } 1276 free( jack_ports ); 1277 UNLESS( !err , paInsufficientMemory ); 1278 1279 /* Fewer ports than expected? */ 1280 UNLESS( i == outputChannelCount, paInternalError ); 1281 } 1282 1283 ENSURE_PA( PaUtil_InitializeBufferProcessor( 1284 &stream->bufferProcessor, 1285 inputChannelCount, 1286 inputSampleFormat, 1287 paFloat32 | paNonInterleaved, /* hostInputSampleFormat */ 1288 outputChannelCount, 1289 outputSampleFormat, 1290 paFloat32 | paNonInterleaved, /* hostOutputSampleFormat */ 1291 jackSr, 1292 streamFlags, 1293 framesPerBuffer, 1294 0, /* Ignored */ 1295 paUtilUnknownHostBufferSize, /* Buffer size may vary on JACK's discretion */ 1296 streamCallback, 1297 userData ) ); 1298 bpInitialized = 1; 1299 1300 if( stream->num_incoming_connections > 0 ) 1301 stream->streamRepresentation.streamInfo.inputLatency = (jack_port_get_latency( stream->remote_output_ports[0] ) 1302 - jack_get_buffer_size( jackHostApi->jack_client ) /* One buffer is not counted as latency */ 1303 + PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor )) / sampleRate; 1304 if( stream->num_outgoing_connections > 0 ) 1305 stream->streamRepresentation.streamInfo.outputLatency = (jack_port_get_latency( stream->remote_input_ports[0] ) 1306 - jack_get_buffer_size( jackHostApi->jack_client ) /* One buffer is not counted as latency */ 1307 + PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor )) / sampleRate; 1308 1309 stream->streamRepresentation.streamInfo.sampleRate = jackSr; 1310 stream->t0 = jack_frame_time( jackHostApi->jack_client ); /* A: Time should run from Pa_OpenStream */ 1311 1312 /* Add to queue of opened streams */ 1313 ENSURE_PA( AddStream( stream ) ); 1314 1315 *s = (PaStream*)stream; 1316 1317 return result; 1318 1319 error: 1320 if( stream ) 1321 CleanUpStream( stream, srInitialized, bpInitialized ); 1322 1323 return result; 1324 } 1325 1326 /* 1327 When CloseStream() is called, the multi-api layer ensures that 1328 the stream has already been stopped or aborted. 1329 */ 1330 static PaError CloseStream( PaStream* s ) 1331 { 1332 PaError result = paNoError; 1333 PaJackStream *stream = (PaJackStream*)s; 1334 1335 /* Remove this stream from the processing queue */ 1336 ENSURE_PA( RemoveStream( stream ) ); 1337 1338 error: 1339 CleanUpStream( stream, 1, 1 ); 1340 return result; 1341 } 1342 1343 static PaError RealProcess( PaJackStream *stream, jack_nframes_t frames ) 1344 { 1345 PaError result = paNoError; 1346 PaStreamCallbackTimeInfo timeInfo = {0,0,0}; 1347 int chn; 1348 int framesProcessed; 1349 const double sr = jack_get_sample_rate( stream->jack_client ); /* Shouldn't change during the process callback */ 1350 PaStreamCallbackFlags cbFlags = 0; 1351 1352 /* If the user has returned !paContinue from the callback we'll want to flush the internal buffers, 1353 * when these are empty we can finally mark the stream as inactive */ 1354 if( stream->callbackResult != paContinue && 1355 PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) 1356 { 1357 stream->is_active = 0; 1358 if( stream->streamRepresentation.streamFinishedCallback ) 1359 stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); 1360 PA_DEBUG(( "%s: Callback finished\n", __FUNCTION__ )); 1361 1362 goto end; 1363 } 1364 1365 timeInfo.currentTime = (jack_frame_time( stream->jack_client ) - stream->t0) / sr; 1366 if( stream->num_incoming_connections > 0 ) 1367 timeInfo.inputBufferAdcTime = timeInfo.currentTime - jack_port_get_latency( stream->remote_output_ports[0] ) 1368 / sr; 1369 if( stream->num_outgoing_connections > 0 ) 1370 timeInfo.outputBufferDacTime = timeInfo.currentTime + jack_port_get_latency( stream->remote_input_ports[0] ) 1371 / sr; 1372 1373 PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); 1374 1375 if( stream->xrun ) 1376 { 1377 /* XXX: Any way to tell which of these occurred? */ 1378 cbFlags = paOutputUnderflow | paInputOverflow; 1379 stream->xrun = FALSE; 1380 } 1381 PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 1382 cbFlags ); 1383 1384 if( stream->num_incoming_connections > 0 ) 1385 PaUtil_SetInputFrameCount( &stream->bufferProcessor, frames ); 1386 if( stream->num_outgoing_connections > 0 ) 1387 PaUtil_SetOutputFrameCount( &stream->bufferProcessor, frames ); 1388 1389 for( chn = 0; chn < stream->num_incoming_connections; chn++ ) 1390 { 1391 jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*) 1392 jack_port_get_buffer( stream->local_input_ports[chn], 1393 frames ); 1394 1395 PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor, 1396 chn, 1397 channel_buf ); 1398 } 1399 1400 for( chn = 0; chn < stream->num_outgoing_connections; chn++ ) 1401 { 1402 jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*) 1403 jack_port_get_buffer( stream->local_output_ports[chn], 1404 frames ); 1405 1406 PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor, 1407 chn, 1408 channel_buf ); 1409 } 1410 1411 framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, 1412 &stream->callbackResult ); 1413 /* We've specified a host buffer size mode where every frame should be consumed by the buffer processor */ 1414 assert( framesProcessed == frames ); 1415 1416 PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); 1417 1418 end: 1419 return result; 1420 } 1421 1422 /* Update the JACK callback's stream processing queue. */ 1423 static PaError UpdateQueue( PaJackHostApiRepresentation *hostApi ) 1424 { 1425 PaError result = paNoError; 1426 int queueModified = 0; 1427 const double jackSr = jack_get_sample_rate( hostApi->jack_client ); 1428 int err; 1429 1430 if( (err = pthread_mutex_trylock( &hostApi->mtx )) != 0 ) 1431 { 1432 assert( err == EBUSY ); 1433 return paNoError; 1434 } 1435 1436 if( hostApi->toAdd ) 1437 { 1438 if( hostApi->processQueue ) 1439 { 1440 PaJackStream *node = hostApi->processQueue; 1441 /* Advance to end of queue */ 1442 while( node->next ) 1443 node = node->next; 1444 1445 node->next = hostApi->toAdd; 1446 } 1447 else 1448 { 1449 /* The only queue entry. */ 1450 hostApi->processQueue = (PaJackStream *)hostApi->toAdd; 1451 } 1452 1453 /* If necessary, update stream state */ 1454 if( hostApi->toAdd->streamRepresentation.streamInfo.sampleRate != jackSr ) 1455 UpdateSampleRate( hostApi->toAdd, jackSr ); 1456 1457 hostApi->toAdd = NULL; 1458 queueModified = 1; 1459 } 1460 if( hostApi->toRemove ) 1461 { 1462 int removed = 0; 1463 PaJackStream *node = hostApi->processQueue, *prev = NULL; 1464 assert( hostApi->processQueue ); 1465 1466 while( node ) 1467 { 1468 if( node == hostApi->toRemove ) 1469 { 1470 if( prev ) 1471 prev->next = node->next; 1472 else 1473 hostApi->processQueue = (PaJackStream *)node->next; 1474 1475 removed = 1; 1476 break; 1477 } 1478 1479 prev = node; 1480 node = node->next; 1481 } 1482 UNLESS( removed, paInternalError ); 1483 hostApi->toRemove = NULL; 1484 PA_DEBUG(( "%s: Removed stream from processing queue\n", __FUNCTION__ )); 1485 queueModified = 1; 1486 } 1487 1488 if( queueModified ) 1489 { 1490 /* Signal that we've done what was asked of us */ 1491 ASSERT_CALL( pthread_cond_signal( &hostApi->cond ), 0 ); 1492 } 1493 1494 error: 1495 ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); 1496 1497 return result; 1498 } 1499 1500 /* Audio processing callback invoked periodically from JACK. */ 1501 static int JackCallback( jack_nframes_t frames, void *userData ) 1502 { 1503 PaError result = paNoError; 1504 PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)userData; 1505 PaJackStream *stream = NULL; 1506 int xrun = hostApi->xrun; 1507 hostApi->xrun = 0; 1508 1509 assert( hostApi ); 1510 1511 ENSURE_PA( UpdateQueue( hostApi ) ); 1512 1513 /* Process each stream */ 1514 stream = hostApi->processQueue; 1515 for( ; stream; stream = stream->next ) 1516 { 1517 if( xrun ) /* Don't override if already set */ 1518 stream->xrun = 1; 1519 1520 /* See if this stream is to be started */ 1521 if( stream->doStart ) 1522 { 1523 /* If we can't obtain a lock, we'll try next time */ 1524 int err = pthread_mutex_trylock( &stream->hostApi->mtx ); 1525 if( !err ) 1526 { 1527 if( stream->doStart ) /* Could potentially change before obtaining the lock */ 1528 { 1529 stream->is_active = 1; 1530 stream->doStart = 0; 1531 PA_DEBUG(( "%s: Starting stream\n", __FUNCTION__ )); 1532 ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 ); 1533 stream->callbackResult = paContinue; 1534 stream->isSilenced = 0; 1535 } 1536 1537 ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); 1538 } 1539 else 1540 assert( err == EBUSY ); 1541 } 1542 else if( stream->doStop || stream->doAbort ) /* Should we stop/abort stream? */ 1543 { 1544 if( stream->callbackResult == paContinue ) /* Ok, make it stop */ 1545 { 1546 PA_DEBUG(( "%s: Stopping stream\n", __FUNCTION__ )); 1547 stream->callbackResult = stream->doStop ? paComplete : paAbort; 1548 } 1549 } 1550 1551 if( stream->is_active ) 1552 ENSURE_PA( RealProcess( stream, frames ) ); 1553 /* If we have just entered inactive state, silence output */ 1554 if( !stream->is_active && !stream->isSilenced ) 1555 { 1556 int i; 1557 1558 /* Silence buffer after entering inactive state */ 1559 PA_DEBUG(( "Silencing the output\n" )); 1560 for( i = 0; i < stream->num_outgoing_connections; ++i ) 1561 { 1562 jack_default_audio_sample_t *buffer = jack_port_get_buffer( stream->local_output_ports[i], frames ); 1563 memset( buffer, 0, sizeof (jack_default_audio_sample_t) * frames ); 1564 } 1565 1566 stream->isSilenced = 1; 1567 } 1568 1569 if( stream->doStop || stream->doAbort ) 1570 { 1571 /* See if RealProcess has acted on the request */ 1572 if( !stream->is_active ) /* Ok, signal to the main thread that we've carried out the operation */ 1573 { 1574 /* If we can't obtain a lock, we'll try next time */ 1575 int err = pthread_mutex_trylock( &stream->hostApi->mtx ); 1576 if( !err ) 1577 { 1578 stream->doStop = stream->doAbort = 0; 1579 ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 ); 1580 ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); 1581 } 1582 else 1583 assert( err == EBUSY ); 1584 } 1585 } 1586 } 1587 1588 return 0; 1589 error: 1590 return -1; 1591 } 1592 1593 static PaError StartStream( PaStream *s ) 1594 { 1595 PaError result = paNoError; 1596 PaJackStream *stream = (PaJackStream*)s; 1597 int i; 1598 1599 /* Ready the processor */ 1600 PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); 1601 1602 /* Connect the ports. Note that the ports may already have been connected by someone else in 1603 * the meantime, in which case JACK returns EEXIST. */ 1604 1605 if( stream->num_incoming_connections > 0 ) 1606 { 1607 for( i = 0; i < stream->num_incoming_connections; i++ ) 1608 { 1609 int r = jack_connect( stream->jack_client, jack_port_name( stream->remote_output_ports[i] ), 1610 jack_port_name( stream->local_input_ports[i] ) ); 1611 UNLESS( 0 == r || EEXIST == r, paUnanticipatedHostError ); 1612 } 1613 } 1614 1615 if( stream->num_outgoing_connections > 0 ) 1616 { 1617 for( i = 0; i < stream->num_outgoing_connections; i++ ) 1618 { 1619 int r = jack_connect( stream->jack_client, jack_port_name( stream->local_output_ports[i] ), 1620 jack_port_name( stream->remote_input_ports[i] ) ); 1621 UNLESS( 0 == r || EEXIST == r, paUnanticipatedHostError ); 1622 } 1623 } 1624 1625 stream->xrun = FALSE; 1626 1627 /* Enable processing */ 1628 1629 ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 ); 1630 stream->doStart = 1; 1631 1632 /* Wait for stream to be started */ 1633 result = WaitCondition( stream->hostApi ); 1634 /* 1635 do 1636 { 1637 err = pthread_cond_timedwait( &stream->hostApi->cond, &stream->hostApi->mtx, &ts ); 1638 } while( !stream->is_active && !err ); 1639 */ 1640 if( result != paNoError ) /* Something went wrong, call off the stream start */ 1641 { 1642 stream->doStart = 0; 1643 stream->is_active = 0; /* Cancel any processing */ 1644 } 1645 ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); 1646 1647 ENSURE_PA( result ); 1648 1649 stream->is_running = TRUE; 1650 PA_DEBUG(( "%s: Stream started\n", __FUNCTION__ )); 1651 1652 error: 1653 return result; 1654 } 1655 1656 static PaError RealStop( PaJackStream *stream, int abort ) 1657 { 1658 PaError result = paNoError; 1659 int i; 1660 1661 if( stream->isBlockingStream ) 1662 BlockingWaitEmpty ( stream ); 1663 1664 ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 ); 1665 if( abort ) 1666 stream->doAbort = 1; 1667 else 1668 stream->doStop = 1; 1669 1670 /* Wait for stream to be stopped */ 1671 result = WaitCondition( stream->hostApi ); 1672 ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); 1673 ENSURE_PA( result ); 1674 1675 UNLESS( !stream->is_active, paInternalError ); 1676 1677 PA_DEBUG(( "%s: Stream stopped\n", __FUNCTION__ )); 1678 1679 error: 1680 stream->is_running = FALSE; 1681 1682 /* Disconnect ports belonging to this stream */ 1683 1684 if( !stream->hostApi->jackIsDown ) /* XXX: Well? */ 1685 { 1686 for( i = 0; i < stream->num_incoming_connections; i++ ) 1687 { 1688 if( jack_port_connected( stream->local_input_ports[i] ) ) 1689 { 1690 UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_input_ports[i] ), 1691 paUnanticipatedHostError ); 1692 } 1693 } 1694 for( i = 0; i < stream->num_outgoing_connections; i++ ) 1695 { 1696 if( jack_port_connected( stream->local_output_ports[i] ) ) 1697 { 1698 UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_output_ports[i] ), 1699 paUnanticipatedHostError ); 1700 } 1701 } 1702 } 1703 1704 return result; 1705 } 1706 1707 static PaError StopStream( PaStream *s ) 1708 { 1709 assert(s); 1710 return RealStop( (PaJackStream *)s, 0 ); 1711 } 1712 1713 static PaError AbortStream( PaStream *s ) 1714 { 1715 assert(s); 1716 return RealStop( (PaJackStream *)s, 1 ); 1717 } 1718 1719 static PaError IsStreamStopped( PaStream *s ) 1720 { 1721 PaJackStream *stream = (PaJackStream*)s; 1722 return !stream->is_running; 1723 } 1724 1725 1726 static PaError IsStreamActive( PaStream *s ) 1727 { 1728 PaJackStream *stream = (PaJackStream*)s; 1729 return stream->is_active; 1730 } 1731 1732 1733 static PaTime GetStreamTime( PaStream *s ) 1734 { 1735 PaJackStream *stream = (PaJackStream*)s; 1736 1737 /* A: Is this relevant?? --> TODO: what if we're recording-only? */ 1738 return (jack_frame_time( stream->jack_client ) - stream->t0) / (PaTime)jack_get_sample_rate( stream->jack_client ); 1739 } 1740 1741 1742 static double GetStreamCpuLoad( PaStream* s ) 1743 { 1744 PaJackStream *stream = (PaJackStream*)s; 1745 return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); 1746 } 1747 1748 PaError PaJack_SetClientName( const char* name ) 1749 { 1750 if( strlen( name ) > jack_client_name_size() ) 1751 { 1752 /* OK, I don't know any better error code */ 1753 return paInvalidFlag; 1754 } 1755 clientName_ = name; 1756 return paNoError; 1757 } 1758 1759 PaError PaJack_GetClientName(const char** clientName) 1760 { 1761 PaError result = paNoError; 1762 PaJackHostApiRepresentation* jackHostApi = NULL; 1763 PaJackHostApiRepresentation** ref = &jackHostApi; 1764 ENSURE_PA( PaUtil_GetHostApiRepresentation( (PaUtilHostApiRepresentation**)ref, paJACK ) ); 1765 *clientName = jack_get_client_name( jackHostApi->jack_client ); 1766 1767 error: 1768 return result; 1769 }