00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <errno.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <fcntl.h>
00027 #include <math.h>
00028 #include <unistd.h>
00029 #include <inttypes.h>
00030 #include <jack/jack.h>
00031 #include <pthread.h>
00032 #include <sys/time.h>
00033
00034 #include "bio2jack.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #define CALLBACK_TRACE 0
00047
00048
00049 #define VERBOSE_OUTPUT 0
00050
00051
00052 #define TRACE_ENABLE 0
00053
00054
00055 #define TRACE_getReleaseDevice 0
00056
00057
00058 #define OUTFILE stderr
00059
00060 #if TRACE_ENABLE
00061 #define TRACE(...) fprintf(OUTFILE, "%s:", __FUNCTION__), \
00062 fprintf(OUTFILE, __VA_ARGS__), \
00063 fflush(OUTFILE);
00064 #else
00065 #define TRACE(...) do{}while(0)
00066 #endif
00067
00068 #define ERR(...) fprintf(OUTFILE, "ERR: %s:", __FUNCTION__),\
00069 fprintf(OUTFILE, __VA_ARGS__), \
00070 fflush(OUTFILE);
00071
00072 #define min(a,b) (((a) < (b)) ? (a) : (b))
00073 #define max(a,b) (((a) < (b)) ? (b) : (a))
00074
00075
00076
00077 typedef struct wave_header_s
00078 {
00079 unsigned char* pData;
00080 long size;
00081
00082 struct wave_header_s *pNext;
00083 } wave_header_t;
00084
00085
00086 enum cmd_enum { CMD_SET_POSITION };
00087
00088
00089 typedef struct message_s
00090 {
00091 enum cmd_enum command;
00092 long data;
00093
00094 struct message_s *pNext;
00095 } message_t;
00096
00097
00098 #define MAX_OUTPUT_PORTS 10
00099
00100 typedef struct jack_driver_s
00101 {
00102 int deviceID;
00103 long sample_rate;
00104 unsigned long num_input_channels;
00105 unsigned long num_output_channels;
00106 unsigned long bits_per_channel;
00107 unsigned long bytes_per_output_frame;
00108 unsigned long bytes_per_input_frame;
00109
00110 unsigned long latencyMS;
00111
00112 long clientBytesInJack;
00113 unsigned long buffer_size;
00114
00115 unsigned char* sound_buffer;
00116 struct timeval previousTime;
00117
00118 unsigned long written_client_bytes;
00119 unsigned long played_client_bytes;
00120
00121 unsigned long client_bytes;
00122
00123 jack_port_t* output_port[MAX_OUTPUT_PORTS];
00124 jack_client_t* client;
00125
00126 char **jack_port_name;
00127 unsigned int jack_port_name_count;
00128 unsigned long jack_port_flags;
00129
00130 wave_header_t* pPlayPtr;
00131 long playptr_offset;
00132
00133 enum status_enum state;
00134
00135 unsigned int volume[MAX_OUTPUT_PORTS];
00136 enum JACK_VOLUME_TYPE volumeEffectType;
00137
00138
00139 long position_byte_offset;
00140
00141
00142 bool in_use;
00143
00144 message_t *pMessages;
00145
00146 pthread_mutex_t mutex;
00147
00148
00149 bool jackd_died;
00150 struct timeval last_reconnect_attempt;
00151 } jack_driver_t;
00152
00153
00154
00155
00156 #define JACK_CLOSE_HACK 1
00157
00158 typedef jack_default_audio_sample_t sample_t;
00159 typedef jack_nframes_t nframes_t;
00160
00161
00162 static int first_free_device = 0;
00163 #define MAX_OUTDEVICES 10
00164 static jack_driver_t outDev[MAX_OUTDEVICES];
00165
00166
00167 #define SECONDS .25
00168 static long MAX_BUFFERED_BYTES = (long)(16 * 2 * (44100/(1/SECONDS))) / 8;
00169
00170 #if JACK_CLOSE_HACK
00171 static void JACK_CloseDevice(jack_driver_t* drv, bool close_client);
00172 #else
00173 static void JACK_CloseDevice(jack_driver_t* drv);
00174 #endif
00175
00176
00177
00178 static int JACK_OpenDevice(jack_driver_t* drv);
00179 static long JACK_GetBytesFreeSpaceFromDriver(jack_driver_t *drv);
00180 static void JACK_ResetFromDriver(jack_driver_t *drv);
00181 static long JACK_GetPositionFromDriver(jack_driver_t *drv, enum pos_enum position, int type);
00182
00183
00184
00185
00186
00187 long TimeValDifference(struct timeval *start, struct timeval *end)
00188 {
00189 double long ms;
00190
00191 ms = end->tv_sec - start->tv_sec;
00192 ms*=(double)1000;
00193
00194 ms+=(double)(end->tv_usec - start->tv_usec) / (double)1000;
00195
00196 return (long)ms;
00197 }
00198
00199
00200
00201
00202
00203
00204 jack_driver_t *getDriver(int deviceID)
00205 {
00206 jack_driver_t *drv = &outDev[deviceID];
00207 #if TRACE_getReleaseDevice
00208 TRACE("deviceID == %d\n", deviceID);
00209 #endif
00210 pthread_mutex_lock(&drv->mutex);
00211
00212
00213 if (drv->jackd_died && drv->client == 0)
00214 {
00215 struct timeval now;
00216 gettimeofday(&now, 0);
00217
00218
00219 if (TimeValDifference(&drv->last_reconnect_attempt, &now) >= 250)
00220 {
00221 JACK_OpenDevice(drv);
00222 drv->last_reconnect_attempt = now;
00223 }
00224 }
00225
00226 return drv;
00227 }
00228
00229
00230 void releaseDriver(jack_driver_t *drv)
00231 {
00232 #if TRACE_getReleaseDevice
00233 TRACE("deviceID == %d\n", drv->deviceID);
00234 #endif
00235 pthread_mutex_unlock(&drv->mutex);
00236 }
00237
00238
00239
00240 char* DEBUGSTATE(enum status_enum state)
00241 {
00242 if (state == PLAYING)
00243 return "PLAYING";
00244 else if (state == PAUSED)
00245 return "PAUSED";
00246 else if (state == STOPPED)
00247 return "STOPPED";
00248 else if (state == CLOSED)
00249 return "CLOSED";
00250 else if (state == RESET)
00251 return "RESET";
00252 else
00253 return "unknown state";
00254 }
00255
00256
00257 #define SAMPLE_MAX_16BIT 32767.0f
00258
00259
00260
00261 static void float_volume_effect(sample_t *buf, unsigned long nsamples, float volume)
00262 {
00263 if (volume < 0) volume = 0;
00264 if (volume > 1.0) volume = 1.0;
00265
00266 while (nsamples--)
00267 {
00268 *buf = (*buf) * volume;
00269 buf++;
00270 }
00271 }
00272
00273
00274 static void sample_move_d16_d16(short *dst, short *src,
00275 unsigned long nsamples, int nDstChannels, int nSrcChannels)
00276 {
00277 int nSrcCount, nDstCount;
00278
00279 TRACE("nsamples == %ld, nDstChannels == %d, nSrcChannels == %d\n", nsamples, nDstChannels, nSrcChannels);
00280
00281 if (!nSrcChannels && !nDstChannels)
00282 {
00283 ERR("nSrcChannels of %d, nDstChannels of %d, can't have zero channels\n", nSrcChannels, nDstChannels);
00284 return;
00285 }
00286
00287 while(nsamples--)
00288 {
00289 nSrcCount = nSrcChannels;
00290 nDstCount = nDstChannels;
00291
00292
00293 while(nDstCount)
00294 {
00295 nSrcCount--;
00296 nDstCount--;
00297
00298 *dst = *src;
00299 dst++;
00300 src++;
00301
00302
00303
00304 if (!nSrcCount && nDstCount)
00305 {
00306 src-=nSrcChannels;
00307 nSrcCount = nSrcChannels;
00308 }
00309 }
00310
00311
00312 src+=nSrcCount;
00313 dst+=nDstCount;
00314 }
00315 }
00316
00317
00318
00319
00320 static void sample_move_d16_s16 (sample_t *dst, short *src,
00321 unsigned long nsamples, unsigned long src_skip)
00322 {
00323
00324 while (nsamples--)
00325 {
00326 *dst = (*src) / SAMPLE_MAX_16BIT;
00327 dst++;
00328 src += src_skip;
00329 }
00330 }
00331
00332
00333 void sample_silence_dS (sample_t *dst, unsigned long nsamples)
00334 {
00335
00336 while (nsamples--)
00337 {
00338 *dst = 0;
00339 dst++;
00340 }
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350 static int JACK_callback (nframes_t nframes, void *arg)
00351 {
00352 sample_t* out_buffer[MAX_OUTPUT_PORTS];
00353 jack_driver_t* drv = (jack_driver_t*)arg;
00354 unsigned int i;
00355
00356 gettimeofday(&drv->previousTime, 0);
00357
00358 #if CALLBACK_TRACE
00359 TRACE("nframes %ld, sizeof(sample_t) == %d\n", (long)nframes, sizeof(sample_t));
00360 #endif
00361
00362 if (!drv->client)
00363 ERR("client is closed, this is weird...\n");
00364
00365
00366 for(i = 0; i < drv->num_output_channels; i++)
00367 out_buffer[i] = (sample_t *) jack_port_get_buffer(drv->output_port[i], nframes);
00368
00369 #if 0
00370
00371 if (drv->pMessages)
00372 {
00373 message_t *msg = drv->pMessages;
00374
00375
00376 if (msg->command == CMD_SET_POSITION)
00377 {
00378
00379
00380 drv->position_byte_offset = msg->data - drv->client_bytes;
00381
00382
00383
00384 drv->written_jack_bytes = drv->played_bytes = drv->client_bytes;
00385
00386 drv->clientBytesInJack = 0;
00387
00388 if (drv->pPlayPtr != 0)
00389 {
00390 TRACE("ERROR, setting position but pPlayPtr != 0\n");
00391 TRACE("state == %s\n", DEBUGSTATE(drv->state));
00392 }
00393
00394 TRACE("deviceID(%d), setting position to byte offset of %ld\n", drv->deviceID, msg->data);
00395 }
00396
00397 #if 0
00398 if (msg->command == WRITTEN)
00399 {
00400 drv->client_bytes = msg->data;
00401 TRACE("deviceID(%d), setting client_bytes to %d\n", drv->deviceID, drv->client_bytes);
00402 } else if (msg->command == WRITTEN_TO_JACK)
00403 {
00404 drv->written_jack_bytes = msg->data;
00405 TRACE("deviceID(%d), setting written_jack_bytes to %d\n", drv->deviceID, drv->written_jack_bytes);
00406 }
00407 else if (msg->command == PLAYED)
00408 {
00409 drv->played_bytes = msg->data;
00410 TRACE("deviceID(%d), setting played_bytes to %d\n", drv->deviceID, drv->played_bytes);
00411 } else
00412 {
00413 ERR("unknown type for drv->setType\n");
00414 }
00415 #endif
00416 drv->pMessages = msg->pNext;
00417 free(msg);
00418 }
00419 #endif
00420
00421
00422 if (drv->state == PLAYING)
00423 {
00424 unsigned long jackFramesAvailable = nframes;
00425 unsigned long inputFramesAvailable;
00426 unsigned long numFramesToWrite;
00427
00428 long written, read;
00429 unsigned char* buffer;
00430
00431 written = read = 0;
00432
00433 #if CALLBACK_TRACE
00434 TRACE("playing... jackFramesAvailable = %ld\n", jackFramesAvailable);
00435 #endif
00436
00437 #if JACK_CLOSE_HACK
00438 if (drv->in_use == FALSE)
00439 {
00440
00441 for(i = 0; i < drv->num_output_channels; i++)
00442 sample_silence_dS(out_buffer[i], nframes);
00443
00444 return 0;
00445 }
00446 #endif
00447
00448
00449
00450
00451
00452 if (drv->buffer_size < (jackFramesAvailable * sizeof(short) * drv->num_output_channels))
00453 {
00454 ERR("our buffer must have changed size\n");
00455 ERR("allocated %ld bytes, need %ld bytes\n", drv->buffer_size,
00456 jackFramesAvailable * sizeof(short) * drv->num_output_channels);
00457 return 0;
00458 }
00459
00460
00461 while(jackFramesAvailable && drv->pPlayPtr)
00462 {
00463
00464 if (drv->num_input_channels != 0)
00465 inputFramesAvailable = (drv->pPlayPtr->size - drv->playptr_offset) / (sizeof(short) * drv->num_input_channels);
00466 else
00467 inputFramesAvailable = 0;
00468
00469 #if CALLBACK_TRACE
00470 TRACE("inputFramesAvailable == %ld, jackFramesAvailable == %ld\n", inputFramesAvailable, jackFramesAvailable);
00471 #endif
00472
00473 buffer = drv->pPlayPtr->pData + drv->playptr_offset;
00474
00475
00476 if (drv->bits_per_channel == 8)
00477 inputFramesAvailable<<=1;
00478
00479 numFramesToWrite = min(jackFramesAvailable, inputFramesAvailable);
00480
00481 #if CALLBACK_TRACE
00482 TRACE("inputFramesAvailable after conversion %ld\n", inputFramesAvailable);
00483 TRACE("nframes == %d, jackFramesAvailable == %ld,\n\tdrv->num_input_channels == %ld, drv->num_output_channels == %ld\n",
00484 nframes, jackFramesAvailable, drv->num_input_channels, drv->num_output_channels);
00485 #endif
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 if (drv->num_input_channels != drv->num_output_channels)
00498 {
00499 sample_move_d16_d16((short*)drv->sound_buffer + ((nframes - jackFramesAvailable) * drv->bits_per_channel * drv->num_output_channels) / (sizeof(short) * 8),
00500 (short*)buffer, numFramesToWrite, drv->num_output_channels, drv->num_input_channels);
00501 } else
00502 {
00503 memcpy(drv->sound_buffer + ((nframes - jackFramesAvailable) * drv->bits_per_channel * drv->num_output_channels) / 8,
00504 buffer, (numFramesToWrite * drv->bits_per_channel * drv->num_input_channels) / 8);
00505 }
00506
00507
00508
00509 if (numFramesToWrite == inputFramesAvailable)
00510 {
00511 wave_header_t* pOldHeader;
00512
00513 #if CALLBACK_TRACE
00514 TRACE("numFramesToWrite == inputFramesAvailable, advancing to next header\n");
00515 #endif
00516
00517 free(drv->pPlayPtr->pData);
00518 drv->playptr_offset = 0;
00519 pOldHeader = drv->pPlayPtr;
00520 drv->pPlayPtr = drv->pPlayPtr->pNext;
00521 free(pOldHeader);
00522 }
00523 else
00524 {
00525
00526 drv->playptr_offset+=((numFramesToWrite * drv->bits_per_channel * drv->num_input_channels) / 8);
00527 }
00528
00529
00530 written+=((numFramesToWrite * drv->bits_per_channel * drv->num_output_channels) / 8);
00531 read+=((numFramesToWrite * drv->bits_per_channel * drv->num_input_channels) / 8);
00532
00533 jackFramesAvailable-=numFramesToWrite;
00534
00535 #if CALLBACK_TRACE
00536 TRACE("jackFramesAvailable == %ld\n", jackFramesAvailable);
00537 #endif
00538 }
00539
00540
00541 drv->written_client_bytes+=read;
00542 drv->played_client_bytes+=drv->clientBytesInJack;
00543 drv->clientBytesInJack = read;
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 for(i = 0; i < drv->num_output_channels; i++)
00554 {
00555 sample_move_d16_s16(out_buffer[i], (short*)drv->sound_buffer + i,
00556 (nframes - jackFramesAvailable), drv->num_output_channels);
00557
00558
00559 if (drv->volumeEffectType == dbAttenuation)
00560 {
00561
00562
00563 float volume = powf(10.0, -((float)drv->volume[i]) / 20.0);
00564 float_volume_effect(out_buffer[i], (nframes - jackFramesAvailable),
00565 volume);
00566 } else
00567 {
00568 float_volume_effect(out_buffer[i], (nframes - jackFramesAvailable),
00569 ((float)drv->volume[i] / 100.0));
00570 }
00571 }
00572
00573
00574
00575
00576
00577 if (jackFramesAvailable)
00578 {
00579 #if CALLBACK_TRACE
00580 TRACE("buffer underrun of %ld frames\n", jackFramesAvailable);
00581 #endif
00582 for(i = 0 ; i < drv->num_output_channels; i++)
00583 sample_silence_dS(out_buffer[i] + (nframes - jackFramesAvailable), jackFramesAvailable);
00584 }
00585 }
00586 else if (drv->state == PAUSED ||
00587 drv->state == STOPPED ||
00588 drv->state == CLOSED ||
00589 drv->state == RESET)
00590 {
00591 #if CALLBACK_TRACE
00592 TRACE("PAUSED or STOPPED or CLOSED, outputting silence\n");
00593 #endif
00594
00595
00596 for(i = 0; i < drv->num_output_channels; i++)
00597 sample_silence_dS(out_buffer[i], nframes);
00598
00599
00600
00601 if (drv->state == RESET)
00602 {
00603 wave_header_t *wh = drv->pPlayPtr;
00604 drv->written_client_bytes = 0;
00605 drv->played_client_bytes = 0;
00606
00607 drv->client_bytes = 0;
00608 drv->clientBytesInJack = 0;
00609
00610 drv->pPlayPtr = 0;
00611 drv->playptr_offset = 0;
00612 drv->position_byte_offset = 0;
00613
00614
00615
00616
00617 wh = drv->pPlayPtr;
00618 while(wh)
00619 {
00620 wh = wh->pNext;
00621 free(drv->pPlayPtr->pData);
00622 free(drv->pPlayPtr);
00623 drv->pPlayPtr = wh;
00624 }
00625
00626 drv->state = STOPPED;
00627 }
00628 }
00629
00630 #if CALLBACK_TRACE
00631 TRACE("done\n");
00632 #endif
00633
00634 return 0;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644 static int JACK_bufsize (nframes_t nframes, void *arg)
00645 {
00646 jack_driver_t* drv = (jack_driver_t*)arg;
00647 unsigned long buffer_required;
00648 TRACE("the maximum buffer size is now %lu frames\n", (long)nframes);
00649
00650
00651
00652
00653 buffer_required = nframes * sizeof(short) * drv->num_output_channels;
00654 if (drv->buffer_size < buffer_required)
00655 {
00656 TRACE("expanding buffer from drv->buffer_size == %ld, to %ld\n",
00657 drv->buffer_size, buffer_required);
00658 drv->buffer_size = buffer_required;
00659 drv->sound_buffer = (unsigned char*)realloc(drv->sound_buffer, drv->buffer_size);
00660
00661
00662 if (!drv->sound_buffer)
00663 {
00664 ERR("error allocating sound_buffer memory\n");
00665 return 0;
00666 }
00667 }
00668
00669 TRACE("called\n");
00670 return 0;
00671 }
00672
00673
00674
00675
00676 int JACK_srate (nframes_t nframes, void *arg)
00677 {
00678 (void)nframes;
00679 (void)arg;
00680 TRACE("the sample rate is now %lu/sec\n", (long)nframes);
00681 return 0;
00682 }
00683
00684
00685
00686
00687
00688
00689 void JACK_shutdown(void* arg)
00690 {
00691 jack_driver_t* drv = (jack_driver_t*)arg;
00692
00693 drv->client = 0;
00694 drv->jackd_died = TRUE;
00695
00696 TRACE("jack shutdown, setting client to 0 and jackd_died to true\n");
00697 TRACE("trying to reconnect right now\n");
00698
00699
00700 if (JACK_OpenDevice(drv) != ERR_SUCCESS)
00701 {
00702 ERR("unable to reconnect with jack\n");
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711
00712 static void JACK_Error(const char *desc)
00713 {
00714 ERR("%s\n", desc);
00715 }
00716
00717
00718 #if 0
00719
00720
00721
00722
00723 static bool JACK_SendMessage(jack_driver_t* this, enum cmd_enum command, long data)
00724 {
00725 message_t *newMessage;
00726 message_t **m;
00727
00728 newMessage = (message_t*)malloc(sizeof(message_t));
00729 if (!newMessage)
00730 {
00731 ERR("error allocating new message\n");
00732 return FALSE;
00733 }
00734
00735 newMessage->command = command;
00736 newMessage->data = data;
00737 newMessage->pNext = 0;
00738
00739
00740
00741
00742 for(m = &(drv->pMessages); *m; m = &((*m)->pNext));
00743 *m = newMessage;
00744
00745 return TRUE;
00746 }
00747 #endif
00748
00749
00750
00751
00752
00753
00754
00755 static int JACK_OpenDevice(jack_driver_t* drv)
00756 {
00757 const char** ports;
00758 unsigned int i;
00759 char client_name[64];
00760 int failed = 0;
00761
00762 TRACE("creating jack client and setting up callbacks\n");
00763
00764 #if JACK_CLOSE_HACK
00765
00766 if (drv->client)
00767 {
00768
00769 if (drv->in_use)
00770 return ERR_OPENING_JACK;
00771
00772 TRACE("using existing client\n");
00773 drv->in_use = TRUE;
00774 return ERR_SUCCESS;
00775 }
00776 #endif
00777
00778
00779 drv->sound_buffer = 0;
00780 drv->buffer_size = 0;
00781 drv->playptr_offset = 0;
00782
00783
00784 jack_set_error_function(JACK_Error);
00785
00786
00787 snprintf(client_name, sizeof(client_name), "bio2jack_%d_%d", 0, getpid());
00788 TRACE("client name '%s'\n", client_name);
00789 if ((drv->client = jack_client_new(client_name)) == 0)
00790 {
00791
00792 TRACE("trying once more to jack_client_new");
00793 if ((drv->client = jack_client_new(client_name)) == 0)
00794 {
00795 ERR("jack server not running?\n");
00796 return ERR_OPENING_JACK;
00797 }
00798 }
00799
00800 TRACE("setting up jack callbacks\n");
00801
00802
00803
00804 jack_set_process_callback(drv->client, JACK_callback, drv);
00805
00806
00807 jack_set_buffer_size_callback(drv->client, JACK_bufsize, drv);
00808
00809
00810
00811 jack_set_sample_rate_callback(drv->client, JACK_srate, drv);
00812
00813
00814
00815
00816 jack_on_shutdown(drv->client, JACK_shutdown, drv);
00817
00818
00819
00820
00821 drv->sample_rate = jack_get_sample_rate(drv->client);
00822 TRACE("engine sample rate: %lu\n", drv->sample_rate);
00823
00824
00825 TRACE("creating output ports\n");
00826 for(i = 0; i < drv->num_output_channels; i++)
00827 {
00828 char portname[32];
00829 sprintf(portname, "out_%d", i);
00830 TRACE("port %d is named '%s'\n", i, portname);
00831
00832
00833 drv->output_port[i] = jack_port_register(drv->client, portname,
00834 JACK_DEFAULT_AUDIO_TYPE,
00835 JackPortIsOutput,
00836 0);
00837 }
00838
00839
00840 JACK_bufsize(jack_get_buffer_size(drv->client), drv);
00841
00842 #if JACK_CLOSE_HACK
00843 drv->in_use = TRUE;
00844 #endif
00845
00846
00847 TRACE("calling jack_activate()\n");
00848 if (jack_activate(drv->client))
00849 {
00850 ERR( "cannot activate client\n");
00851 return ERR_OPENING_JACK;
00852 }
00853
00854
00855 if ((drv->jack_port_name_count == 0) || (drv->jack_port_name_count == 1))
00856 {
00857 if (drv->jack_port_name_count == 0)
00858 {
00859 TRACE("jack_get_ports() passing in NULL/NULL\n");
00860 ports = jack_get_ports(drv->client, NULL, NULL, drv->jack_port_flags);
00861 }
00862 else
00863 {
00864 TRACE("jack_get_ports() passing in port of '%s'\n", drv->jack_port_name[0]);
00865 ports = jack_get_ports(drv->client, drv->jack_port_name[0], NULL, drv->jack_port_flags);
00866 }
00867
00868
00869 if (ports) {
00870 for(i = 0; ports[i]; i++)
00871 TRACE("ports[%d] = '%s'\n", i, ports[i]);
00872 } else {
00873 i = 0;
00874 }
00875
00876
00877 if (i < drv->num_output_channels)
00878 {
00879 TRACE("ERR: jack_get_ports() failed to find ports with jack port flags of 0x%lX'\n", drv->jack_port_flags);
00880 JACK_CloseDevice(drv, TRUE);
00881 return ERR_PORT_NOT_FOUND;
00882 }
00883
00884
00885
00886 for(i = 0; i < drv->num_output_channels; i++)
00887 {
00888 TRACE("jack_connect() to port %d('%p')\n", i, drv->output_port[i]);
00889 if (jack_connect(drv->client, jack_port_name(drv->output_port[i]), ports[i]))
00890 {
00891 ERR("cannot connect to output port %d('%s')\n", i, ports[i]);
00892 failed = 1;
00893 }
00894 }
00895
00896 free(ports);
00897 } else
00898 {
00899 for(i = 0; i < drv->jack_port_name_count; i++)
00900 {
00901 TRACE("jack_get_ports() portname %d of '%s\n", i, drv->jack_port_name[i]);
00902 ports = jack_get_ports(drv->client, drv->jack_port_name[i], NULL, drv->jack_port_flags);
00903
00904 if (!ports)
00905 {
00906 ERR("jack_get_ports() failed to find ports with jack port flags of 0x%lX'\n", drv->jack_port_flags);
00907 return ERR_PORT_NOT_FOUND;
00908 }
00909 TRACE("ports[%d] = '%s'\n", 0, ports[0]);
00910
00911
00912 TRACE("jack_connect() to port %d('%p')\n", i, drv->output_port[i]);
00913 if (jack_connect(drv->client, jack_port_name(drv->output_port[i]), ports[0]))
00914 {
00915 ERR("cannot connect to output port %d('%s')\n", 0, ports[0]);
00916 failed = 1;
00917 }
00918 free(ports);
00919 }
00920 }
00921
00922
00923 if (failed)
00924 {
00925 TRACE("failed, closing and returning error\n");
00926 JACK_CloseDevice(drv, TRUE);
00927 return ERR_OPENING_JACK;
00928 }
00929
00930 TRACE("success\n");
00931
00932 drv->jackd_died = FALSE;
00933
00934 return ERR_SUCCESS;
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 #if JACK_CLOSE_HACK
00946 static void JACK_CloseDevice(jack_driver_t* drv, bool close_client)
00947 #else
00948 static void JACK_CloseDevice(jack_driver_t* drv)
00949 #endif
00950 {
00951 unsigned int i;
00952
00953 #if JACK_CLOSE_HACK
00954 if (close_client)
00955 {
00956 #endif
00957 TRACE("closing the jack client thread\n");
00958 if (drv->client)
00959 {
00960
00961
00962 TRACE("after jack_deactivate()\n");
00963 jack_client_close(drv->client);
00964 }
00965
00966 JACK_ResetFromDriver(drv);
00967 drv->client = 0;
00968 free(drv->sound_buffer);
00969 drv->sound_buffer = 0;
00970 drv->buffer_size = 0;
00971
00972
00973 TRACE("freeing up port strings\n");
00974 if (drv->jack_port_name_count > 1)
00975 {
00976 for(i = 0; i < drv->jack_port_name_count; i++)
00977 free(drv->jack_port_name[i]);
00978 free(drv->jack_port_name);
00979 }
00980 #if JACK_CLOSE_HACK
00981 } else
00982 {
00983 TRACE("setting in_use to FALSE\n");
00984 drv->in_use = FALSE;
00985
00986 if (!drv->client)
00987 {
00988 TRACE("critical error, closing a device that has no client\n");
00989 }
00990 }
00991 #endif
00992 }
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 static void JACK_ResetFromDriver(jack_driver_t *drv)
01004 {
01005 TRACE("resetting drv->deviceID(%d)\n", drv->deviceID);
01006
01007
01008
01009
01010 drv->state = RESET;
01011 }
01012
01013
01014 void JACK_Reset(int deviceID)
01015 {
01016 jack_driver_t *drv = getDriver(deviceID);
01017 TRACE("resetting deviceID(%d)\n", deviceID);
01018 JACK_ResetFromDriver(drv);
01019 releaseDriver(drv);
01020 }
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 int JACK_Open(int* deviceID, unsigned int bits_per_channel, unsigned long *rate, int channels)
01034 {
01035
01036 return JACK_OpenEx(deviceID, bits_per_channel, rate, channels, channels,
01037 NULL, 0, JackPortIsPhysical);
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 int JACK_OpenEx(int* deviceID, unsigned int bits_per_channel,
01050 unsigned long *rate,
01051 unsigned int input_channels, unsigned int output_channels,
01052 const char** jack_port_name,
01053 unsigned int jack_port_name_count,
01054 unsigned long jack_port_flags)
01055 {
01056 jack_driver_t *drv = getDriver(first_free_device);
01057 unsigned int i;
01058 int retval;
01059
01060 TRACE("bits_per_channel=%d rate=%ld, input_channels=%d, output_channels=%d\n",
01061 bits_per_channel, *rate, input_channels, output_channels);
01062
01063 if (output_channels > MAX_OUTPUT_PORTS)
01064 {
01065 ERR("output_channels == %d, MAX_OUTPUT_PORTS == %d\n", output_channels, MAX_OUTPUT_PORTS);
01066 releaseDriver(drv);
01067 return ERR_TOO_MANY_OUTPUT_CHANNELS;
01068 }
01069
01070 jack_port_flags|=JackPortIsInput;
01071
01072
01073 if ((jack_port_name_count > 1) && (jack_port_name_count != output_channels))
01074 {
01075 ERR("specified individual port names but not enough, gave %d names, need %d\n",
01076 jack_port_name_count, output_channels);
01077 releaseDriver(drv);
01078 return ERR_PORT_NAME_OUTPUT_CHANNEL_MISMATCH;
01079 } else
01080 {
01081
01082 drv->jack_port_flags = jack_port_flags;
01083 drv->jack_port_name_count = jack_port_name_count;
01084
01085 if (drv->jack_port_name_count != 0)
01086 {
01087 drv->jack_port_name = (char**)malloc(sizeof(char*) * drv->jack_port_name_count);
01088 for(i = 0; i < drv->jack_port_name_count; i++)
01089 {
01090 drv->jack_port_name[i] = strdup(jack_port_name[i]);
01091 TRACE("jack_port_name[%d] == '%s'\n", i, jack_port_name[i]);
01092 }
01093 }
01094 else
01095 {
01096 drv->jack_port_name = NULL;
01097 TRACE("jack_port_name = NULL\n");
01098 }
01099 }
01100
01101
01102 drv->in_use = FALSE;
01103
01104 JACK_ResetFromDriver(drv);
01105
01106
01107 drv->bits_per_channel = bits_per_channel;
01108 drv->num_input_channels = input_channels;
01109 drv->num_output_channels = output_channels;
01110 drv->bytes_per_input_frame = (drv->bits_per_channel*drv->num_input_channels)/8;
01111 drv->bytes_per_output_frame = (drv->bits_per_channel*drv->num_output_channels)/8;
01112
01113 TRACE("bytes_per_output_frame == %ld\n", drv->bytes_per_output_frame);
01114 TRACE("bytes_per_input_frame == %ld\n", drv->bytes_per_input_frame);
01115
01116
01117 if (!drv->bytes_per_output_frame)
01118 {
01119 ERR("bytes_per_output_frame is zero\n");
01120 releaseDriver(drv);
01121 return ERR_BYTES_PER_OUTPUT_FRAME_INVALID;
01122 }
01123
01124
01125 retval = JACK_OpenDevice(drv);
01126 if (retval != ERR_SUCCESS)
01127 {
01128 TRACE("error opening jack device\n");
01129 releaseDriver(drv);
01130 return retval;
01131 } else
01132 {
01133 TRACE("succeeded opening jack device\n");
01134 }
01135
01136
01137 if ((long)(*rate) != drv->sample_rate)
01138 {
01139 TRACE("rate of %ld doesn't match jack sample rate of %ld, returning error\n",
01140 *rate, drv->sample_rate);
01141 *rate = drv->sample_rate;
01142 JACK_CloseDevice(drv, TRUE);
01143 releaseDriver(drv);
01144 return ERR_RATE_MISMATCH;
01145 }
01146
01147 first_free_device++;
01148
01149 TRACE("sizeof(sample_t) == %d\n", sizeof(sample_t));
01150
01151 drv->latencyMS = 10;
01152
01153 TRACE("drv->latencyMS == %ldms\n", drv->latencyMS);
01154
01155 *deviceID = drv->deviceID;
01156 releaseDriver(drv);
01157 return ERR_SUCCESS;
01158 }
01159
01160
01161
01162
01163 int JACK_Close(int deviceID)
01164 {
01165 jack_driver_t* drv = getDriver(deviceID);
01166
01167 TRACE("deviceID(%d)\n", deviceID);
01168
01169 #if JACK_CLOSE_HACK
01170 JACK_CloseDevice(drv, TRUE);
01171 #else
01172 JACK_CloseDevice(drv);
01173 #endif
01174
01175 JACK_ResetFromDriver(drv);
01176
01177 first_free_device--;
01178
01179 releaseDriver(drv);
01180 return 0;
01181 }
01182
01183
01184
01185
01186
01187
01188
01189 long JACK_Write(int deviceID, unsigned char *data, unsigned long bytes)
01190 {
01191 jack_driver_t *drv = getDriver(deviceID);
01192 wave_header_t *newWaveHeader;
01193 wave_header_t **wh;
01194 struct timeval now;
01195 long bytes_free;
01196
01197 TRACE("deviceID(%d), bytes == %ld\n", deviceID, bytes);
01198
01199 gettimeofday(&now, 0);
01200 TRACE("Starting Time = %ld.%ld\n", now.tv_sec, now.tv_usec);
01201
01202
01203 bytes_free = JACK_GetBytesFreeSpaceFromDriver(drv);
01204 TRACE("bytes free == %ld\n", bytes_free);
01205 if ((long)bytes > bytes_free)
01206 {
01207 bytes = 0;
01208 }
01209
01210
01211 if (bytes == 0)
01212 {
01213 releaseDriver(drv);
01214 return 0;
01215 }
01216
01217 newWaveHeader = (wave_header_t*)malloc(sizeof(wave_header_t));
01218 if (!newWaveHeader)
01219 {
01220 ERR("error allocating memory for newWaveHeader\n");
01221 releaseDriver(drv);
01222 return 0;
01223 }
01224
01225 newWaveHeader->pData = (unsigned char*)malloc(sizeof(unsigned char) * bytes);
01226 memcpy(newWaveHeader->pData, data, sizeof(unsigned char) * bytes);
01227 newWaveHeader->size = bytes;
01228 newWaveHeader->pNext = 0;
01229
01230
01231
01232
01233 for(wh = &(drv->pPlayPtr); *wh; wh = &((*wh)->pNext));
01234 *wh = newWaveHeader;
01235
01236 drv->client_bytes += bytes;
01237
01238 if (!drv->pPlayPtr)
01239 {
01240 drv->pPlayPtr = newWaveHeader;
01241 drv->playptr_offset = 0;
01242 }
01243
01244
01245 if (drv->state == STOPPED)
01246 {
01247 TRACE("currently STOPPED, transitioning to PLAYING\n");
01248 drv->state = PLAYING;
01249 }
01250
01251 gettimeofday(&now, 0);
01252 TRACE("Ending Time = %ld.%ld\n", now.tv_sec, now.tv_usec);
01253
01254 TRACE("returning bytes written of %ld\n", bytes);
01255
01256 releaseDriver(drv);
01257 return bytes;
01258 }
01259
01260 #if 0
01261
01262 static void JACK_exit(int deviceID)
01263 {
01264 jack_driver_t* this = getDriver(deviceID);
01265
01266 TRACE("deviceID(%d)\n", deviceID);
01267
01268 JACK_CloseDevice(drv, TRUE);
01269 releaseDriver(drv);
01270 }
01271 #endif
01272
01273
01274
01275 static int JACK_SetVolumeForChannelFromDriver(jack_driver_t *drv,
01276 unsigned int channel,
01277 unsigned int volume)
01278 {
01279
01280 if (channel > (drv->num_output_channels - 1))
01281 {
01282 return 1;
01283 }
01284
01285 if (volume > 100) volume = 100;
01286
01287 drv->volume[channel] = volume;
01288 return ERR_SUCCESS;
01289 }
01290
01291
01292 int JACK_SetVolumeForChannel(int deviceID, unsigned int channel, unsigned int volume)
01293 {
01294 jack_driver_t *drv = getDriver(deviceID);
01295 int retval = JACK_SetVolumeForChannelFromDriver(drv, channel, volume);
01296 releaseDriver(drv);
01297 return retval;
01298 }
01299
01300
01301
01302
01303 int JACK_SetAllVolume(int deviceID, unsigned int volume)
01304 {
01305 jack_driver_t *drv = getDriver(deviceID);
01306 unsigned int i;
01307
01308 TRACE("deviceID(%d), setting volume of %d\n", deviceID, volume);
01309
01310 for(i = 0; i < drv->num_output_channels; i++)
01311 {
01312 if (JACK_SetVolumeForChannelFromDriver(drv, i, volume) != ERR_SUCCESS)
01313 {
01314 releaseDriver(drv);
01315 return 1;
01316 }
01317 }
01318
01319 releaseDriver(drv);
01320 return ERR_SUCCESS;
01321 }
01322
01323
01324
01325 void JACK_GetVolumeForChannel(int deviceID, unsigned int channel, unsigned int *volume)
01326 {
01327 jack_driver_t *drv = getDriver(deviceID);
01328
01329 if (volume) *volume = drv->volume[channel];
01330
01331 #if VERBOSE_OUTPUT
01332 if (volume)
01333 {
01334 TRACE("deviceID(%d), returning volume of %d for channel %d\n", deviceID, *volume, channel);
01335 } else
01336 {
01337 TRACE("volume is null, can't dereference it\n");
01338 }
01339 #endif
01340
01341 releaseDriver(drv);
01342 }
01343
01344
01345
01346
01347
01348 enum JACK_VOLUME_TYPE JACK_SetVolumeEffectType(int deviceID, enum JACK_VOLUME_TYPE type)
01349 {
01350 enum JACK_VOLUME_TYPE retval;
01351 jack_driver_t *drv = getDriver(deviceID);
01352
01353 TRACE("setting type of '%s'\n",
01354 (type == dbAttenuation ? "dbAttenuation" : "linear"));
01355
01356 retval = drv->volumeEffectType;
01357 drv->volumeEffectType = type;
01358
01359 releaseDriver(drv);
01360 return retval;
01361 }
01362
01363
01364
01365 int JACK_SetState(int deviceID, enum status_enum state)
01366 {
01367 jack_driver_t *drv = getDriver(deviceID);
01368
01369 switch (state) {
01370 case PAUSED:
01371 drv->state = PAUSED;
01372 break;
01373 case PLAYING:
01374 drv->state = PLAYING;
01375 break;
01376 case STOPPED:
01377 drv->state = STOPPED;
01378 break;
01379 default:
01380 TRACE("unknown state of %d\n", state);
01381 }
01382
01383 TRACE("%s\n", DEBUGSTATE(drv->state));
01384
01385 releaseDriver(drv);
01386 return 0;
01387 }
01388
01389
01390 enum status_enum JACK_GetState(int deviceID)
01391 {
01392 jack_driver_t *drv = getDriver(deviceID);
01393 enum status_enum return_val;
01394
01395 return_val = drv->state;
01396 releaseDriver(drv);
01397
01398 TRACE("deviceID(%d), returning current state of %s\n", deviceID, DEBUGSTATE(return_val));
01399 return return_val;
01400 }
01401
01402
01403 long JACK_GetOutputBytesPerSecond(int deviceID)
01404 {
01405 jack_driver_t *drv = getDriver(deviceID);
01406 long return_val;
01407
01408 return_val = drv->bytes_per_output_frame * drv->sample_rate;
01409 releaseDriver(drv);
01410
01411 #if VERBOSE_OUTPUT
01412 TRACE("deviceID(%d), return_val = %ld\n", deviceID, return_val);
01413 #endif
01414
01415 return return_val;
01416 }
01417
01418
01419 static long JACK_GetInputBytesPerSecondFromDriver(jack_driver_t *drv)
01420 {
01421 long return_val;
01422
01423 return_val = drv->bytes_per_input_frame * drv->sample_rate;
01424 #if VERBOSE_OUTPUT
01425 TRACE("drv->deviceID(%d), return_val = %ld\n", drv->deviceID, return_val);
01426 #endif
01427
01428 return return_val;
01429 }
01430
01431
01432 long JACK_GetInputBytesPerSecond(int deviceID)
01433 {
01434 jack_driver_t *drv = getDriver(deviceID);
01435 long return_val = JACK_GetInputBytesPerSecondFromDriver(drv);
01436 releaseDriver(drv);
01437
01438 #if VERBOSE_OUTPUT
01439 TRACE("deviceID(%d), return_val = %ld\n", deviceID, return_val);
01440 #endif
01441
01442 return return_val;
01443 }
01444
01445
01446
01447
01448 static long JACK_GetBytesStoredFromDriver(jack_driver_t *drv)
01449 {
01450 long return_val;
01451
01452
01453
01454
01455 return_val = (drv->client_bytes -
01456 (JACK_GetPositionFromDriver(drv, BYTES, PLAYED)
01457 - drv->position_byte_offset));
01458
01459 if (return_val < 0) return_val = 0;
01460
01461 TRACE("drv->deviceID(%d), return_val = %ld\n", drv->deviceID, return_val);
01462
01463 return return_val;
01464 }
01465
01466
01467
01468
01469
01470
01471 long JACK_GetBytesStored(int deviceID)
01472 {
01473 jack_driver_t *drv = getDriver(deviceID);
01474 long retval = JACK_GetBytesStoredFromDriver(drv);
01475 releaseDriver(drv);
01476 TRACE("deviceID(%d), retval = %ld\n", deviceID, retval);
01477 return retval;
01478 }
01479
01480 static long JACK_GetBytesFreeSpaceFromDriver(jack_driver_t *drv)
01481 {
01482 return MAX_BUFFERED_BYTES - (drv->client_bytes - drv->played_client_bytes);
01483 }
01484
01485
01486 long JACK_GetBytesFreeSpace(int deviceID)
01487 {
01488 jack_driver_t *drv = getDriver(deviceID);
01489 long return_val;
01490
01491 return_val = JACK_GetBytesFreeSpaceFromDriver(drv);
01492 releaseDriver(drv);
01493
01494 if (return_val < 0) return_val = 0;
01495 TRACE("deviceID(%d), JACK_GetFreeSpacesFromDriver(deviceID) == %ld\n", deviceID, return_val);
01496
01497 return return_val;
01498 }
01499
01500
01501
01502
01503 static long JACK_GetPositionFromDriver(jack_driver_t *drv, enum pos_enum position, int type)
01504 {
01505 long return_val = 0;
01506 struct timeval now;
01507 long elapsedMS;
01508 double sec2msFactor = 1000;
01509
01510 char *type_str = "UNKNOWN type";
01511
01512
01513 if (drv->state == RESET)
01514 {
01515 TRACE("we are currently RESET, returning 0\n");
01516 return 0;
01517 }
01518
01519 if (type == WRITTEN)
01520 {
01521 type_str = "WRITTEN";
01522 return_val = drv->client_bytes;
01523 }
01524 else if (type == WRITTEN_TO_JACK)
01525 {
01526 type_str = "WRITTEN_TO_JACK";
01527 return_val = drv->written_client_bytes;
01528 }
01529 else if (type == PLAYED)
01530 {
01531 type_str = "PLAYED";
01532 return_val = drv->played_client_bytes;
01533 gettimeofday(&now, 0);
01534
01535 elapsedMS = TimeValDifference(&drv->previousTime, &now);
01536
01537 TRACE("elapsedMS since last callback is '%ld'\n", elapsedMS);
01538
01539
01540
01541
01542
01543 if (drv->clientBytesInJack != 0)
01544 {
01545 return_val+=(long)((double)elapsedMS * ((double)JACK_GetInputBytesPerSecondFromDriver(drv) / sec2msFactor));
01546 } else
01547 {
01548 TRACE("clientBytesInJack == 0\n");
01549 }
01550 }
01551
01552
01553 return_val+=drv->position_byte_offset;
01554
01555
01556 if (position == MILLISECONDS)
01557 {
01558 if (JACK_GetInputBytesPerSecondFromDriver(drv) != 0)
01559 return_val = (long)(((double)return_val / (double)JACK_GetInputBytesPerSecondFromDriver(drv)) * (double)sec2msFactor);
01560 else
01561 return_val = 0;
01562 }
01563
01564 TRACE("drv->deviceID(%d), type(%s), return_val = %ld\n", drv->deviceID, type_str, return_val);
01565
01566 return return_val;
01567 }
01568
01569
01570
01571
01572 long JACK_GetPosition(int deviceID, enum pos_enum position, int type)
01573 {
01574 jack_driver_t *drv = getDriver(deviceID);
01575 long retval = JACK_GetPositionFromDriver(drv, position, type);
01576 releaseDriver(drv);
01577 TRACE("retval == %ld\n", retval);
01578 return retval;
01579 }
01580
01581
01582
01583
01584
01585
01586
01587 void JACK_SetPositionFromDriver(jack_driver_t *drv, enum pos_enum position, long value)
01588 {
01589 double sec2msFactor = 1000;
01590 #if TRACE_ENABLE
01591 long input_value = value;
01592 #endif
01593
01594
01595 if (position == MILLISECONDS)
01596 value = (long)(((double)value*(double)JACK_GetInputBytesPerSecondFromDriver(drv)) / sec2msFactor);
01597
01598
01599
01600 drv->position_byte_offset = value - drv->client_bytes;
01601
01602 TRACE("deviceID(%d) input_value of %ld, new value of %ld, setting position_byte_offset to %ld\n",
01603 drv->deviceID, input_value, value, drv->position_byte_offset);
01604 }
01605
01606
01607
01608
01609
01610
01611 void JACK_SetPosition(int deviceID, enum pos_enum position, long value)
01612 {
01613 jack_driver_t *drv = getDriver(deviceID);
01614 JACK_SetPositionFromDriver(drv, position, value);
01615 releaseDriver(drv);
01616
01617 TRACE("deviceID(%d) value of %ld\n",
01618 drv->deviceID, value);
01619 }
01620
01621
01622 long JACK_GetBytesPerOutputFrame(int deviceID)
01623 {
01624 jack_driver_t *drv = getDriver(deviceID);
01625 long return_val = drv->bytes_per_output_frame;
01626 releaseDriver(drv);
01627 TRACE("deviceID(%d), return_val = %ld\n", deviceID, return_val);
01628 return return_val;
01629 }
01630
01631
01632 long JACK_GetMaxBufferedBytes(int deviceID)
01633 {
01634 long return_val;
01635 (void)deviceID;
01636
01637 return_val = MAX_BUFFERED_BYTES;
01638 TRACE("getting MAX_BUFFERED_BYTES of %ld\n", return_val);
01639
01640 return return_val;
01641 }
01642
01643
01644 void JACK_SetMaxBufferedBytes(int deviceID, long max_buffered_bytes)
01645 {
01646 (void)deviceID;
01647 TRACE("setting MAX_BUFFERED_BYTES to %ld, from %ld\n", max_buffered_bytes, MAX_BUFFERED_BYTES);
01648 MAX_BUFFERED_BYTES = (unsigned long) max_buffered_bytes;
01649 }
01650
01651
01652 int JACK_GetNumOutputChannels(int deviceID)
01653 {
01654 jack_driver_t *drv = getDriver(deviceID);
01655 int return_val = drv->num_output_channels;
01656 releaseDriver(drv);
01657 TRACE("getting num_output_channels of %d\n", return_val);
01658 return return_val;
01659 }
01660
01661
01662 int JACK_GetNumInputChannels(int deviceID)
01663 {
01664 jack_driver_t *drv = getDriver(deviceID);
01665 int return_val = drv->num_input_channels;
01666 releaseDriver(drv);
01667 TRACE("getting num_input_channels of %d\n", return_val);
01668 return return_val;
01669 }
01670
01671 int JACK_SetNumOutputChannels(int deviceID, int channels)
01672 {
01673 (void)deviceID;
01674 (void)channels;
01675
01676
01677 return 1;
01678 }
01679
01680
01681 int JACK_SetNumInputChannels(int deviceID, int channels)
01682 {
01683 jack_driver_t *drv = getDriver(deviceID);
01684 int return_val = drv->num_input_channels;
01685 #if TRACE_ENABLE
01686 int bpif = drv->bytes_per_input_frame;
01687 #endif
01688
01689 long positionMS = JACK_GetPositionFromDriver(drv, MILLISECONDS, PLAYED);
01690
01691 drv->num_input_channels = channels;
01692 drv->bytes_per_input_frame = (drv->bits_per_channel*drv->num_input_channels)/8;
01693
01694 JACK_SetPositionFromDriver(drv, MILLISECONDS, positionMS);
01695
01696 releaseDriver(drv);
01697
01698 TRACE("changing num_input_channels from '%d' to '%d'\n", return_val, channels);
01699 TRACE("bytes_per_input_frame changed from '%d' to '%ld'\n", bpif, drv->bytes_per_input_frame);
01700
01701 return return_val;
01702 }
01703
01704
01705 long JACK_GetSampleRate(int deviceID)
01706 {
01707 jack_driver_t *drv = getDriver(deviceID);
01708 int return_val = drv->sample_rate;
01709 releaseDriver(drv);
01710 TRACE("getting sample_rate of %d\n", return_val);
01711 return return_val;
01712 }
01713
01714
01715 void JACK_Init(void)
01716 {
01717 jack_driver_t *drv;
01718 int x, y;
01719
01720 TRACE("\n");
01721
01722 for(x = 0; x < MAX_OUTDEVICES; x++)
01723 {
01724 drv = &outDev[x];
01725
01726 JACK_Reset(x);
01727
01728 drv->deviceID = x;
01729 drv->client = 0;
01730 drv->in_use = FALSE;
01731 for(y = 0; y < MAX_OUTPUT_PORTS; y++)
01732 drv->volume[y] = 25;
01733 drv->volumeEffectType = linear;
01734 drv->state = CLOSED;
01735 drv->bytes_per_output_frame = 0;
01736 drv->bytes_per_input_frame = 0;
01737 drv->sample_rate = 0;
01738 drv->pMessages = 0;
01739 drv->position_byte_offset = 0;
01740 gettimeofday(&drv->previousTime, 0);
01741
01742 drv->jackd_died = FALSE;
01743 gettimeofday(&drv->last_reconnect_attempt, 0);
01744
01745 pthread_mutex_init(&drv->mutex, NULL);
01746 }
01747
01748 TRACE("finished\n");
01749 }
01750
01751
01752 long JACK_GetJackLatency(int deviceID)
01753 {
01754 jack_driver_t *drv = getDriver(deviceID);
01755 long return_val;
01756
01757 return_val = jack_port_get_total_latency(drv->client, drv->output_port[0]);
01758 TRACE("got latency of %ldms\n", return_val);
01759
01760 releaseDriver(drv);
01761 return return_val;
01762 }
01763
01764 unsigned long JACK_GetJackBufferedBytes(int deviceID)
01765 {
01766 jack_driver_t *drv = getDriver(deviceID);
01767 long return_val;
01768
01769 return_val = drv->buffer_size;
01770
01771 releaseDriver(drv);
01772 return return_val;
01773 }
01774
01775
01776
01777 #if 0
01778 bool test_sample_move_d16_d16(void)
01779 {
01780
01781 short buffer[4];
01782 short buffer2[8];
01783 buffer[0] = 1;
01784 buffer[1] = 10;
01785 buffer[2] = 20;
01786 buffer[3] = 40;
01787 sample_move_d16_d16(buffer2, buffer, 2, 4, 2);
01788
01789 if (buffer[0] != buffer2[0])
01790 TRACE("error, buffer[0] != buffer2[0]\n");
01791 if (buffer[1] != buffer2[1])
01792 TRACE("error, buffer[1] != buffer2[1]\n");
01793 if (buffer[0] != buffer2[2])
01794 TRACE("error, buffer[0] != buffer2[2]\n");
01795 if (buffer[1] != buffer2[3])
01796 TRACE("error, buffer[1] != buffer2[3]\n");
01797
01798 if (buffer[2] != buffer2[4])
01799 TRACE("error, buffer[2] != buffer2[4]\n");
01800 if (buffer[3] != buffer2[5])
01801 TRACE("error, buffer[3] != buffer2[5]\n");
01802 if (buffer[2] != buffer2[6])
01803 TRACE("error, buffer[2] != buffer2[6]\n");
01804 if (buffer[3] != buffer2[7])
01805 TRACE("error, buffer[3] != buffer2[7]\n");
01806
01807 return TRUE;
01808 }
01809 #endif