git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4252 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
| @@ -1,4 +1,4 @@ | |||||
| /** @file simple_client.c | |||||
| /** @file latent_client.c | |||||
| * | * | ||||
| * @brief This simple client demonstrates the most basic features of JACK | * @brief This simple client demonstrates the most basic features of JACK | ||||
| * as they would be used by many applications. | * as they would be used by many applications. | ||||
| @@ -8,7 +8,7 @@ | |||||
| #include <errno.h> | #include <errno.h> | ||||
| #include <unistd.h> | #include <unistd.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | |||||
| #include <string.h> | |||||
| #include <inttypes.h> | #include <inttypes.h> | ||||
| #include <jack/jack.h> | #include <jack/jack.h> | ||||
| @@ -19,12 +19,12 @@ jack_client_t *client; | |||||
| jack_default_audio_sample_t *delay_line; | jack_default_audio_sample_t *delay_line; | ||||
| jack_nframes_t delay_index; | jack_nframes_t delay_index; | ||||
| jack_nframes_t latency = 1024; | |||||
| #ifdef WIN32 | |||||
| #define jack_sleep(val) Sleep((val)) | |||||
| #else | |||||
| #define jack_sleep(val) usleep((val) * 1000) | |||||
| jack_nframes_t latency = 1024; | |||||
| #ifdef WIN32 | |||||
| #define jack_sleep(val) Sleep((val)) | |||||
| #else | |||||
| #define jack_sleep(val) usleep((val) * 1000) | |||||
| #endif | #endif | ||||
| /** | /** | ||||
| @@ -213,3 +213,4 @@ main (int argc, char *argv[]) | |||||
| jack_client_close (client); | jack_client_close (client); | ||||
| exit (0); | exit (0); | ||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| /** @file simple_client.c | |||||
| /** @file thru_client.c | |||||
| * | * | ||||
| * @brief This simple through client demonstrates the basic features of JACK | * @brief This simple through client demonstrates the basic features of JACK | ||||
| * as they would be used by many applications. | * as they would be used by many applications. | ||||
| @@ -1,4 +1,4 @@ | |||||
| /** @file simple_client.c | |||||
| /** @file tw.c | |||||
| * | * | ||||
| * @brief This simple client demonstrates the basic features of JACK | * @brief This simple client demonstrates the basic features of JACK | ||||
| * as they would be used by many applications. | * as they would be used by many applications. | ||||
| @@ -42,56 +42,56 @@ _process (jack_nframes_t nframes) | |||||
| { | { | ||||
| jack_default_audio_sample_t *in, *out; | jack_default_audio_sample_t *in, *out; | ||||
| jack_transport_state_t ts = jack_transport_query(client, NULL); | jack_transport_state_t ts = jack_transport_query(client, NULL); | ||||
| if (ts == JackTransportRolling) { | if (ts == JackTransportRolling) { | ||||
| if (client_state == Init) | if (client_state == Init) | ||||
| client_state = Run; | client_state = Run; | ||||
| in = jack_port_get_buffer (input_port, nframes); | in = jack_port_get_buffer (input_port, nframes); | ||||
| out = jack_port_get_buffer (output_port, nframes); | out = jack_port_get_buffer (output_port, nframes); | ||||
| memcpy (out, in, | memcpy (out, in, | ||||
| sizeof (jack_default_audio_sample_t) * nframes); | sizeof (jack_default_audio_sample_t) * nframes); | ||||
| } else if (ts == JackTransportStopped) { | } else if (ts == JackTransportStopped) { | ||||
| if (client_state == Run) { | if (client_state == Run) { | ||||
| client_state = Exit; | client_state = Exit; | ||||
| return -1; // to stop the thread | return -1; // to stop the thread | ||||
| } | } | ||||
| } | } | ||||
| return 0; | |||||
| return 0; | |||||
| } | } | ||||
| static void* jack_thread(void *arg) | |||||
| static void* jack_thread(void *arg) | |||||
| { | { | ||||
| jack_client_t* client = (jack_client_t*) arg; | jack_client_t* client = (jack_client_t*) arg; | ||||
| while (1) { | while (1) { | ||||
| jack_nframes_t frames = jack_cycle_wait (client); | jack_nframes_t frames = jack_cycle_wait (client); | ||||
| int status = _process(frames); | int status = _process(frames); | ||||
| jack_cycle_signal (client, status); | jack_cycle_signal (client, status); | ||||
| /* | /* | ||||
| Possibly do something else after signaling next clients in the graph | Possibly do something else after signaling next clients in the graph | ||||
| */ | */ | ||||
| /* End condition */ | /* End condition */ | ||||
| if (status != 0) | if (status != 0) | ||||
| return 0; | |||||
| return 0; | |||||
| } | } | ||||
| /* not reached*/ | /* not reached*/ | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* | /* | ||||
| static void* jack_thread(void *arg) | |||||
| static void* jack_thread(void *arg) | |||||
| { | { | ||||
| jack_client_t* client = (jack_client_t*) arg; | jack_client_t* client = (jack_client_t*) arg; | ||||
| while (1) { | while (1) { | ||||
| jack_nframes_t frames; | jack_nframes_t frames; | ||||
| int status; | int status; | ||||
| @@ -103,7 +103,7 @@ static void* jack_thread(void *arg) | |||||
| frames = jack_cycle_wait (client); | frames = jack_cycle_wait (client); | ||||
| status = _process(frames); | status = _process(frames); | ||||
| jack_cycle_signal (client, status); | jack_cycle_signal (client, status); | ||||
| // cycle 3 | |||||
| // cycle 3 | |||||
| frames = jack_cycle_wait (client); | frames = jack_cycle_wait (client); | ||||
| status = _process(frames); | status = _process(frames); | ||||
| jack_cycle_signal (client, status); | jack_cycle_signal (client, status); | ||||
| @@ -112,7 +112,7 @@ static void* jack_thread(void *arg) | |||||
| status = _process(frames); | status = _process(frames); | ||||
| jack_cycle_signal (client, status); | jack_cycle_signal (client, status); | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| */ | */ | ||||
| @@ -172,8 +172,8 @@ main (int argc, char *argv[]) | |||||
| /* tell the JACK server to call `process()' whenever | /* tell the JACK server to call `process()' whenever | ||||
| there is work to be done. | there is work to be done. | ||||
| */ | |||||
| if (jack_set_process_thread(client, jack_thread, client) < 0) | |||||
| */ | |||||
| if (jack_set_process_thread(client, jack_thread, client) < 0) | |||||
| exit(1); | exit(1); | ||||
| /* tell the JACK server to call `jack_shutdown()' if | /* tell the JACK server to call `jack_shutdown()' if | ||||
| @@ -183,7 +183,7 @@ main (int argc, char *argv[]) | |||||
| jack_on_shutdown (client, jack_shutdown, 0); | jack_on_shutdown (client, jack_shutdown, 0); | ||||
| /* display the current sample rate. | |||||
| /* display the current sample rate. | |||||
| */ | */ | ||||
| printf ("engine sample rate: %" PRIu32 "\n", | printf ("engine sample rate: %" PRIu32 "\n", | ||||
| @@ -231,7 +231,7 @@ main (int argc, char *argv[]) | |||||
| } | } | ||||
| free (ports); | free (ports); | ||||
| ports = jack_get_ports (client, NULL, NULL, | ports = jack_get_ports (client, NULL, NULL, | ||||
| JackPortIsPhysical|JackPortIsInput); | JackPortIsPhysical|JackPortIsInput); | ||||
| if (ports == NULL) { | if (ports == NULL) { | ||||
| @@ -244,7 +244,7 @@ main (int argc, char *argv[]) | |||||
| } | } | ||||
| free (ports); | free (ports); | ||||
| /* install a signal handler to properly quits jack client */ | /* install a signal handler to properly quits jack client */ | ||||
| signal(SIGQUIT, signal_handler); | signal(SIGQUIT, signal_handler); | ||||
| signal(SIGTERM, signal_handler); | signal(SIGTERM, signal_handler); | ||||
| @@ -40,7 +40,7 @@ main (int argc, char *argv[]) | |||||
| int wait_timeout = 0; | int wait_timeout = 0; | ||||
| time_t start_timestamp; | time_t start_timestamp; | ||||
| struct option long_options[] = { | struct option long_options[] = { | ||||
| { "server", 1, 0, 's' }, | { "server", 1, 0, 's' }, | ||||
| { "wait", 0, 0, 'w' }, | { "wait", 0, 0, 'w' }, | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| Copyright (C) 2002 Jeremy Hall | Copyright (C) 2002 Jeremy Hall | ||||
| This program is free software; you can redistribute it and/or modify | This program is free software; you can redistribute it and/or modify | ||||
| it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | ||||
| the Free Software Foundation; either version 2 of the License, or | the Free Software Foundation; either version 2 of the License, or | ||||
| @@ -30,18 +30,18 @@ int count = 0; | |||||
| jack_port_t* output_port; | jack_port_t* output_port; | ||||
| static int | static int | ||||
| process(jack_nframes_t nframes, void* arg) | |||||
| process(jack_nframes_t nframes, void* arg) | |||||
| { | { | ||||
| if (count++ == 1000) { | if (count++ == 1000) { | ||||
| printf("process block\n"); | printf("process block\n"); | ||||
| //while (1) {} | //while (1) {} | ||||
| sleep(1); | sleep(1); | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| static void | |||||
| static void | |||||
| shutdown (void *arg) | shutdown (void *arg) | ||||
| { | { | ||||
| printf("shutdown \n"); | printf("shutdown \n"); | ||||
| @@ -57,7 +57,7 @@ main (int argc, char *argv[]) | |||||
| fprintf (stderr, "jack server not running?\n"); | fprintf (stderr, "jack server not running?\n"); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| jack_set_process_callback (client, process, NULL); | jack_set_process_callback (client, process, NULL); | ||||
| jack_on_shutdown(client, shutdown, NULL); | jack_on_shutdown(client, shutdown, NULL); | ||||
| output_port = jack_port_register (client, "port1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | output_port = jack_port_register (client, "port1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | ||||
| @@ -67,9 +67,9 @@ main (int argc, char *argv[]) | |||||
| fprintf (stderr, "cannot activate client"); | fprintf (stderr, "cannot activate client"); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| jack_connect(client, jack_port_name(output_port), "coreaudio:Built-in Audio:in2"); | jack_connect(client, jack_port_name(output_port), "coreaudio:Built-in Audio:in2"); | ||||
| while (running) { | while (running) { | ||||
| sleep(1); | sleep(1); | ||||
| printf ("run\n"); | printf ("run\n"); | ||||
| @@ -78,9 +78,9 @@ main (int argc, char *argv[]) | |||||
| jack_deactivate (client); | jack_deactivate (client); | ||||
| jack_client_close (client); | jack_client_close (client); | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| if (client) | |||||
| if (client) | |||||
| jack_client_close (client); | jack_client_close (client); | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| @@ -106,14 +106,14 @@ static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nfram | |||||
| case 24: { | case 24: { | ||||
| signed int *s32dst = (signed int*)dst; | signed int *s32dst = (signed int*)dst; | ||||
| s32dst += channel; | s32dst += channel; | ||||
| sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL); | |||||
| sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL); | |||||
| break; | break; | ||||
| } | |||||
| } | |||||
| case 32: { | case 32: { | ||||
| signed int *s32dst = (signed int*)dst; | signed int *s32dst = (signed int*)dst; | ||||
| s32dst += channel; | s32dst += channel; | ||||
| sample_move_d32u24_sS((char*)s32dst, src, nframes, byte_skip, NULL); | sample_move_d32u24_sS((char*)s32dst, src, nframes, byte_skip, NULL); | ||||
| break; | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -127,7 +127,7 @@ void JackBoomerDriver::SetSampleFormat() | |||||
| fSampleSize = 4; | fSampleSize = 4; | ||||
| break; | break; | ||||
| case 32: /* native-endian 32-bit integer */ | case 32: /* native-endian 32-bit integer */ | ||||
| fSampleFormat = AFMT_S32_NE; | |||||
| fSampleFormat = AFMT_S32_NE; | |||||
| fSampleSize = 4; | fSampleSize = 4; | ||||
| break; | break; | ||||
| case 16: /* native-endian 16-bit integer */ | case 16: /* native-endian 16-bit integer */ | ||||
| @@ -144,13 +144,13 @@ void JackBoomerDriver::DisplayDeviceInfo() | |||||
| oss_audioinfo ai_in, ai_out; | oss_audioinfo ai_in, ai_out; | ||||
| memset(&info, 0, sizeof(audio_buf_info)); | memset(&info, 0, sizeof(audio_buf_info)); | ||||
| int cap = 0; | int cap = 0; | ||||
| // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html | // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html | ||||
| jack_info("Audio Interface Description :"); | jack_info("Audio Interface Description :"); | ||||
| jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); | jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); | ||||
| if (fRWMode & kWrite) { | if (fRWMode & kWrite) { | ||||
| oss_sysinfo si; | oss_sysinfo si; | ||||
| if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { | if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { | ||||
| jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -162,18 +162,18 @@ void JackBoomerDriver::DisplayDeviceInfo() | |||||
| jack_info("OSS numaudioengines %d", si.numaudioengines); | jack_info("OSS numaudioengines %d", si.numaudioengines); | ||||
| jack_info("OSS numcards %d", si.numcards); | jack_info("OSS numcards %d", si.numcards); | ||||
| } | } | ||||
| jack_info("Output capabilities - %d channels : ", fPlaybackChannels); | jack_info("Output capabilities - %d channels : ", fPlaybackChannels); | ||||
| jack_info("Output block size = %d", fOutputBufferSize); | jack_info("Output block size = %d", fOutputBufferSize); | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { | ||||
| jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } else { | } else { | ||||
| jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| info.fragments, info.fragstotal, info.fragsize, info.bytes); | info.fragments, info.fragstotal, info.fragsize, info.bytes); | ||||
| fFragmentSize = info.fragsize; | fFragmentSize = info.fragsize; | ||||
| } | } | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { | ||||
| jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } else { | } else { | ||||
| @@ -186,10 +186,10 @@ void JackBoomerDriver::DisplayDeviceInfo() | |||||
| if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); | if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); | ||||
| if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| if (fRWMode & kRead) { | if (fRWMode & kRead) { | ||||
| oss_sysinfo si; | oss_sysinfo si; | ||||
| if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { | if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { | ||||
| jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -201,14 +201,14 @@ void JackBoomerDriver::DisplayDeviceInfo() | |||||
| jack_info("OSS numaudioengines %d", si.numaudioengines); | jack_info("OSS numaudioengines %d", si.numaudioengines); | ||||
| jack_info("OSS numcards %d", si.numcards); | jack_info("OSS numcards %d", si.numcards); | ||||
| } | } | ||||
| jack_info("Input capabilities - %d channels : ", fCaptureChannels); | jack_info("Input capabilities - %d channels : ", fCaptureChannels); | ||||
| jack_info("Input block size = %d", fInputBufferSize); | jack_info("Input block size = %d", fInputBufferSize); | ||||
| if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { | |||||
| if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { | |||||
| jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } else { | } else { | ||||
| jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| info.fragments, info.fragstotal, info.fragsize, info.bytes); | info.fragments, info.fragstotal, info.fragsize, info.bytes); | ||||
| } | } | ||||
| @@ -225,31 +225,30 @@ void JackBoomerDriver::DisplayDeviceInfo() | |||||
| if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | ||||
| } | } | ||||
| } | } | ||||
| if (ai_in.rate_source != ai_out.rate_source) { | if (ai_in.rate_source != ai_out.rate_source) { | ||||
| jack_info("Warning : input and output are not necessarily driven by the same clock!"); | jack_info("Warning : input and output are not necessarily driven by the same clock!"); | ||||
| } | } | ||||
| } | } | ||||
| JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | ||||
| : JackAudioDriver(name, alias, engine, table), | |||||
| fInFD(-1), fOutFD(-1), fBits(0), | |||||
| fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0), | |||||
| fRWMode(0), fExcl(false), fSyncIO(false), | |||||
| fInputBufferSize(0), fOutputBufferSize(0), | |||||
| fInputBuffer(NULL), fOutputBuffer(NULL), | |||||
| fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), | |||||
| fInputHandler(this), fOutputHandler(this) | |||||
| : JackAudioDriver(name, alias, engine, table), | |||||
| fInFD(-1), fOutFD(-1), fBits(0), | |||||
| fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0), | |||||
| fRWMode(0), fExcl(false), fSyncIO(false), | |||||
| fInputBufferSize(0), fOutputBufferSize(0), | |||||
| fInputBuffer(NULL), fOutputBuffer(NULL), | |||||
| fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), | |||||
| fInputHandler(this), fOutputHandler(this) | |||||
| { | { | ||||
| sem_init(&fReadSema, 0, 0); | |||||
| sem_init(&fWriteSema, 0, 0); | |||||
| sem_init(&fReadSema, 0, 0); | |||||
| sem_init(&fWriteSema, 0, 0); | |||||
| } | } | ||||
| JackBoomerDriver::~JackBoomerDriver() | JackBoomerDriver::~JackBoomerDriver() | ||||
| { | { | ||||
| sem_destroy(&fReadSema); | |||||
| sem_destroy(&fWriteSema); | |||||
| sem_destroy(&fReadSema); | |||||
| sem_destroy(&fWriteSema); | |||||
| } | } | ||||
| int JackBoomerDriver::OpenInput() | int JackBoomerDriver::OpenInput() | ||||
| @@ -260,8 +259,9 @@ int JackBoomerDriver::OpenInput() | |||||
| int cur_sample_format; | int cur_sample_format; | ||||
| jack_nframes_t cur_sample_rate; | jack_nframes_t cur_sample_rate; | ||||
| if (fCaptureChannels == 0) fCaptureChannels = 2; | |||||
| if (fCaptureChannels == 0) | |||||
| fCaptureChannels = 2; | |||||
| if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | ||||
| jack_error("JackBoomerDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| return -1; | return -1; | ||||
| @@ -276,7 +276,7 @@ int JackBoomerDriver::OpenInput() | |||||
| } | } | ||||
| } | } | ||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); | |||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); | |||||
| if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | ||||
| jack_error("JackBoomerDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| @@ -290,7 +290,7 @@ int JackBoomerDriver::OpenInput() | |||||
| if (cur_sample_format != fSampleFormat) { | if (cur_sample_format != fSampleFormat) { | ||||
| jack_info("JackBoomerDriver::OpenInput driver forced the sample format %ld", fSampleFormat); | jack_info("JackBoomerDriver::OpenInput driver forced the sample format %ld", fSampleFormat); | ||||
| } | } | ||||
| cur_capture_channels = fCaptureChannels; | cur_capture_channels = fCaptureChannels; | ||||
| if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { | if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { | ||||
| jack_error("JackBoomerDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -299,7 +299,7 @@ int JackBoomerDriver::OpenInput() | |||||
| if (cur_capture_channels != fCaptureChannels) { | if (cur_capture_channels != fCaptureChannels) { | ||||
| jack_info("JackBoomerDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); | jack_info("JackBoomerDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); | ||||
| } | } | ||||
| cur_sample_rate = fEngineControl->fSampleRate; | cur_sample_rate = fEngineControl->fSampleRate; | ||||
| if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { | if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { | ||||
| jack_error("JackBoomerDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -315,7 +315,7 @@ int JackBoomerDriver::OpenInput() | |||||
| fInputBuffer = (void*)calloc(fInputBufferSize, 1); | fInputBuffer = (void*)calloc(fInputBufferSize, 1); | ||||
| assert(fInputBuffer); | assert(fInputBuffer); | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| ::close(fInFD); | ::close(fInFD); | ||||
| return -1; | return -1; | ||||
| @@ -329,28 +329,29 @@ int JackBoomerDriver::OpenOutput() | |||||
| int cur_playback_channels; | int cur_playback_channels; | ||||
| jack_nframes_t cur_sample_rate; | jack_nframes_t cur_sample_rate; | ||||
| if (fPlaybackChannels == 0) fPlaybackChannels = 2; | |||||
| if (fPlaybackChannels == 0) | |||||
| fPlaybackChannels = 2; | |||||
| if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | ||||
| jack_error("JackBoomerDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| jack_log("JackBoomerDriver::OpenOutput output fOutFD = %d", fOutFD); | jack_log("JackBoomerDriver::OpenOutput output fOutFD = %d", fOutFD); | ||||
| if (fExcl) { | if (fExcl) { | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { | ||||
| jack_error("JackBoomerDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); | |||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); | |||||
| if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | ||||
| jack_error("JackBoomerDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| cur_sample_format = fSampleFormat; | cur_sample_format = fSampleFormat; | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { | ||||
| jack_error("JackBoomerDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -359,7 +360,7 @@ int JackBoomerDriver::OpenOutput() | |||||
| if (cur_sample_format != fSampleFormat) { | if (cur_sample_format != fSampleFormat) { | ||||
| jack_info("JackBoomerDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); | jack_info("JackBoomerDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); | ||||
| } | } | ||||
| cur_playback_channels = fPlaybackChannels; | cur_playback_channels = fPlaybackChannels; | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { | ||||
| jack_error("JackBoomerDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -380,33 +381,33 @@ int JackBoomerDriver::OpenOutput() | |||||
| // Just set the write size to the value we want... | // Just set the write size to the value we want... | ||||
| fOutputBufferSize = fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels; | fOutputBufferSize = fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels; | ||||
| fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); | fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); | ||||
| assert(fOutputBuffer); | assert(fOutputBuffer); | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| ::close(fOutFD); | ::close(fOutFD); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| int JackBoomerDriver::Open(jack_nframes_t nframes, | int JackBoomerDriver::Open(jack_nframes_t nframes, | ||||
| int user_nperiods, | |||||
| jack_nframes_t samplerate, | |||||
| bool capturing, | |||||
| bool playing, | |||||
| int inchannels, | |||||
| int outchannels, | |||||
| bool excl, | |||||
| bool monitor, | |||||
| const char* capture_driver_uid, | |||||
| const char* playback_driver_uid, | |||||
| jack_nframes_t capture_latency, | |||||
| jack_nframes_t playback_latency, | |||||
| int bits, bool syncio) | |||||
| int user_nperiods, | |||||
| jack_nframes_t samplerate, | |||||
| bool capturing, | |||||
| bool playing, | |||||
| int inchannels, | |||||
| int outchannels, | |||||
| bool excl, | |||||
| bool monitor, | |||||
| const char* capture_driver_uid, | |||||
| const char* playback_driver_uid, | |||||
| jack_nframes_t capture_latency, | |||||
| jack_nframes_t playback_latency, | |||||
| int bits, bool syncio) | |||||
| { | { | ||||
| // Generic JackAudioDriver Open | // Generic JackAudioDriver Open | ||||
| if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, | |||||
| if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, | |||||
| capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { | capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { | ||||
| return -1; | return -1; | ||||
| } else { | } else { | ||||
| @@ -422,12 +423,12 @@ int JackBoomerDriver::Open(jack_nframes_t nframes, | |||||
| fExcl = excl; | fExcl = excl; | ||||
| fNperiods = (user_nperiods == 0) ? 1 : user_nperiods ; | fNperiods = (user_nperiods == 0) ? 1 : user_nperiods ; | ||||
| fSyncIO = syncio; | fSyncIO = syncio; | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| // Force memory page in | // Force memory page in | ||||
| memset(&gCycleTable, 0, sizeof(gCycleTable)); | memset(&gCycleTable, 0, sizeof(gCycleTable)); | ||||
| #endif | #endif | ||||
| if (OpenAux() < 0) { | if (OpenAux() < 0) { | ||||
| Close(); | Close(); | ||||
| return -1; | return -1; | ||||
| @@ -441,14 +442,14 @@ int JackBoomerDriver::Close() | |||||
| { | { | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| FILE* file = fopen("OSSProfiling.log", "w"); | FILE* file = fopen("OSSProfiling.log", "w"); | ||||
| if (file) { | if (file) { | ||||
| jack_info("Writing OSS driver timing data...."); | jack_info("Writing OSS driver timing data...."); | ||||
| for (int i = 1; i < std::min(gCycleReadCount, gCycleWriteCount); i++) { | for (int i = 1; i < std::min(gCycleReadCount, gCycleWriteCount); i++) { | ||||
| int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; | int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; | ||||
| int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; | int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; | ||||
| int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; | int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; | ||||
| int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; | |||||
| int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; | |||||
| fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); | fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); | ||||
| } | } | ||||
| fclose(file); | fclose(file); | ||||
| @@ -461,7 +462,7 @@ int JackBoomerDriver::Close() | |||||
| if (file == NULL) { | if (file == NULL) { | ||||
| jack_error("JackBoomerDriver::Close cannot open TimingOSS.plot file"); | jack_error("JackBoomerDriver::Close cannot open TimingOSS.plot file"); | ||||
| } else { | } else { | ||||
| fprintf(file, "set grid\n"); | fprintf(file, "set grid\n"); | ||||
| fprintf(file, "set title \"OSS audio driver timing\"\n"); | fprintf(file, "set title \"OSS audio driver timing\"\n"); | ||||
| fprintf(file, "set xlabel \"audio cycles\"\n"); | fprintf(file, "set xlabel \"audio cycles\"\n"); | ||||
| @@ -470,10 +471,10 @@ int JackBoomerDriver::Close() | |||||
| \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | ||||
| \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | ||||
| \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | ||||
| fprintf(file, "set output 'TimingOSS.pdf\n"); | fprintf(file, "set output 'TimingOSS.pdf\n"); | ||||
| fprintf(file, "set terminal pdf\n"); | fprintf(file, "set terminal pdf\n"); | ||||
| fprintf(file, "set grid\n"); | fprintf(file, "set grid\n"); | ||||
| fprintf(file, "set title \"OSS audio driver timing\"\n"); | fprintf(file, "set title \"OSS audio driver timing\"\n"); | ||||
| fprintf(file, "set xlabel \"audio cycles\"\n"); | fprintf(file, "set xlabel \"audio cycles\"\n"); | ||||
| @@ -482,12 +483,12 @@ int JackBoomerDriver::Close() | |||||
| \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | ||||
| \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | ||||
| \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | ||||
| fclose(file); | fclose(file); | ||||
| } | } | ||||
| #endif | #endif | ||||
| int res = JackAudioDriver::Close(); | int res = JackAudioDriver::Close(); | ||||
| CloseAux(); | |||||
| CloseAux(); | |||||
| return res; | return res; | ||||
| } | } | ||||
| @@ -498,12 +499,12 @@ int JackBoomerDriver::OpenAux() | |||||
| if ((fRWMode & kRead) && (OpenInput() < 0)) { | if ((fRWMode & kRead) && (OpenInput() < 0)) { | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| if ((fRWMode & kWrite) && (OpenOutput() < 0)) { | |||||
| if ((fRWMode & kWrite) && (OpenOutput() < 0)) { | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| DisplayDeviceInfo(); | |||||
| DisplayDeviceInfo(); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -513,16 +514,16 @@ void JackBoomerDriver::CloseAux() | |||||
| close(fInFD); | close(fInFD); | ||||
| fInFD = -1; | fInFD = -1; | ||||
| } | } | ||||
| if (fRWMode & kWrite && fOutFD >= 0) { | if (fRWMode & kWrite && fOutFD >= 0) { | ||||
| close(fOutFD); | close(fOutFD); | ||||
| fOutFD = -1; | fOutFD = -1; | ||||
| } | } | ||||
| if (fInputBuffer) | if (fInputBuffer) | ||||
| free(fInputBuffer); | free(fInputBuffer); | ||||
| fInputBuffer = NULL; | fInputBuffer = NULL; | ||||
| if (fOutputBuffer) | if (fOutputBuffer) | ||||
| free(fOutputBuffer); | free(fOutputBuffer); | ||||
| fOutputBuffer = NULL; | fOutputBuffer = NULL; | ||||
| @@ -533,29 +534,29 @@ int JackBoomerDriver::Start() | |||||
| jack_log("JackBoomerDriver::Start"); | jack_log("JackBoomerDriver::Start"); | ||||
| JackAudioDriver::Start(); | JackAudioDriver::Start(); | ||||
| // Input/output synchronisation | |||||
| // Input/output synchronisation | |||||
| if (fInFD >= 0 && fOutFD >= 0 && fSyncIO) { | if (fInFD >= 0 && fOutFD >= 0 && fSyncIO) { | ||||
| jack_log("JackBoomerDriver::Start sync input/output"); | |||||
| jack_log("JackBoomerDriver::Start sync input/output"); | |||||
| // Create and fill synch group | // Create and fill synch group | ||||
| int id; | int id; | ||||
| oss_syncgroup group; | oss_syncgroup group; | ||||
| group.id = 0; | group.id = 0; | ||||
| group.mode = PCM_ENABLE_INPUT; | group.mode = PCM_ENABLE_INPUT; | ||||
| if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) | |||||
| if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) | |||||
| jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| group.mode = PCM_ENABLE_OUTPUT; | group.mode = PCM_ENABLE_OUTPUT; | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) | |||||
| if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) | |||||
| jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| // Prefill output buffer : 2 fragments of silence as described in http://manuals.opensound.com/developer/synctest.c.html#LOC6 | // Prefill output buffer : 2 fragments of silence as described in http://manuals.opensound.com/developer/synctest.c.html#LOC6 | ||||
| char* silence_buf = (char*)malloc(fFragmentSize); | char* silence_buf = (char*)malloc(fFragmentSize); | ||||
| memset(silence_buf, 0, fFragmentSize); | memset(silence_buf, 0, fFragmentSize); | ||||
| jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize); | |||||
| jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize); | |||||
| for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
| ssize_t count = ::write(fOutFD, silence_buf, fFragmentSize); | ssize_t count = ::write(fOutFD, silence_buf, fFragmentSize); | ||||
| @@ -569,12 +570,12 @@ int JackBoomerDriver::Start() | |||||
| // Start input/output in sync | // Start input/output in sync | ||||
| id = group.id; | id = group.id; | ||||
| if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1) | |||||
| if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1) | |||||
| jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCSTART : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCSTART : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } else if (fOutFD >= 0) { | } else if (fOutFD >= 0) { | ||||
| // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html | |||||
| // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html | |||||
| memset(fOutputBuffer, 0, fOutputBufferSize); | memset(fOutputBuffer, 0, fOutputBufferSize); | ||||
| // Prefill ouput buffer | // Prefill ouput buffer | ||||
| @@ -584,8 +585,8 @@ int JackBoomerDriver::Start() | |||||
| jack_error("JackBoomerDriver::Start error bytes written = %ld", count); | jack_error("JackBoomerDriver::Start error bytes written = %ld", count); | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| // Start input thread only when needed | // Start input thread only when needed | ||||
| if (fInFD >= 0) { | if (fInFD >= 0) { | ||||
| if (fInputThread.StartSync() < 0) { | if (fInputThread.StartSync() < 0) { | ||||
| @@ -627,44 +628,44 @@ bool JackBoomerDriver::JackBoomerDriverInput::Init() | |||||
| if (fDriver->fInputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { | if (fDriver->fInputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { | ||||
| jack_error("AcquireRealTime error"); | jack_error("AcquireRealTime error"); | ||||
| } else { | } else { | ||||
| set_threaded_log_function(); | |||||
| set_threaded_log_function(); | |||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| // TODO : better error handling | // TODO : better error handling | ||||
| bool JackBoomerDriver::JackBoomerDriverInput::Execute() | bool JackBoomerDriver::JackBoomerDriverInput::Execute() | ||||
| { | { | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| gCycleTable.fTable[gCycleReadCount].fBeforeRead = GetMicroSeconds(); | gCycleTable.fTable[gCycleReadCount].fBeforeRead = GetMicroSeconds(); | ||||
| #endif | #endif | ||||
| audio_errinfo ei_in; | audio_errinfo ei_in; | ||||
| ssize_t count = ::read(fDriver->fInFD, fDriver->fInputBuffer, fDriver->fInputBufferSize); | |||||
| ssize_t count = ::read(fDriver->fInFD, fDriver->fInputBuffer, fDriver->fInputBufferSize); | |||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| if (count > 0 && count != (int)fDriver->fInputBufferSize) | if (count > 0 && count != (int)fDriver->fInputBufferSize) | ||||
| jack_log("JackBoomerDriverInput::Execute count = %ld", count / (fDriver->fSampleSize * fDriver->fCaptureChannels)); | jack_log("JackBoomerDriverInput::Execute count = %ld", count / (fDriver->fSampleSize * fDriver->fCaptureChannels)); | ||||
| gCycleTable.fTable[gCycleReadCount].fAfterRead = GetMicroSeconds(); | gCycleTable.fTable[gCycleReadCount].fAfterRead = GetMicroSeconds(); | ||||
| #endif | #endif | ||||
| // XRun detection | // XRun detection | ||||
| if (ioctl(fDriver->fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { | if (ioctl(fDriver->fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { | ||||
| if (ei_in.rec_overruns > 0 ) { | if (ei_in.rec_overruns > 0 ) { | ||||
| jack_error("JackBoomerDriverInput::Execute overruns"); | jack_error("JackBoomerDriverInput::Execute overruns"); | ||||
| jack_time_t cur_time = GetMicroSeconds(); | jack_time_t cur_time = GetMicroSeconds(); | ||||
| fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... | |||||
| fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... | |||||
| } | } | ||||
| if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { | if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { | ||||
| jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); | jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| if (count < 0) { | if (count < 0) { | ||||
| jack_log("JackBoomerDriverInput::Execute error = %s", strerror(errno)); | jack_log("JackBoomerDriverInput::Execute error = %s", strerror(errno)); | ||||
| } else if (count < (int)fDriver->fInputBufferSize) { | } else if (count < (int)fDriver->fInputBufferSize) { | ||||
| @@ -675,11 +676,11 @@ bool JackBoomerDriver::JackBoomerDriverInput::Execute() | |||||
| fDriver->CycleTakeBeginTime(); | fDriver->CycleTakeBeginTime(); | ||||
| for (int i = 0; i < fDriver->fCaptureChannels; i++) { | for (int i = 0; i < fDriver->fCaptureChannels; i++) { | ||||
| if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) { | if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) { | ||||
| CopyAndConvertIn(fDriver->GetInputBuffer(i), | |||||
| fDriver->fInputBuffer, | |||||
| fDriver->fEngineControl->fBufferSize, | |||||
| i, | |||||
| fDriver->fCaptureChannels * fDriver->fSampleSize, | |||||
| CopyAndConvertIn(fDriver->GetInputBuffer(i), | |||||
| fDriver->fInputBuffer, | |||||
| fDriver->fEngineControl->fBufferSize, | |||||
| i, | |||||
| fDriver->fCaptureChannels * fDriver->fSampleSize, | |||||
| fDriver->fBits); | fDriver->fBits); | ||||
| } | } | ||||
| } | } | ||||
| @@ -707,18 +708,18 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Init() | |||||
| if (fDriver->fOutputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { | if (fDriver->fOutputThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { | ||||
| jack_error("AcquireRealTime error"); | jack_error("AcquireRealTime error"); | ||||
| } else { | } else { | ||||
| set_threaded_log_function(); | |||||
| set_threaded_log_function(); | |||||
| } | } | ||||
| } | } | ||||
| int delay; | int delay; | ||||
| if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { | if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { | ||||
| jack_error("JackBoomerDriverOutput::Init error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackBoomerDriverOutput::Init error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } | } | ||||
| delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; | delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; | ||||
| jack_info("JackBoomerDriverOutput::Init output latency frames = %ld", delay); | jack_info("JackBoomerDriverOutput::Init output latency frames = %ld", delay); | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -730,21 +731,21 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() | |||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| gCycleTable.fTable[gCycleWriteCount].fBeforeWriteConvert = GetMicroSeconds(); | gCycleTable.fTable[gCycleWriteCount].fBeforeWriteConvert = GetMicroSeconds(); | ||||
| #endif | #endif | ||||
| for (int i = 0; i < fDriver->fPlaybackChannels; i++) { | for (int i = 0; i < fDriver->fPlaybackChannels; i++) { | ||||
| if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fPlaybackPortList[i]) > 0) { | if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fPlaybackPortList[i]) > 0) { | ||||
| CopyAndConvertOut(fDriver->fOutputBuffer, | |||||
| fDriver->GetOutputBuffer(i), | |||||
| fDriver->fEngineControl->fBufferSize, | |||||
| i, | |||||
| fDriver->fPlaybackChannels * fDriver->fSampleSize, | |||||
| CopyAndConvertOut(fDriver->fOutputBuffer, | |||||
| fDriver->GetOutputBuffer(i), | |||||
| fDriver->fEngineControl->fBufferSize, | |||||
| i, | |||||
| fDriver->fPlaybackChannels * fDriver->fSampleSize, | |||||
| fDriver->fBits); | fDriver->fBits); | ||||
| } | } | ||||
| } | } | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| gCycleTable.fTable[gCycleWriteCount].fBeforeWrite = GetMicroSeconds(); | gCycleTable.fTable[gCycleWriteCount].fBeforeWrite = GetMicroSeconds(); | ||||
| #endif | |||||
| #endif | |||||
| ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); | ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); | ||||
| @@ -762,20 +763,20 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() | |||||
| if (ei_out.play_underruns > 0) { | if (ei_out.play_underruns > 0) { | ||||
| jack_error("JackBoomerDriverOutput::Execute underruns"); | jack_error("JackBoomerDriverOutput::Execute underruns"); | ||||
| jack_time_t cur_time = GetMicroSeconds(); | jack_time_t cur_time = GetMicroSeconds(); | ||||
| fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... | |||||
| fDriver->NotifyXRun(cur_time, float(cur_time - fDriver->fBeginDateUst)); // Better this value than nothing... | |||||
| } | } | ||||
| if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { | if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { | ||||
| jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); | jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); | ||||
| } | } | ||||
| } | } | ||||
| if (count < 0) { | if (count < 0) { | ||||
| jack_log("JackBoomerDriverOutput::Execute error = %s", strerror(errno)); | jack_log("JackBoomerDriverOutput::Execute error = %s", strerror(errno)); | ||||
| } else if (count < (int)fDriver->fOutputBufferSize) { | } else if (count < (int)fDriver->fOutputBufferSize) { | ||||
| jack_error("JackBoomerDriverOutput::Execute error bytes written = %ld", count); | jack_error("JackBoomerDriverOutput::Execute error bytes written = %ld", count); | ||||
| } | } | ||||
| // Duplex : sync with read thread | // Duplex : sync with read thread | ||||
| if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { | if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { | ||||
| fDriver->SynchronizeWrite(); | fDriver->SynchronizeWrite(); | ||||
| @@ -802,12 +803,11 @@ void JackBoomerDriver::SynchronizeWrite() | |||||
| int JackBoomerDriver::SetBufferSize(jack_nframes_t buffer_size) | int JackBoomerDriver::SetBufferSize(jack_nframes_t buffer_size) | ||||
| { | { | ||||
| CloseAux(); | |||||
| JackAudioDriver::SetBufferSize(buffer_size); // never fails | |||||
| CloseAux(); | |||||
| JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails | |||||
| return OpenAux(); | return OpenAux(); | ||||
| } | } | ||||
| } // end of namespace | } // end of namespace | ||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| @@ -823,7 +823,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| strcpy(desc->name, "boomer"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | strcpy(desc->name, "boomer"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | ||||
| strcpy(desc->desc, "Boomer/OSS API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | strcpy(desc->desc, "Boomer/OSS API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | ||||
| desc->nparams = OSS_DRIVER_N_PARAMS; | desc->nparams = OSS_DRIVER_N_PARAMS; | ||||
| desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | ||||
| @@ -866,7 +866,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| desc->params[i].value.ui = OSS_DRIVER_DEF_INS; | desc->params[i].value.ui = OSS_DRIVER_DEF_INS; | ||||
| strcpy(desc->params[i].short_desc, "Capture channels"); | strcpy(desc->params[i].short_desc, "Capture channels"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "outchannels"); | strcpy(desc->params[i].name, "outchannels"); | ||||
| desc->params[i].character = 'o'; | desc->params[i].character = 'o'; | ||||
| @@ -874,7 +874,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| desc->params[i].value.ui = OSS_DRIVER_DEF_OUTS; | desc->params[i].value.ui = OSS_DRIVER_DEF_OUTS; | ||||
| strcpy(desc->params[i].short_desc, "Playback channels"); | strcpy(desc->params[i].short_desc, "Playback channels"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "excl"); | strcpy(desc->params[i].name, "excl"); | ||||
| desc->params[i].character = 'e'; | desc->params[i].character = 'e'; | ||||
| @@ -890,7 +890,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | ||||
| strcpy(desc->params[i].short_desc, "Input device"); | strcpy(desc->params[i].short_desc, "Input device"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "playback"); | strcpy(desc->params[i].name, "playback"); | ||||
| desc->params[i].character = 'P'; | desc->params[i].character = 'P'; | ||||
| @@ -906,7 +906,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | ||||
| strcpy(desc->params[i].short_desc, "OSS device name"); | strcpy(desc->params[i].short_desc, "OSS device name"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "input-latency"); | strcpy(desc->params[i].name, "input-latency"); | ||||
| desc->params[i].character = 'I'; | desc->params[i].character = 'I'; | ||||
| @@ -953,13 +953,13 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| const jack_driver_param_t *param; | const jack_driver_param_t *param; | ||||
| jack_nframes_t systemic_input_latency = 0; | jack_nframes_t systemic_input_latency = 0; | ||||
| jack_nframes_t systemic_output_latency = 0; | jack_nframes_t systemic_output_latency = 0; | ||||
| for (node = params; node; node = jack_slist_next(node)) { | for (node = params; node; node = jack_slist_next(node)) { | ||||
| param = (const jack_driver_param_t *)node->data; | param = (const jack_driver_param_t *)node->data; | ||||
| switch (param->character) { | switch (param->character) { | ||||
| case 'r': | case 'r': | ||||
| srate = param->value.ui; | srate = param->value.ui; | ||||
| break; | break; | ||||
| @@ -983,7 +983,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| case 'o': | case 'o': | ||||
| chan_out = (int)param->value.ui; | chan_out = (int)param->value.ui; | ||||
| break; | break; | ||||
| case 'C': | case 'C': | ||||
| capture = true; | capture = true; | ||||
| if (strcmp(param->value.str, "none") != 0) { | if (strcmp(param->value.str, "none") != 0) { | ||||
| @@ -1002,11 +1002,11 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| playback_pcm_name = param->value.str; | playback_pcm_name = param->value.str; | ||||
| capture_pcm_name = param->value.str; | capture_pcm_name = param->value.str; | ||||
| break; | break; | ||||
| case 'e': | case 'e': | ||||
| excl = true; | excl = true; | ||||
| break; | break; | ||||
| case 'I': | case 'I': | ||||
| systemic_input_latency = param->value.ui; | systemic_input_latency = param->value.ui; | ||||
| break; | break; | ||||
| @@ -1028,9 +1028,9 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| } | } | ||||
| Jack::JackBoomerDriver* boomer_driver = new Jack::JackBoomerDriver("system", "boomer", engine, table); | Jack::JackBoomerDriver* boomer_driver = new Jack::JackBoomerDriver("system", "boomer", engine, table); | ||||
| // Special open for Boomer driver... | // Special open for Boomer driver... | ||||
| if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, | |||||
| if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, | |||||
| monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, syncio) == 0) { | monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, syncio) == 0) { | ||||
| return boomer_driver; | return boomer_driver; | ||||
| } else { | } else { | ||||
| @@ -107,12 +107,12 @@ static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nfram | |||||
| s32dst += channel; | s32dst += channel; | ||||
| sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... | sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... | ||||
| break; | break; | ||||
| } | |||||
| } | |||||
| case 32: { | case 32: { | ||||
| signed int *s32dst = (signed int*)dst; | signed int *s32dst = (signed int*)dst; | ||||
| s32dst += channel; | s32dst += channel; | ||||
| sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); | sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); | ||||
| break; | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -126,7 +126,7 @@ void JackOSSDriver::SetSampleFormat() | |||||
| fSampleSize = sizeof(int); | fSampleSize = sizeof(int); | ||||
| break; | break; | ||||
| case 32: /* native-endian 32-bit integer */ | case 32: /* native-endian 32-bit integer */ | ||||
| fSampleFormat = AFMT_S32_NE; | |||||
| fSampleFormat = AFMT_S32_NE; | |||||
| fSampleSize = sizeof(int); | fSampleSize = sizeof(int); | ||||
| break; | break; | ||||
| case 16: /* native-endian 16-bit integer */ | case 16: /* native-endian 16-bit integer */ | ||||
| @@ -143,13 +143,13 @@ void JackOSSDriver::DisplayDeviceInfo() | |||||
| oss_audioinfo ai_in, ai_out; | oss_audioinfo ai_in, ai_out; | ||||
| memset(&info, 0, sizeof(audio_buf_info)); | memset(&info, 0, sizeof(audio_buf_info)); | ||||
| int cap = 0; | int cap = 0; | ||||
| // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html | // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html | ||||
| jack_info("Audio Interface Description :"); | jack_info("Audio Interface Description :"); | ||||
| jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); | jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fEngineControl->fSampleRate, fSampleFormat, fRWMode); | ||||
| if (fRWMode & kWrite) { | if (fRWMode & kWrite) { | ||||
| oss_sysinfo si; | oss_sysinfo si; | ||||
| if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { | if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) { | ||||
| jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -161,17 +161,17 @@ void JackOSSDriver::DisplayDeviceInfo() | |||||
| jack_info("OSS numaudioengines %d", si.numaudioengines); | jack_info("OSS numaudioengines %d", si.numaudioengines); | ||||
| jack_info("OSS numcards %d", si.numcards); | jack_info("OSS numcards %d", si.numcards); | ||||
| } | } | ||||
| jack_info("Output capabilities - %d channels : ", fPlaybackChannels); | jack_info("Output capabilities - %d channels : ", fPlaybackChannels); | ||||
| jack_info("Output block size = %d", fOutputBufferSize); | jack_info("Output block size = %d", fOutputBufferSize); | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) { | ||||
| jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } else { | } else { | ||||
| jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| info.fragments, info.fragstotal, info.fragsize, info.bytes); | info.fragments, info.fragstotal, info.fragsize, info.bytes); | ||||
| } | } | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { | ||||
| jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } else { | } else { | ||||
| @@ -184,10 +184,10 @@ void JackOSSDriver::DisplayDeviceInfo() | |||||
| if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); | if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI"); | ||||
| if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| if (fRWMode & kRead) { | if (fRWMode & kRead) { | ||||
| oss_sysinfo si; | oss_sysinfo si; | ||||
| if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { | if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) { | ||||
| jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -199,14 +199,14 @@ void JackOSSDriver::DisplayDeviceInfo() | |||||
| jack_info("OSS numaudioengines %d", si.numaudioengines); | jack_info("OSS numaudioengines %d", si.numaudioengines); | ||||
| jack_info("OSS numcards %d", si.numcards); | jack_info("OSS numcards %d", si.numcards); | ||||
| } | } | ||||
| jack_info("Input capabilities - %d channels : ", fCaptureChannels); | jack_info("Input capabilities - %d channels : ", fCaptureChannels); | ||||
| jack_info("Input block size = %d", fInputBufferSize); | jack_info("Input block size = %d", fInputBufferSize); | ||||
| if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { | |||||
| if (ioctl(fInFD, SNDCTL_DSP_GETISPACE, &info) == -1) { | |||||
| jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| } else { | } else { | ||||
| jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", | |||||
| info.fragments, info.fragstotal, info.fragsize, info.bytes); | info.fragments, info.fragstotal, info.fragsize, info.bytes); | ||||
| } | } | ||||
| @@ -223,7 +223,7 @@ void JackOSSDriver::DisplayDeviceInfo() | |||||
| if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND"); | ||||
| } | } | ||||
| } | } | ||||
| if (ai_in.rate_source != ai_out.rate_source) { | if (ai_in.rate_source != ai_out.rate_source) { | ||||
| jack_info("Warning : input and output are not necessarily driven by the same clock!"); | jack_info("Warning : input and output are not necessarily driven by the same clock!"); | ||||
| } | } | ||||
| @@ -238,7 +238,7 @@ int JackOSSDriver::OpenInput() | |||||
| jack_nframes_t cur_sample_rate; | jack_nframes_t cur_sample_rate; | ||||
| if (fCaptureChannels == 0) fCaptureChannels = 2; | if (fCaptureChannels == 0) fCaptureChannels = 2; | ||||
| if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | ||||
| jack_error("JackOSSDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| return -1; | return -1; | ||||
| @@ -253,7 +253,7 @@ int JackOSSDriver::OpenInput() | |||||
| } | } | ||||
| } | } | ||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); | |||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fCaptureChannels); | |||||
| if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | ||||
| jack_error("JackOSSDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| @@ -267,7 +267,7 @@ int JackOSSDriver::OpenInput() | |||||
| if (cur_sample_format != fSampleFormat) { | if (cur_sample_format != fSampleFormat) { | ||||
| jack_info("JackOSSDriver::OpenInput driver forced the sample format %ld", fSampleFormat); | jack_info("JackOSSDriver::OpenInput driver forced the sample format %ld", fSampleFormat); | ||||
| } | } | ||||
| cur_capture_channels = fCaptureChannels; | cur_capture_channels = fCaptureChannels; | ||||
| if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { | if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) { | ||||
| jack_error("JackOSSDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -276,7 +276,7 @@ int JackOSSDriver::OpenInput() | |||||
| if (cur_capture_channels != fCaptureChannels) { | if (cur_capture_channels != fCaptureChannels) { | ||||
| jack_info("JackOSSDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); | jack_info("JackOSSDriver::OpenInput driver forced the number of capture channels %ld", fCaptureChannels); | ||||
| } | } | ||||
| cur_sample_rate = fEngineControl->fSampleRate; | cur_sample_rate = fEngineControl->fSampleRate; | ||||
| if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { | if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fEngineControl->fSampleRate) == -1) { | ||||
| jack_error("JackOSSDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -291,7 +291,7 @@ int JackOSSDriver::OpenInput() | |||||
| jack_error("JackOSSDriver::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| if (fInputBufferSize != fEngineControl->fBufferSize * fSampleSize * fCaptureChannels) { | if (fInputBufferSize != fEngineControl->fBufferSize * fSampleSize * fCaptureChannels) { | ||||
| if (fIgnoreHW) { | if (fIgnoreHW) { | ||||
| int new_buffer_size = fInputBufferSize / (fSampleSize * fCaptureChannels); | int new_buffer_size = fInputBufferSize / (fSampleSize * fCaptureChannels); | ||||
| @@ -306,7 +306,7 @@ int JackOSSDriver::OpenInput() | |||||
| fInputBuffer = (void*)calloc(fInputBufferSize, 1); | fInputBuffer = (void*)calloc(fInputBufferSize, 1); | ||||
| assert(fInputBuffer); | assert(fInputBuffer); | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| ::close(fInFD); | ::close(fInFD); | ||||
| return -1; | return -1; | ||||
| @@ -321,27 +321,27 @@ int JackOSSDriver::OpenOutput() | |||||
| jack_nframes_t cur_sample_rate; | jack_nframes_t cur_sample_rate; | ||||
| if (fPlaybackChannels == 0) fPlaybackChannels = 2; | if (fPlaybackChannels == 0) fPlaybackChannels = 2; | ||||
| if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) { | ||||
| jack_error("JackOSSDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| jack_log("JackOSSDriver::OpenOutput output fOutFD = %d", fOutFD); | jack_log("JackOSSDriver::OpenOutput output fOutFD = %d", fOutFD); | ||||
| if (fExcl) { | if (fExcl) { | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) { | ||||
| jack_error("JackOSSDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); | |||||
| gFragFormat = (2 << 16) + int2pow2(fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels); | |||||
| if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) { | ||||
| jack_error("JackOSSDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| cur_sample_format = fSampleFormat; | cur_sample_format = fSampleFormat; | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) { | ||||
| jack_error("JackOSSDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -350,7 +350,7 @@ int JackOSSDriver::OpenOutput() | |||||
| if (cur_sample_format != fSampleFormat) { | if (cur_sample_format != fSampleFormat) { | ||||
| jack_info("JackOSSDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); | jack_info("JackOSSDriver::OpenOutput driver forced the sample format %ld", fSampleFormat); | ||||
| } | } | ||||
| cur_playback_channels = fPlaybackChannels; | cur_playback_channels = fPlaybackChannels; | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) { | ||||
| jack_error("JackOSSDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| @@ -374,7 +374,7 @@ int JackOSSDriver::OpenOutput() | |||||
| jack_error("JackOSSDriver::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| if (fOutputBufferSize != fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels) { | if (fOutputBufferSize != fEngineControl->fBufferSize * fSampleSize * fPlaybackChannels) { | ||||
| if (fIgnoreHW) { | if (fIgnoreHW) { | ||||
| int new_buffer_size = fOutputBufferSize / (fSampleSize * fPlaybackChannels); | int new_buffer_size = fOutputBufferSize / (fSampleSize * fPlaybackChannels); | ||||
| @@ -385,19 +385,19 @@ int JackOSSDriver::OpenOutput() | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| } | } | ||||
| fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); | fOutputBuffer = (void*)calloc(fOutputBufferSize, 1); | ||||
| fFirstCycle = true; | fFirstCycle = true; | ||||
| assert(fOutputBuffer); | assert(fOutputBuffer); | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| ::close(fOutFD); | ::close(fOutFD); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| int JackOSSDriver::Open(jack_nframes_t nframes, | int JackOSSDriver::Open(jack_nframes_t nframes, | ||||
| int user_nperiods, | |||||
| int user_nperiods, | |||||
| jack_nframes_t samplerate, | jack_nframes_t samplerate, | ||||
| bool capturing, | bool capturing, | ||||
| bool playing, | bool playing, | ||||
| @@ -413,7 +413,7 @@ int JackOSSDriver::Open(jack_nframes_t nframes, | |||||
| bool ignorehwbuf) | bool ignorehwbuf) | ||||
| { | { | ||||
| // Generic JackAudioDriver Open | // Generic JackAudioDriver Open | ||||
| if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, | |||||
| if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, | |||||
| capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { | capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { | ||||
| return -1; | return -1; | ||||
| } else { | } else { | ||||
| @@ -422,7 +422,7 @@ int JackOSSDriver::Open(jack_nframes_t nframes, | |||||
| jack_error("Cannot run in asynchronous mode, use the -S parameter for jackd"); | jack_error("Cannot run in asynchronous mode, use the -S parameter for jackd"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| fRWMode |= ((capturing) ? kRead : 0); | fRWMode |= ((capturing) ? kRead : 0); | ||||
| fRWMode |= ((playing) ? kWrite : 0); | fRWMode |= ((playing) ? kWrite : 0); | ||||
| fBits = bits; | fBits = bits; | ||||
| @@ -434,7 +434,7 @@ int JackOSSDriver::Open(jack_nframes_t nframes, | |||||
| // Force memory page in | // Force memory page in | ||||
| memset(&gCycleTable, 0, sizeof(gCycleTable)); | memset(&gCycleTable, 0, sizeof(gCycleTable)); | ||||
| #endif | #endif | ||||
| if (OpenAux() < 0) { | if (OpenAux() < 0) { | ||||
| Close(); | Close(); | ||||
| return -1; | return -1; | ||||
| @@ -448,14 +448,14 @@ int JackOSSDriver::Close() | |||||
| { | { | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| FILE* file = fopen("OSSProfiling.log", "w"); | FILE* file = fopen("OSSProfiling.log", "w"); | ||||
| if (file) { | if (file) { | ||||
| jack_info("Writing OSS driver timing data...."); | jack_info("Writing OSS driver timing data...."); | ||||
| for (int i = 1; i < gCycleCount; i++) { | for (int i = 1; i < gCycleCount; i++) { | ||||
| int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; | int d1 = gCycleTable.fTable[i].fAfterRead - gCycleTable.fTable[i].fBeforeRead; | ||||
| int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; | int d2 = gCycleTable.fTable[i].fAfterReadConvert - gCycleTable.fTable[i].fAfterRead; | ||||
| int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; | int d3 = gCycleTable.fTable[i].fAfterWrite - gCycleTable.fTable[i].fBeforeWrite; | ||||
| int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; | |||||
| int d4 = gCycleTable.fTable[i].fBeforeWrite - gCycleTable.fTable[i].fBeforeWriteConvert; | |||||
| fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); | fprintf(file, "%d \t %d \t %d \t %d \t \n", d1, d2, d3, d4); | ||||
| } | } | ||||
| fclose(file); | fclose(file); | ||||
| @@ -468,7 +468,7 @@ int JackOSSDriver::Close() | |||||
| if (file == NULL) { | if (file == NULL) { | ||||
| jack_error("JackOSSDriver::Close cannot open TimingOSS.plot file"); | jack_error("JackOSSDriver::Close cannot open TimingOSS.plot file"); | ||||
| } else { | } else { | ||||
| fprintf(file, "set grid\n"); | fprintf(file, "set grid\n"); | ||||
| fprintf(file, "set title \"OSS audio driver timing\"\n"); | fprintf(file, "set title \"OSS audio driver timing\"\n"); | ||||
| fprintf(file, "set xlabel \"audio cycles\"\n"); | fprintf(file, "set xlabel \"audio cycles\"\n"); | ||||
| @@ -477,10 +477,10 @@ int JackOSSDriver::Close() | |||||
| \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | ||||
| \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | ||||
| \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | ||||
| fprintf(file, "set output 'TimingOSS.pdf\n"); | fprintf(file, "set output 'TimingOSS.pdf\n"); | ||||
| fprintf(file, "set terminal pdf\n"); | fprintf(file, "set terminal pdf\n"); | ||||
| fprintf(file, "set grid\n"); | fprintf(file, "set grid\n"); | ||||
| fprintf(file, "set title \"OSS audio driver timing\"\n"); | fprintf(file, "set title \"OSS audio driver timing\"\n"); | ||||
| fprintf(file, "set xlabel \"audio cycles\"\n"); | fprintf(file, "set xlabel \"audio cycles\"\n"); | ||||
| @@ -489,12 +489,12 @@ int JackOSSDriver::Close() | |||||
| \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | \"OSSProfiling.log\" using 2 title \"Driver read convert duration\" with lines, \ | ||||
| \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | \"OSSProfiling.log\" using 3 title \"Driver write wait\" with lines, \ | ||||
| \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | \"OSSProfiling.log\" using 4 title \"Driver write convert duration\" with lines\n"); | ||||
| fclose(file); | fclose(file); | ||||
| } | } | ||||
| #endif | #endif | ||||
| int res = JackAudioDriver::Close(); | int res = JackAudioDriver::Close(); | ||||
| CloseAux(); | |||||
| CloseAux(); | |||||
| return res; | return res; | ||||
| } | } | ||||
| @@ -506,8 +506,8 @@ int JackOSSDriver::OpenAux() | |||||
| if ((fRWMode & kRead) && (OpenInput() < 0)) { | if ((fRWMode & kRead) && (OpenInput() < 0)) { | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| if ((fRWMode & kWrite) && (OpenOutput() < 0)) { | |||||
| if ((fRWMode & kWrite) && (OpenOutput() < 0)) { | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -522,7 +522,7 @@ int JackOSSDriver::OpenAux() | |||||
| } | } | ||||
| */ | */ | ||||
| DisplayDeviceInfo(); | |||||
| DisplayDeviceInfo(); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -532,16 +532,16 @@ void JackOSSDriver::CloseAux() | |||||
| close(fInFD); | close(fInFD); | ||||
| fInFD = -1; | fInFD = -1; | ||||
| } | } | ||||
| if (fRWMode & kWrite && fOutFD > 0) { | if (fRWMode & kWrite && fOutFD > 0) { | ||||
| close(fOutFD); | close(fOutFD); | ||||
| fOutFD = -1; | fOutFD = -1; | ||||
| } | } | ||||
| if (fInputBuffer) | if (fInputBuffer) | ||||
| free(fInputBuffer); | free(fInputBuffer); | ||||
| fInputBuffer = NULL; | fInputBuffer = NULL; | ||||
| if (fOutputBuffer) | if (fOutputBuffer) | ||||
| free(fOutputBuffer); | free(fOutputBuffer); | ||||
| fOutputBuffer = NULL; | fOutputBuffer = NULL; | ||||
| @@ -554,7 +554,7 @@ int JackOSSDriver::Read() | |||||
| JackDriver::CycleTakeBeginTime(); | JackDriver::CycleTakeBeginTime(); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| ssize_t count; | ssize_t count; | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| @@ -562,28 +562,28 @@ int JackOSSDriver::Read() | |||||
| #endif | #endif | ||||
| audio_errinfo ei_in; | audio_errinfo ei_in; | ||||
| count = ::read(fInFD, fInputBuffer, fInputBufferSize); | |||||
| count = ::read(fInFD, fInputBuffer, fInputBufferSize); | |||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| if (count > 0 && count != (int)fInputBufferSize) | if (count > 0 && count != (int)fInputBufferSize) | ||||
| jack_log("JackOSSDriver::Read count = %ld", count / (fSampleSize * fCaptureChannels)); | jack_log("JackOSSDriver::Read count = %ld", count / (fSampleSize * fCaptureChannels)); | ||||
| gCycleTable.fTable[gCycleCount].fAfterRead = GetMicroSeconds(); | gCycleTable.fTable[gCycleCount].fAfterRead = GetMicroSeconds(); | ||||
| #endif | #endif | ||||
| // XRun detection | // XRun detection | ||||
| if (ioctl(fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { | if (ioctl(fInFD, SNDCTL_DSP_GETERROR, &ei_in) == 0) { | ||||
| if (ei_in.rec_overruns > 0 ) { | if (ei_in.rec_overruns > 0 ) { | ||||
| jack_error("JackOSSDriver::Read overruns"); | jack_error("JackOSSDriver::Read overruns"); | ||||
| jack_time_t cur_time = GetMicroSeconds(); | jack_time_t cur_time = GetMicroSeconds(); | ||||
| NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... | |||||
| NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... | |||||
| } | } | ||||
| if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { | if (ei_in.rec_errorcount > 0 && ei_in.rec_lasterror != 0) { | ||||
| jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); | jack_error("%d OSS rec event(s), last=%05d:%d", ei_in.rec_errorcount, ei_in.rec_lasterror, ei_in.rec_errorparm); | ||||
| } | } | ||||
| } | |||||
| } | |||||
| if (count < 0) { | if (count < 0) { | ||||
| jack_log("JackOSSDriver::Read error = %s", strerror(errno)); | jack_log("JackOSSDriver::Read error = %s", strerror(errno)); | ||||
| return -1; | return -1; | ||||
| @@ -603,7 +603,7 @@ int JackOSSDriver::Read() | |||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| gCycleTable.fTable[gCycleCount].fAfterReadConvert = GetMicroSeconds(); | gCycleTable.fTable[gCycleCount].fAfterReadConvert = GetMicroSeconds(); | ||||
| #endif | #endif | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | } | ||||
| @@ -618,10 +618,10 @@ int JackOSSDriver::Write() | |||||
| ssize_t count; | ssize_t count; | ||||
| audio_errinfo ei_out; | audio_errinfo ei_out; | ||||
| // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html | |||||
| // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html | |||||
| if (fFirstCycle) { | if (fFirstCycle) { | ||||
| fFirstCycle = false; | fFirstCycle = false; | ||||
| memset(fOutputBuffer, 0, fOutputBufferSize); | memset(fOutputBuffer, 0, fOutputBufferSize); | ||||
| @@ -633,17 +633,17 @@ int JackOSSDriver::Write() | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| } | } | ||||
| int delay; | int delay; | ||||
| if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { | if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { | ||||
| jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); | jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| delay /= fSampleSize * fPlaybackChannels; | delay /= fSampleSize * fPlaybackChannels; | ||||
| jack_info("JackOSSDriver::Write output latency frames = %ld", delay); | jack_info("JackOSSDriver::Write output latency frames = %ld", delay); | ||||
| } | } | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| gCycleTable.fTable[gCycleCount].fBeforeWriteConvert = GetMicroSeconds(); | gCycleTable.fTable[gCycleCount].fBeforeWriteConvert = GetMicroSeconds(); | ||||
| #endif | #endif | ||||
| @@ -657,7 +657,7 @@ int JackOSSDriver::Write() | |||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| gCycleTable.fTable[gCycleCount].fBeforeWrite = GetMicroSeconds(); | gCycleTable.fTable[gCycleCount].fBeforeWrite = GetMicroSeconds(); | ||||
| #endif | |||||
| #endif | |||||
| // Keep end cycle time | // Keep end cycle time | ||||
| JackDriver::CycleTakeEndTime(); | JackDriver::CycleTakeEndTime(); | ||||
| @@ -676,14 +676,14 @@ int JackOSSDriver::Write() | |||||
| if (ei_out.play_underruns > 0) { | if (ei_out.play_underruns > 0) { | ||||
| jack_error("JackOSSDriver::Write underruns"); | jack_error("JackOSSDriver::Write underruns"); | ||||
| jack_time_t cur_time = GetMicroSeconds(); | jack_time_t cur_time = GetMicroSeconds(); | ||||
| NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... | |||||
| NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... | |||||
| } | } | ||||
| if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { | if (ei_out.play_errorcount > 0 && ei_out.play_lasterror != 0) { | ||||
| jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); | jack_error("%d OSS play event(s), last=%05d:%d",ei_out.play_errorcount, ei_out.play_lasterror, ei_out.play_errorparm); | ||||
| } | } | ||||
| } | } | ||||
| if (count < 0) { | if (count < 0) { | ||||
| jack_log("JackOSSDriver::Write error = %s", strerror(errno)); | jack_log("JackOSSDriver::Write error = %s", strerror(errno)); | ||||
| return -1; | return -1; | ||||
| @@ -697,15 +697,15 @@ int JackOSSDriver::Write() | |||||
| int JackOSSDriver::SetBufferSize(jack_nframes_t buffer_size) | int JackOSSDriver::SetBufferSize(jack_nframes_t buffer_size) | ||||
| { | { | ||||
| CloseAux(); | |||||
| JackAudioDriver::SetBufferSize(buffer_size); // never fails | |||||
| CloseAux(); | |||||
| JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails | |||||
| return OpenAux(); | return OpenAux(); | ||||
| } | } | ||||
| int JackOSSDriver::ProcessSync() | int JackOSSDriver::ProcessSync() | ||||
| { | { | ||||
| // Read input buffers for the current cycle | // Read input buffers for the current cycle | ||||
| if (Read() < 0) { | |||||
| if (Read() < 0) { | |||||
| jack_error("ProcessSync: read error, skip cycle"); | jack_error("ProcessSync: read error, skip cycle"); | ||||
| return 0; // Non fatal error here, skip cycle, but continue processing... | return 0; // Non fatal error here, skip cycle, but continue processing... | ||||
| } | } | ||||
| @@ -715,13 +715,13 @@ int JackOSSDriver::ProcessSync() | |||||
| } else { | } else { | ||||
| fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); | fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); | ||||
| } | } | ||||
| // Write output buffers for the current cycle | // Write output buffers for the current cycle | ||||
| if (Write() < 0) { | |||||
| if (Write() < 0) { | |||||
| jack_error("JackAudioDriver::ProcessSync: write error, skip cycle"); | jack_error("JackAudioDriver::ProcessSync: write error, skip cycle"); | ||||
| return 0; // Non fatal error here, skip cycle, but continue processing... | return 0; // Non fatal error here, skip cycle, but continue processing... | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -740,7 +740,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| strcpy(desc->name, "oss"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | strcpy(desc->name, "oss"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 | ||||
| strcpy(desc->desc, "OSS API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | strcpy(desc->desc, "OSS API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 | ||||
| desc->nparams = OSS_DRIVER_N_PARAMS; | desc->nparams = OSS_DRIVER_N_PARAMS; | ||||
| desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); | ||||
| @@ -783,7 +783,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| desc->params[i].value.ui = OSS_DRIVER_DEF_INS; | desc->params[i].value.ui = OSS_DRIVER_DEF_INS; | ||||
| strcpy(desc->params[i].short_desc, "Capture channels"); | strcpy(desc->params[i].short_desc, "Capture channels"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "outchannels"); | strcpy(desc->params[i].name, "outchannels"); | ||||
| desc->params[i].character = 'o'; | desc->params[i].character = 'o'; | ||||
| @@ -807,7 +807,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | ||||
| strcpy(desc->params[i].short_desc, "Input device"); | strcpy(desc->params[i].short_desc, "Input device"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "playback"); | strcpy(desc->params[i].name, "playback"); | ||||
| desc->params[i].character = 'P'; | desc->params[i].character = 'P'; | ||||
| @@ -823,7 +823,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | strcpy(desc->params[i].value.str, OSS_DRIVER_DEF_DEV); | ||||
| strcpy(desc->params[i].short_desc, "OSS device name"); | strcpy(desc->params[i].short_desc, "OSS device name"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "ignorehwbuf"); | strcpy(desc->params[i].name, "ignorehwbuf"); | ||||
| desc->params[i].character = 'b'; | desc->params[i].character = 'b'; | ||||
| @@ -831,7 +831,7 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() | |||||
| desc->params[i].value.i = false; | desc->params[i].value.i = false; | ||||
| strcpy(desc->params[i].short_desc, "Ignore hardware period size"); | strcpy(desc->params[i].short_desc, "Ignore hardware period size"); | ||||
| strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | strcpy(desc->params[i].long_desc, desc->params[i].short_desc); | ||||
| i++; | i++; | ||||
| strcpy(desc->params[i].name, "input-latency"); | strcpy(desc->params[i].name, "input-latency"); | ||||
| desc->params[i].character = 'I'; | desc->params[i].character = 'I'; | ||||
| @@ -870,13 +870,13 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| bool ignorehwbuf = false; | bool ignorehwbuf = false; | ||||
| jack_nframes_t systemic_input_latency = 0; | jack_nframes_t systemic_input_latency = 0; | ||||
| jack_nframes_t systemic_output_latency = 0; | jack_nframes_t systemic_output_latency = 0; | ||||
| for (node = params; node; node = jack_slist_next(node)) { | for (node = params; node; node = jack_slist_next(node)) { | ||||
| param = (const jack_driver_param_t *)node->data; | param = (const jack_driver_param_t *)node->data; | ||||
| switch (param->character) { | switch (param->character) { | ||||
| case 'r': | case 'r': | ||||
| srate = param->value.ui; | srate = param->value.ui; | ||||
| break; | break; | ||||
| @@ -900,7 +900,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| case 'o': | case 'o': | ||||
| chan_out = (int)param->value.ui; | chan_out = (int)param->value.ui; | ||||
| break; | break; | ||||
| case 'C': | case 'C': | ||||
| capture = true; | capture = true; | ||||
| if (strcmp(param->value.str, "none") != 0) { | if (strcmp(param->value.str, "none") != 0) { | ||||
| @@ -919,7 +919,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| playback_pcm_name = param->value.str; | playback_pcm_name = param->value.str; | ||||
| capture_pcm_name = param->value.str; | capture_pcm_name = param->value.str; | ||||
| break; | break; | ||||
| case 'b': | case 'b': | ||||
| ignorehwbuf = true; | ignorehwbuf = true; | ||||
| break; | break; | ||||
| @@ -927,7 +927,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| case 'e': | case 'e': | ||||
| excl = true; | excl = true; | ||||
| break; | break; | ||||
| case 'I': | case 'I': | ||||
| systemic_input_latency = param->value.ui; | systemic_input_latency = param->value.ui; | ||||
| break; | break; | ||||
| @@ -946,9 +946,9 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine | |||||
| Jack::JackOSSDriver* oss_driver = new Jack::JackOSSDriver("system", "oss", engine, table); | Jack::JackOSSDriver* oss_driver = new Jack::JackOSSDriver("system", "oss", engine, table); | ||||
| Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(oss_driver); | Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(oss_driver); | ||||
| // Special open for OSS driver... | // Special open for OSS driver... | ||||
| if (oss_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, | |||||
| if (oss_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, | |||||
| excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, ignorehwbuf) == 0) { | excl, monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, ignorehwbuf) == 0) { | ||||
| return threaded_driver; | return threaded_driver; | ||||
| } else { | } else { | ||||
| @@ -225,8 +225,6 @@ error: | |||||
| return -1; | return -1; | ||||
| } else { | } else { | ||||
| JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails | JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails | ||||
| // PortAudio specific | |||||
| JackAudioDriver::UpdateLatencies(); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | } | ||||