00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackOSSAdapter.h"
00021 #include "JackServerGlobals.h"
00022 #include "JackEngineControl.h"
00023 #include "memops.h"
00024
00025 #include <sys/ioctl.h>
00026 #include <sys/soundcard.h>
00027 #include <fcntl.h>
00028 #include <iostream>
00029 #include <assert.h>
00030
00031 namespace Jack
00032 {
00033
00034 inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; }
00035
00036 static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits)
00037 {
00038 switch (bits) {
00039
00040 case 16: {
00041 signed short *s16src = (signed short*)src;
00042 s16src += channel;
00043 sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1);
00044 break;
00045 }
00046 case 24: {
00047 signed int *s32src = (signed int*)src;
00048 s32src += channel;
00049 sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2);
00050 break;
00051 }
00052 case 32: {
00053 signed int *s32src = (signed int*)src;
00054 s32src += channel;
00055 sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2);
00056 break;
00057 }
00058 }
00059 }
00060
00061 static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits)
00062 {
00063 switch (bits) {
00064
00065 case 16: {
00066 signed short *s16dst = (signed short*)dst;
00067 s16dst += channel;
00068 sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL);
00069 break;
00070 }
00071 case 24: {
00072 signed int *s32dst = (signed int*)dst;
00073 s32dst += channel;
00074 sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL);
00075 break;
00076 }
00077 case 32: {
00078 signed int *s32dst = (signed int*)dst;
00079 s32dst += channel;
00080 sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL);
00081 break;
00082 }
00083 }
00084 }
00085
00086 void JackOSSAdapter::SetSampleFormat()
00087 {
00088 switch (fBits) {
00089
00090 case 24:
00091 fSampleFormat = AFMT_S24_NE;
00092 fSampleSize = sizeof(int);
00093 break;
00094 case 32:
00095 fSampleFormat = AFMT_S32_NE;
00096 fSampleSize = sizeof(int);
00097 break;
00098 case 16:
00099 default:
00100 fSampleFormat = AFMT_S16_NE;
00101 fSampleSize = sizeof(short);
00102 break;
00103 }
00104 }
00105
00106 JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params)
00107 :JackAudioAdapterInterface(buffer_size, sample_rate)
00108 ,fThread(this),
00109 fInFD(-1), fOutFD(-1), fBits(OSS_DRIVER_DEF_BITS),
00110 fSampleFormat(0), fNperiods(OSS_DRIVER_DEF_NPERIODS), fRWMode(0), fIgnoreHW(true), fExcl(false),
00111 fInputBufferSize(0), fOutputBufferSize(0),
00112 fInputBuffer(NULL), fOutputBuffer(NULL), fFirstCycle(true)
00113 {
00114 const JSList* node;
00115 const jack_driver_param_t* param;
00116
00117 fCaptureChannels = 2;
00118 fPlaybackChannels = 2;
00119
00120 strcpy(fCaptureDriverName, OSS_DRIVER_DEF_DEV);
00121 strcpy(fPlaybackDriverName, OSS_DRIVER_DEF_DEV);
00122
00123 for (node = params; node; node = jack_slist_next(node)) {
00124 param = (const jack_driver_param_t*) node->data;
00125
00126 switch (param->character) {
00127
00128 case 'r':
00129 SetAdaptedSampleRate(param->value.ui);
00130 break;
00131
00132 case 'p':
00133 SetAdaptedBufferSize(param->value.ui);
00134 break;
00135
00136 case 'n':
00137 fNperiods = param->value.ui;
00138 break;
00139
00140 case 'w':
00141 fBits = param->value.i;
00142 break;
00143
00144 case 'i':
00145 fCaptureChannels = param->value.ui;
00146 break;
00147
00148 case 'o':
00149 fPlaybackChannels = param->value.ui;
00150 break;
00151
00152 case 'e':
00153 fExcl = true;
00154 break;
00155
00156 case 'C':
00157 fRWMode |= kRead;
00158 if (strcmp(param->value.str, "none") != 0) {
00159 strcpy(fCaptureDriverName, param->value.str);
00160 }
00161 break;
00162
00163 case 'P':
00164 fRWMode |= kWrite;
00165 if (strcmp(param->value.str, "none") != 0) {
00166 strcpy(fPlaybackDriverName, param->value.str);
00167 }
00168 break;
00169
00170 case 'd':
00171 fRWMode |= kRead;
00172 fRWMode |= kWrite;
00173 strcpy(fCaptureDriverName, param->value.str);
00174 strcpy(fPlaybackDriverName, param->value.str);
00175 break;
00176
00177 case 'b':
00178 fIgnoreHW = true;
00179 break;
00180
00181 case 'q':
00182 fQuality = param->value.ui;
00183 break;
00184
00185 case 'g':
00186 fRingbufferCurSize = param->value.ui;
00187 fAdaptative = false;
00188 break;
00189
00190 }
00191 }
00192
00193 fRWMode |= kRead;
00194 fRWMode |= kWrite;
00195 }
00196
00197 void JackOSSAdapter::DisplayDeviceInfo()
00198 {
00199 audio_buf_info info;
00200 oss_audioinfo ai_in, ai_out;
00201 memset(&info, 0, sizeof(audio_buf_info));
00202 int cap = 0;
00203
00204
00205
00206 jack_info("Audio Interface Description :");
00207 jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fAdaptedSampleRate, fSampleFormat, fRWMode);
00208
00209 if (fRWMode & kWrite) {
00210
00211 oss_sysinfo si;
00212 if (ioctl(fOutFD, OSS_SYSINFO, &si) == -1) {
00213 jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00214 } else {
00215 jack_info("OSS product %s", si.product);
00216 jack_info("OSS version %s", si.version);
00217 jack_info("OSS version num %d", si.versionnum);
00218 jack_info("OSS numaudios %d", si.numaudios);
00219 jack_info("OSS numaudioengines %d", si.numaudioengines);
00220 jack_info("OSS numcards %d", si.numcards);
00221 }
00222
00223 jack_info("Output capabilities - %d channels : ", fPlaybackChannels);
00224 jack_info("Output block size = %d", fOutputBufferSize);
00225
00226 if (ioctl(fOutFD, SNDCTL_DSP_GETOSPACE, &info) == -1) {
00227 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00228 } else {
00229 jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d",
00230 info.fragments, info.fragstotal, info.fragsize, info.bytes);
00231 }
00232
00233 if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) {
00234 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00235 } else {
00236 if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX");
00237 if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME");
00238 if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH");
00239 if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC");
00240 if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER");
00241 if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP");
00242 if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI");
00243 if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND");
00244 }
00245 }
00246
00247 if (fRWMode & kRead) {
00248
00249 oss_sysinfo si;
00250 if (ioctl(fInFD, OSS_SYSINFO, &si) == -1) {
00251 jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00252 } else {
00253 jack_info("OSS product %s", si.product);
00254 jack_info("OSS version %s", si.version);
00255 jack_info("OSS version num %d", si.versionnum);
00256 jack_info("OSS numaudios %d", si.numaudios);
00257 jack_info("OSS numaudioengines %d", si.numaudioengines);
00258 jack_info("OSS numcards %d", si.numcards);
00259 }
00260
00261 jack_info("Input capabilities - %d channels : ", fCaptureChannels);
00262 jack_info("Input block size = %d", fInputBufferSize);
00263
00264 if (ioctl(fInFD, SNDCTL_DSP_GETOSPACE, &info) == -1) {
00265 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00266 } else {
00267 jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d",
00268 info.fragments, info.fragstotal, info.fragsize, info.bytes);
00269 }
00270
00271 if (ioctl(fInFD, SNDCTL_DSP_GETCAPS, &cap) == -1) {
00272 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00273 } else {
00274 if (cap & DSP_CAP_DUPLEX) jack_info(" DSP_CAP_DUPLEX");
00275 if (cap & DSP_CAP_REALTIME) jack_info(" DSP_CAP_REALTIME");
00276 if (cap & DSP_CAP_BATCH) jack_info(" DSP_CAP_BATCH");
00277 if (cap & DSP_CAP_COPROC) jack_info(" DSP_CAP_COPROC");
00278 if (cap & DSP_CAP_TRIGGER) jack_info(" DSP_CAP_TRIGGER");
00279 if (cap & DSP_CAP_MMAP) jack_info(" DSP_CAP_MMAP");
00280 if (cap & DSP_CAP_MULTI) jack_info(" DSP_CAP_MULTI");
00281 if (cap & DSP_CAP_BIND) jack_info(" DSP_CAP_BIND");
00282 }
00283 }
00284
00285 if (ioctl(fInFD, SNDCTL_AUDIOINFO, &ai_in) != -1) {
00286 jack_info("Using audio engine %d = %s for input", ai_in.dev, ai_in.name);
00287 }
00288
00289 if (ioctl(fOutFD, SNDCTL_AUDIOINFO, &ai_out) != -1) {
00290 jack_info("Using audio engine %d = %s for output", ai_out.dev, ai_out.name);
00291 }
00292
00293 if (ai_in.rate_source != ai_out.rate_source) {
00294 jack_info("Warning : input and output are not necessarily driven by the same clock!");
00295 }
00296 }
00297
00298 int JackOSSAdapter::OpenInput()
00299 {
00300 int flags = 0;
00301 int gFragFormat;
00302 int cur_sample_format, cur_capture_channels;
00303 jack_nframes_t cur_sample_rate;
00304
00305 if (fCaptureChannels == 0) fCaptureChannels = 2;
00306
00307 if ((fInFD = open(fCaptureDriverName, O_RDONLY | ((fExcl) ? O_EXCL : 0))) < 0) {
00308 jack_error("JackOSSAdapter::OpenInput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00309 return -1;
00310 }
00311
00312 if (fExcl) {
00313 if (ioctl(fInFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) {
00314 jack_error("JackOSSAdapter::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00315 goto error;
00316 }
00317 }
00318
00319 gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fCaptureChannels);
00320 if (ioctl(fInFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) {
00321 jack_error("JackOSSAdapter::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00322 goto error;
00323 }
00324
00325 cur_sample_format = fSampleFormat;
00326 if (ioctl(fInFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) {
00327 jack_error("JackOSSAdapter::OpenInput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00328 goto error;
00329 }
00330 if (cur_sample_format != fSampleFormat) {
00331 jack_info("JackOSSAdapter::OpenInput driver forced the sample format %ld", fSampleFormat);
00332 }
00333
00334 cur_capture_channels = fCaptureChannels;
00335 if (ioctl(fInFD, SNDCTL_DSP_CHANNELS, &fCaptureChannels) == -1) {
00336 jack_error("JackOSSAdapter::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00337 goto error;
00338 }
00339 if (cur_capture_channels != fCaptureChannels) {
00340 jack_info("JackOSSAdapter::OpenInput driver forced the number of capture channels %ld", fCaptureChannels);
00341 }
00342
00343 cur_sample_rate = fAdaptedSampleRate;
00344 if (ioctl(fInFD, SNDCTL_DSP_SPEED, &fAdaptedSampleRate) == -1) {
00345 jack_error("JackOSSAdapter::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00346 goto error;
00347 }
00348 if (cur_sample_rate != fAdaptedSampleRate) {
00349 jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate);
00350 }
00351
00352 fInputBufferSize = 0;
00353 if (ioctl(fInFD, SNDCTL_DSP_GETBLKSIZE, &fInputBufferSize) == -1) {
00354 jack_error("JackOSSAdapter::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00355 goto error;
00356 }
00357
00358 if (fInputBufferSize != fAdaptedBufferSize * fSampleSize * fCaptureChannels) {
00359 if (fIgnoreHW) {
00360 jack_info("JackOSSAdapter::OpenInput driver forced buffer size %ld", fOutputBufferSize);
00361 } else {
00362 jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained");
00363 goto error;
00364 }
00365 }
00366
00367 fInputBuffer = (void*)calloc(fInputBufferSize, 1);
00368 assert(fInputBuffer);
00369
00370 fInputSampleBuffer = (float**)malloc(fCaptureChannels * sizeof(float*));
00371 assert(fInputSampleBuffer);
00372
00373 for (int i = 0; i < fCaptureChannels; i++) {
00374 fInputSampleBuffer[i] = (float*)malloc(fAdaptedBufferSize * sizeof(float));
00375 assert(fInputSampleBuffer[i]);
00376 }
00377 return 0;
00378
00379 error:
00380 ::close(fInFD);
00381 return -1;
00382 }
00383
00384 int JackOSSAdapter::OpenOutput()
00385 {
00386 int flags = 0;
00387 int gFragFormat;
00388 int cur_sample_format, cur_playback_channels;
00389 jack_nframes_t cur_sample_rate;
00390
00391 if (fPlaybackChannels == 0) fPlaybackChannels = 2;
00392
00393 if ((fOutFD = open(fPlaybackDriverName, O_WRONLY | ((fExcl) ? O_EXCL : 0))) < 0) {
00394 jack_error("JackOSSAdapter::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00395 return -1;
00396 }
00397
00398 if (fExcl) {
00399 if (ioctl(fOutFD, SNDCTL_DSP_COOKEDMODE, &flags) == -1) {
00400 jack_error("JackOSSAdapter::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00401 goto error;
00402 }
00403 }
00404
00405 gFragFormat = (2 << 16) + int2pow2(fAdaptedBufferSize * fSampleSize * fPlaybackChannels);
00406 if (ioctl(fOutFD, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) == -1) {
00407 jack_error("JackOSSAdapter::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00408 goto error;
00409 }
00410
00411 cur_sample_format = fSampleFormat;
00412 if (ioctl(fOutFD, SNDCTL_DSP_SETFMT, &fSampleFormat) == -1) {
00413 jack_error("JackOSSAdapter::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00414 goto error;
00415 }
00416 if (cur_sample_format != fSampleFormat) {
00417 jack_info("JackOSSAdapter::OpenOutput driver forced the sample format %ld", fSampleFormat);
00418 }
00419
00420 cur_playback_channels = fPlaybackChannels;
00421 if (ioctl(fOutFD, SNDCTL_DSP_CHANNELS, &fPlaybackChannels) == -1) {
00422 jack_error("JackOSSAdapter::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00423 goto error;
00424 }
00425 if (cur_playback_channels != fPlaybackChannels) {
00426 jack_info("JackOSSAdapter::OpenOutput driver forced the number of playback channels %ld", fPlaybackChannels);
00427 }
00428
00429 cur_sample_rate = fAdaptedSampleRate;
00430 if (ioctl(fOutFD, SNDCTL_DSP_SPEED, &fAdaptedSampleRate) == -1) {
00431 jack_error("JackOSSAdapter::OpenOutput failed to set sample rate : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00432 goto error;
00433 }
00434 if (cur_sample_rate != fAdaptedSampleRate) {
00435 jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate);
00436 }
00437
00438 fOutputBufferSize = 0;
00439 if (ioctl(fOutFD, SNDCTL_DSP_GETBLKSIZE, &fOutputBufferSize) == -1) {
00440 jack_error("JackOSSAdapter::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00441 goto error;
00442 }
00443
00444 if (fOutputBufferSize != fAdaptedBufferSize * fSampleSize * fPlaybackChannels) {
00445 if (fIgnoreHW) {
00446 jack_info("JackOSSAdapter::OpenOutput driver forced buffer size %ld", fOutputBufferSize);
00447 } else {
00448 jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained");
00449 goto error;
00450 }
00451 }
00452
00453 fOutputBuffer = (void*)calloc(fOutputBufferSize, 1);
00454 assert(fOutputBuffer);
00455
00456 fOutputSampleBuffer = (float**)malloc(fPlaybackChannels * sizeof(float*));
00457 assert(fOutputSampleBuffer);
00458
00459 for (int i = 0; i < fPlaybackChannels; i++) {
00460 fOutputSampleBuffer[i] = (float*)malloc(fAdaptedBufferSize * sizeof(float));
00461 assert(fOutputSampleBuffer[i]);
00462 }
00463
00464 fFirstCycle = true;
00465 return 0;
00466
00467 error:
00468 ::close(fOutFD);
00469 return -1;
00470 }
00471
00472 int JackOSSAdapter::Open()
00473 {
00474 SetSampleFormat();
00475
00476 if ((fRWMode & kRead) && (OpenInput() < 0)) {
00477 return -1;
00478 }
00479
00480 if ((fRWMode & kWrite) && (OpenOutput() < 0)) {
00481 return -1;
00482 }
00483
00484
00485 if ((fRWMode & kRead) && (fRWMode & kWrite) && (fInputBufferSize != fOutputBufferSize)) {
00486 jack_error("JackOSSAdapter::OpenAux input and output buffer size are not the same!!");
00487 goto error;
00488 }
00489
00490 DisplayDeviceInfo();
00491
00492
00493 if (fThread.StartSync() < 0) {
00494 jack_error ( "Cannot start audioadapter thread" );
00495 return -1;
00496 }
00497
00498
00499 fThread.AcquireRealTime(JackServerGlobals::fInstance->GetEngineControl()->fClientPriority);
00500 return 0;
00501
00502 error:
00503 CloseAux();
00504 return -1;
00505 }
00506
00507
00508 int JackOSSAdapter::Close()
00509 {
00510 #ifdef JACK_MONITOR
00511 fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
00512 #endif
00513 fThread.Stop();
00514 CloseAux();
00515 return 0;
00516 }
00517
00518 void JackOSSAdapter::CloseAux()
00519 {
00520 if (fRWMode & kRead) {
00521 close(fInFD);
00522 fInFD = -1;
00523 }
00524
00525 if (fRWMode & kWrite) {
00526 close(fOutFD);
00527 fOutFD = -1;
00528 }
00529
00530 free(fInputBuffer);
00531 fInputBuffer = NULL;
00532
00533 free(fOutputBuffer);
00534 fOutputBuffer = NULL;
00535
00536 for (int i = 0; i < fCaptureChannels; i++) {
00537 free(fInputSampleBuffer[i]);
00538 }
00539 free(fInputSampleBuffer);
00540
00541 for (int i = 0; i < fPlaybackChannels; i++) {
00542 free(fOutputSampleBuffer[i]);
00543 }
00544 free(fOutputSampleBuffer);
00545 }
00546
00547 int JackOSSAdapter::Read()
00548 {
00549 ssize_t count = ::read(fInFD, fInputBuffer, fInputBufferSize);
00550
00551 if (count < fInputBufferSize) {
00552 jack_error("JackOSSAdapter::Read error bytes read = %ld", count);
00553 return -1;
00554 } else {
00555 for (int i = 0; i < fCaptureChannels; i++) {
00556 CopyAndConvertIn(fInputSampleBuffer[i], fInputBuffer, fAdaptedBufferSize, i, fCaptureChannels, fBits);
00557 }
00558 return 0;
00559 }
00560 }
00561
00562 int JackOSSAdapter::Write()
00563 {
00564 ssize_t count;
00565
00566
00567 if (fFirstCycle) {
00568
00569 fFirstCycle = false;
00570 memset(fOutputBuffer, 0, fOutputBufferSize);
00571
00572
00573 for (int i = 0; i < fNperiods; i++) {
00574 count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize);
00575 if (count < fOutputBufferSize) {
00576 jack_error("JackOSSDriver::Write error bytes written = %ld", count);
00577 return -1;
00578 }
00579 }
00580
00581 int delay;
00582 if (ioctl(fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) {
00583 jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno);
00584 return -1;
00585 }
00586
00587 delay /= fSampleSize * fPlaybackChannels;
00588 jack_info("JackOSSDriver::Write output latency frames = %ld", delay);
00589 }
00590
00591 for (int i = 0; i < fPlaybackChannels; i++) {
00592 CopyAndConvertOut(fOutputBuffer, fOutputSampleBuffer[i], fAdaptedBufferSize, i, fCaptureChannels, fBits);
00593 }
00594
00595 count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize);
00596
00597 if (count < fOutputBufferSize) {
00598 jack_error("JackOSSAdapter::Write error bytes written = %ld", count);
00599 return -1;
00600 } else {
00601 return 0;
00602 }
00603 }
00604
00605 bool JackOSSAdapter::Execute()
00606 {
00607
00608 if (Read() < 0)
00609 return false;
00610
00611 PushAndPull(fInputSampleBuffer, fOutputSampleBuffer, fAdaptedBufferSize);
00612
00613
00614 if (Write() < 0)
00615 return false;
00616
00617 return true;
00618 }
00619
00620 int JackOSSAdapter::SetBufferSize(jack_nframes_t buffer_size)
00621 {
00622 JackAudioAdapterInterface::SetBufferSize(buffer_size);
00623 Close();
00624 return Open();
00625 }
00626
00627 }
00628
00629 #ifdef __cplusplus
00630 extern "C"
00631 {
00632 #endif
00633
00634 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
00635 {
00636 jack_driver_desc_t * desc;
00637 jack_driver_desc_filler_t filler;
00638 jack_driver_param_value_t value;
00639
00640 desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler);
00641
00642 value.ui = OSS_DRIVER_DEF_FS;
00643 jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
00644
00645 value.ui = OSS_DRIVER_DEF_BLKSIZE;
00646 jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
00647
00648 value.ui = OSS_DRIVER_DEF_NPERIODS;
00649 jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods to prefill output buffer", NULL);
00650
00651 value.i = OSS_DRIVER_DEF_BITS;
00652 jack_driver_descriptor_add_parameter(desc, &filler, "wordlength", 'w', JackDriverParamInt, &value, NULL, "Word length", NULL);
00653
00654 value.ui = OSS_DRIVER_DEF_INS;
00655 jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamUInt, &value, NULL, "Capture channels", NULL);
00656
00657 value.ui = OSS_DRIVER_DEF_OUTS;
00658 jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamUInt, &value, NULL, "Playback channels", NULL);
00659
00660 value.i = false;
00661 jack_driver_descriptor_add_parameter(desc, &filler, "excl", 'e', JackDriverParamBool, &value, NULL, "Exclusif (O_EXCL) access mode", NULL);
00662
00663 strcpy(value.str, OSS_DRIVER_DEF_DEV);
00664 jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input device", NULL);
00665 jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Output device", NULL);
00666 jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "OSS device name", NULL);
00667
00668 value.i = true;
00669 jack_driver_descriptor_add_parameter(desc, &filler, "ignorehwbuf", 'b', JackDriverParamBool, &value, NULL, "Ignore hardware period size", NULL);
00670
00671 value.ui = 0;
00672 jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL);
00673
00674 value.i = 32768;
00675 jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)");
00676
00677 return desc;
00678 }
00679
00680 #ifdef __cplusplus
00681 }
00682 #endif
00683