2 Copyright (C) 2008 Grame & RTL 2008
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "JackOSSAdapter.h"
21 #include "JackServerGlobals.h"
22 #include "JackEngineControl.h"
25 #include <sys/ioctl.h>
26 #include <sys/soundcard.h>
34 inline int int2pow2(int x
) { int r
= 0; while ((1 << r
) < x
) r
++; return r
; }
36 static inline void CopyAndConvertIn(jack_sample_t
*dst
, void *src
, size_t nframes
, int channel
, int chcount
, int bits
)
41 signed short *s16src
= (signed short*)src
;
43 sample_move_dS_s16(dst
, (char*)s16src
, nframes
, chcount
<<1);
47 signed int *s32src
= (signed int*)src
;
49 sample_move_dS_s24(dst
, (char*)s32src
, nframes
, chcount
<<2);
53 signed int *s32src
= (signed int*)src
;
55 sample_move_dS_s32u24(dst
, (char*)s32src
, nframes
, chcount
<<2);
61 static inline void CopyAndConvertOut(void *dst
, jack_sample_t
*src
, size_t nframes
, int channel
, int chcount
, int bits
)
66 signed short *s16dst
= (signed short*)dst
;
68 sample_move_d16_sS((char*)s16dst
, src
, nframes
, chcount
<<1, NULL
); // No dithering for now...
72 signed int *s32dst
= (signed int*)dst
;
74 sample_move_d24_sS((char*)s32dst
, src
, nframes
, chcount
<<2, NULL
); // No dithering for now...
78 signed int *s32dst
= (signed int*)dst
;
80 sample_move_d32u24_sS((char*)s32dst
, src
, nframes
, chcount
<<2, NULL
);
86 void JackOSSAdapter::SetSampleFormat()
90 case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */
91 fSampleFormat
= AFMT_S24_NE
;
92 fSampleSize
= sizeof(int);
94 case 32: /* native-endian 32-bit integer */
95 fSampleFormat
= AFMT_S32_NE
;
96 fSampleSize
= sizeof(int);
98 case 16: /* native-endian 16-bit integer */
100 fSampleFormat
= AFMT_S16_NE
;
101 fSampleSize
= sizeof(short);
106 JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size
, jack_nframes_t sample_rate
, const JSList
* params
)
107 :JackAudioAdapterInterface(buffer_size
, sample_rate
)
109 fInFD(-1), fOutFD(-1), fBits(OSS_DRIVER_DEF_BITS
),
110 fSampleFormat(0), fNperiods(OSS_DRIVER_DEF_NPERIODS
), fRWMode(0), fIgnoreHW(true), fExcl(false),
111 fInputBufferSize(0), fOutputBufferSize(0),
112 fInputBuffer(NULL
), fOutputBuffer(NULL
), fFirstCycle(true)
115 const jack_driver_param_t
* param
;
117 fCaptureChannels
= 2;
118 fPlaybackChannels
= 2;
120 strcpy(fCaptureDriverName
, OSS_DRIVER_DEF_DEV
);
121 strcpy(fPlaybackDriverName
, OSS_DRIVER_DEF_DEV
);
123 for (node
= params
; node
; node
= jack_slist_next(node
)) {
124 param
= (const jack_driver_param_t
*) node
->data
;
126 switch (param
->character
) {
129 SetAdaptedSampleRate(param
->value
.ui
);
133 SetAdaptedBufferSize(param
->value
.ui
);
137 fNperiods
= param
->value
.ui
;
141 fBits
= param
->value
.i
;
145 fCaptureChannels
= param
->value
.ui
;
149 fPlaybackChannels
= param
->value
.ui
;
158 if (strcmp(param
->value
.str
, "none") != 0) {
159 strcpy(fCaptureDriverName
, param
->value
.str
);
165 if (strcmp(param
->value
.str
, "none") != 0) {
166 strcpy(fPlaybackDriverName
, param
->value
.str
);
173 strcpy(fCaptureDriverName
, param
->value
.str
);
174 strcpy(fPlaybackDriverName
, param
->value
.str
);
182 fQuality
= param
->value
.ui
;
186 fRingbufferCurSize
= param
->value
.ui
;
197 void JackOSSAdapter::DisplayDeviceInfo()
200 oss_audioinfo ai_in
, ai_out
;
201 memset(&info
, 0, sizeof(audio_buf_info
));
204 // Duplex cards : http://manuals.opensound.com/developer/full_duplex.html
206 jack_info("Audio Interface Description :");
207 jack_info("Sampling Frequency : %d, Sample Format : %d, Mode : %d", fAdaptedSampleRate
, fSampleFormat
, fRWMode
);
209 if (fRWMode
& kWrite
) {
212 if (ioctl(fOutFD
, OSS_SYSINFO
, &si
) == -1) {
213 jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
215 jack_info("OSS product %s", si
.product
);
216 jack_info("OSS version %s", si
.version
);
217 jack_info("OSS version num %d", si
.versionnum
);
218 jack_info("OSS numaudios %d", si
.numaudios
);
219 jack_info("OSS numaudioengines %d", si
.numaudioengines
);
220 jack_info("OSS numcards %d", si
.numcards
);
223 jack_info("Output capabilities - %d channels : ", fPlaybackChannels
);
224 jack_info("Output block size = %d", fOutputBufferSize
);
226 if (ioctl(fOutFD
, SNDCTL_DSP_GETOSPACE
, &info
) == -1) {
227 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
229 jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d",
230 info
.fragments
, info
.fragstotal
, info
.fragsize
, info
.bytes
);
233 if (ioctl(fOutFD
, SNDCTL_DSP_GETCAPS
, &cap
) == -1) {
234 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
236 if (cap
& DSP_CAP_DUPLEX
) jack_info(" DSP_CAP_DUPLEX");
237 if (cap
& DSP_CAP_REALTIME
) jack_info(" DSP_CAP_REALTIME");
238 if (cap
& DSP_CAP_BATCH
) jack_info(" DSP_CAP_BATCH");
239 if (cap
& DSP_CAP_COPROC
) jack_info(" DSP_CAP_COPROC");
240 if (cap
& DSP_CAP_TRIGGER
) jack_info(" DSP_CAP_TRIGGER");
241 if (cap
& DSP_CAP_MMAP
) jack_info(" DSP_CAP_MMAP");
242 if (cap
& DSP_CAP_MULTI
) jack_info(" DSP_CAP_MULTI");
243 if (cap
& DSP_CAP_BIND
) jack_info(" DSP_CAP_BIND");
247 if (fRWMode
& kRead
) {
250 if (ioctl(fInFD
, OSS_SYSINFO
, &si
) == -1) {
251 jack_error("JackOSSAdapter::DisplayDeviceInfo OSS_SYSINFO failed : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
253 jack_info("OSS product %s", si
.product
);
254 jack_info("OSS version %s", si
.version
);
255 jack_info("OSS version num %d", si
.versionnum
);
256 jack_info("OSS numaudios %d", si
.numaudios
);
257 jack_info("OSS numaudioengines %d", si
.numaudioengines
);
258 jack_info("OSS numcards %d", si
.numcards
);
261 jack_info("Input capabilities - %d channels : ", fCaptureChannels
);
262 jack_info("Input block size = %d", fInputBufferSize
);
264 if (ioctl(fInFD
, SNDCTL_DSP_GETOSPACE
, &info
) == -1) {
265 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETOSPACE failed : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
267 jack_info("input space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d",
268 info
.fragments
, info
.fragstotal
, info
.fragsize
, info
.bytes
);
271 if (ioctl(fInFD
, SNDCTL_DSP_GETCAPS
, &cap
) == -1) {
272 jack_error("JackOSSAdapter::DisplayDeviceInfo SNDCTL_DSP_GETCAPS failed : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
274 if (cap
& DSP_CAP_DUPLEX
) jack_info(" DSP_CAP_DUPLEX");
275 if (cap
& DSP_CAP_REALTIME
) jack_info(" DSP_CAP_REALTIME");
276 if (cap
& DSP_CAP_BATCH
) jack_info(" DSP_CAP_BATCH");
277 if (cap
& DSP_CAP_COPROC
) jack_info(" DSP_CAP_COPROC");
278 if (cap
& DSP_CAP_TRIGGER
) jack_info(" DSP_CAP_TRIGGER");
279 if (cap
& DSP_CAP_MMAP
) jack_info(" DSP_CAP_MMAP");
280 if (cap
& DSP_CAP_MULTI
) jack_info(" DSP_CAP_MULTI");
281 if (cap
& DSP_CAP_BIND
) jack_info(" DSP_CAP_BIND");
285 if (ioctl(fInFD
, SNDCTL_AUDIOINFO
, &ai_in
) != -1) {
286 jack_info("Using audio engine %d = %s for input", ai_in
.dev
, ai_in
.name
);
289 if (ioctl(fOutFD
, SNDCTL_AUDIOINFO
, &ai_out
) != -1) {
290 jack_info("Using audio engine %d = %s for output", ai_out
.dev
, ai_out
.name
);
293 if (ai_in
.rate_source
!= ai_out
.rate_source
) {
294 jack_info("Warning : input and output are not necessarily driven by the same clock!");
298 int JackOSSAdapter::OpenInput()
302 int cur_sample_format
, cur_capture_channels
;
303 jack_nframes_t cur_sample_rate
;
305 if (fCaptureChannels
== 0) fCaptureChannels
= 2;
307 if ((fInFD
= open(fCaptureDriverName
, O_RDONLY
| ((fExcl
) ? O_EXCL
: 0))) < 0) {
308 jack_error("JackOSSAdapter::OpenInput failed to open device : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
313 if (ioctl(fInFD
, SNDCTL_DSP_COOKEDMODE
, &flags
) == -1) {
314 jack_error("JackOSSAdapter::OpenInput failed to set cooked mode : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
319 gFragFormat
= (2 << 16) + int2pow2(fAdaptedBufferSize
* fSampleSize
* fCaptureChannels
);
320 if (ioctl(fInFD
, SNDCTL_DSP_SETFRAGMENT
, &gFragFormat
) == -1) {
321 jack_error("JackOSSAdapter::OpenInput failed to set fragments : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
325 cur_sample_format
= fSampleFormat
;
326 if (ioctl(fInFD
, SNDCTL_DSP_SETFMT
, &fSampleFormat
) == -1) {
327 jack_error("JackOSSAdapter::OpenInput failed to set format : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
330 if (cur_sample_format
!= fSampleFormat
) {
331 jack_info("JackOSSAdapter::OpenInput driver forced the sample format %ld", fSampleFormat
);
334 cur_capture_channels
= fCaptureChannels
;
335 if (ioctl(fInFD
, SNDCTL_DSP_CHANNELS
, &fCaptureChannels
) == -1) {
336 jack_error("JackOSSAdapter::OpenInput failed to set channels : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
339 if (cur_capture_channels
!= fCaptureChannels
) {
340 jack_info("JackOSSAdapter::OpenInput driver forced the number of capture channels %ld", fCaptureChannels
);
343 cur_sample_rate
= fAdaptedSampleRate
;
344 if (ioctl(fInFD
, SNDCTL_DSP_SPEED
, &fAdaptedSampleRate
) == -1) {
345 jack_error("JackOSSAdapter::OpenInput failed to set sample rate : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
348 if (cur_sample_rate
!= fAdaptedSampleRate
) {
349 jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate
);
352 fInputBufferSize
= 0;
353 if (ioctl(fInFD
, SNDCTL_DSP_GETBLKSIZE
, &fInputBufferSize
) == -1) {
354 jack_error("JackOSSAdapter::OpenInput failed to get fragments : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
358 if (fInputBufferSize
!= fAdaptedBufferSize
* fSampleSize
* fCaptureChannels
) {
360 jack_info("JackOSSAdapter::OpenInput driver forced buffer size %ld", fOutputBufferSize
);
362 jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained");
367 fInputBuffer
= (void*)calloc(fInputBufferSize
, 1);
368 assert(fInputBuffer
);
370 fInputSampleBuffer
= (float**)malloc(fCaptureChannels
* sizeof(float*));
371 assert(fInputSampleBuffer
);
373 for (int i
= 0; i
< fCaptureChannels
; i
++) {
374 fInputSampleBuffer
[i
] = (float*)malloc(fAdaptedBufferSize
* sizeof(float));
375 assert(fInputSampleBuffer
[i
]);
384 int JackOSSAdapter::OpenOutput()
388 int cur_sample_format
, cur_playback_channels
;
389 jack_nframes_t cur_sample_rate
;
391 if (fPlaybackChannels
== 0) fPlaybackChannels
= 2;
393 if ((fOutFD
= open(fPlaybackDriverName
, O_WRONLY
| ((fExcl
) ? O_EXCL
: 0))) < 0) {
394 jack_error("JackOSSAdapter::OpenOutput failed to open device : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
399 if (ioctl(fOutFD
, SNDCTL_DSP_COOKEDMODE
, &flags
) == -1) {
400 jack_error("JackOSSAdapter::OpenOutput failed to set cooked mode : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
405 gFragFormat
= (2 << 16) + int2pow2(fAdaptedBufferSize
* fSampleSize
* fPlaybackChannels
);
406 if (ioctl(fOutFD
, SNDCTL_DSP_SETFRAGMENT
, &gFragFormat
) == -1) {
407 jack_error("JackOSSAdapter::OpenOutput failed to set fragments : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
411 cur_sample_format
= fSampleFormat
;
412 if (ioctl(fOutFD
, SNDCTL_DSP_SETFMT
, &fSampleFormat
) == -1) {
413 jack_error("JackOSSAdapter::OpenOutput failed to set format : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
416 if (cur_sample_format
!= fSampleFormat
) {
417 jack_info("JackOSSAdapter::OpenOutput driver forced the sample format %ld", fSampleFormat
);
420 cur_playback_channels
= fPlaybackChannels
;
421 if (ioctl(fOutFD
, SNDCTL_DSP_CHANNELS
, &fPlaybackChannels
) == -1) {
422 jack_error("JackOSSAdapter::OpenOutput failed to set channels : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
425 if (cur_playback_channels
!= fPlaybackChannels
) {
426 jack_info("JackOSSAdapter::OpenOutput driver forced the number of playback channels %ld", fPlaybackChannels
);
429 cur_sample_rate
= fAdaptedSampleRate
;
430 if (ioctl(fOutFD
, SNDCTL_DSP_SPEED
, &fAdaptedSampleRate
) == -1) {
431 jack_error("JackOSSAdapter::OpenOutput failed to set sample rate : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
434 if (cur_sample_rate
!= fAdaptedSampleRate
) {
435 jack_info("JackOSSAdapter::OpenInput driver forced the sample rate %ld", fAdaptedSampleRate
);
438 fOutputBufferSize
= 0;
439 if (ioctl(fOutFD
, SNDCTL_DSP_GETBLKSIZE
, &fOutputBufferSize
) == -1) {
440 jack_error("JackOSSAdapter::OpenOutput failed to get fragments : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
444 if (fOutputBufferSize
!= fAdaptedBufferSize
* fSampleSize
* fPlaybackChannels
) {
446 jack_info("JackOSSAdapter::OpenOutput driver forced buffer size %ld", fOutputBufferSize
);
448 jack_error("JackOSSAdapter::OpenInput wanted buffer size cannot be obtained");
453 fOutputBuffer
= (void*)calloc(fOutputBufferSize
, 1);
454 assert(fOutputBuffer
);
456 fOutputSampleBuffer
= (float**)malloc(fPlaybackChannels
* sizeof(float*));
457 assert(fOutputSampleBuffer
);
459 for (int i
= 0; i
< fPlaybackChannels
; i
++) {
460 fOutputSampleBuffer
[i
] = (float*)malloc(fAdaptedBufferSize
* sizeof(float));
461 assert(fOutputSampleBuffer
[i
]);
472 int JackOSSAdapter::Open()
476 if ((fRWMode
& kRead
) && (OpenInput() < 0)) {
480 if ((fRWMode
& kWrite
) && (OpenOutput() < 0)) {
484 // In duplex mode, check that input and output use the same buffer size
485 if ((fRWMode
& kRead
) && (fRWMode
& kWrite
) && (fInputBufferSize
!= fOutputBufferSize
)) {
486 jack_error("JackOSSAdapter::OpenAux input and output buffer size are not the same!!");
492 //start adapter thread
493 if (fThread
.StartSync() < 0) {
494 jack_error ( "Cannot start audioadapter thread" );
498 //turn the thread realtime
499 fThread
.AcquireRealTime(JackServerGlobals::fInstance
->GetEngineControl()->fClientPriority
);
508 int JackOSSAdapter::Close()
511 fTable
.Save(fHostBufferSize
, fHostSampleRate
, fAdaptedSampleRate
, fAdaptedBufferSize
);
518 void JackOSSAdapter::CloseAux()
520 if (fRWMode
& kRead
) {
525 if (fRWMode
& kWrite
) {
534 fOutputBuffer
= NULL
;
536 for (int i
= 0; i
< fCaptureChannels
; i
++) {
537 free(fInputSampleBuffer
[i
]);
539 free(fInputSampleBuffer
);
541 for (int i
= 0; i
< fPlaybackChannels
; i
++) {
542 free(fOutputSampleBuffer
[i
]);
544 free(fOutputSampleBuffer
);
547 int JackOSSAdapter::Read()
549 ssize_t count
= ::read(fInFD
, fInputBuffer
, fInputBufferSize
);
551 if (count
< fInputBufferSize
) {
552 jack_error("JackOSSAdapter::Read error bytes read = %ld", count
);
555 for (int i
= 0; i
< fCaptureChannels
; i
++) {
556 CopyAndConvertIn(fInputSampleBuffer
[i
], fInputBuffer
, fAdaptedBufferSize
, i
, fCaptureChannels
, fBits
);
562 int JackOSSAdapter::Write()
566 // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html
570 memset(fOutputBuffer
, 0, fOutputBufferSize
);
572 // Prefill output buffer
573 for (int i
= 0; i
< fNperiods
; i
++) {
574 count
= ::write(fOutFD
, fOutputBuffer
, fOutputBufferSize
);
575 if (count
< fOutputBufferSize
) {
576 jack_error("JackOSSDriver::Write error bytes written = %ld", count
);
582 if (ioctl(fOutFD
, SNDCTL_DSP_GETODELAY
, &delay
) == -1) {
583 jack_error("JackOSSDriver::Write error get out delay : %s@%i, errno = %d", __FILE__
, __LINE__
, errno
);
587 delay
/= fSampleSize
* fPlaybackChannels
;
588 jack_info("JackOSSDriver::Write output latency frames = %ld", delay
);
591 for (int i
= 0; i
< fPlaybackChannels
; i
++) {
592 CopyAndConvertOut(fOutputBuffer
, fOutputSampleBuffer
[i
], fAdaptedBufferSize
, i
, fCaptureChannels
, fBits
);
595 count
= ::write(fOutFD
, fOutputBuffer
, fOutputBufferSize
);
597 if (count
< fOutputBufferSize
) {
598 jack_error("JackOSSAdapter::Write error bytes written = %ld", count
);
605 bool JackOSSAdapter::Execute()
607 //read data from audio interface
611 PushAndPull(fInputSampleBuffer
, fOutputSampleBuffer
, fAdaptedBufferSize
);
613 //write data to audio interface
620 int JackOSSAdapter::SetBufferSize(jack_nframes_t buffer_size
)
622 JackAudioAdapterInterface::SetBufferSize(buffer_size
);
634 SERVER_EXPORT jack_driver_desc_t
* jack_get_descriptor()
636 jack_driver_desc_t
* desc
;
637 jack_driver_desc_filler_t filler
;
638 jack_driver_param_value_t value
;
640 desc
= jack_driver_descriptor_construct("audioadapter", JackDriverNone
, "netjack audio <==> net backend adapter", &filler
);
642 value
.ui
= OSS_DRIVER_DEF_FS
;
643 jack_driver_descriptor_add_parameter(desc
, &filler
, "rate", 'r', JackDriverParamUInt
, &value
, NULL
, "Sample rate", NULL
);
645 value
.ui
= OSS_DRIVER_DEF_BLKSIZE
;
646 jack_driver_descriptor_add_parameter(desc
, &filler
, "period", 'p', JackDriverParamUInt
, &value
, NULL
, "Frames per period", NULL
);
648 value
.ui
= OSS_DRIVER_DEF_NPERIODS
;
649 jack_driver_descriptor_add_parameter(desc
, &filler
, "nperiods", 'n', JackDriverParamUInt
, &value
, NULL
, "Number of periods to prefill output buffer", NULL
);
651 value
.i
= OSS_DRIVER_DEF_BITS
;
652 jack_driver_descriptor_add_parameter(desc
, &filler
, "wordlength", 'w', JackDriverParamInt
, &value
, NULL
, "Word length", NULL
);
654 value
.ui
= OSS_DRIVER_DEF_INS
;
655 jack_driver_descriptor_add_parameter(desc
, &filler
, "in-channels", 'i', JackDriverParamUInt
, &value
, NULL
, "Capture channels", NULL
);
657 value
.ui
= OSS_DRIVER_DEF_OUTS
;
658 jack_driver_descriptor_add_parameter(desc
, &filler
, "out-channels", 'o', JackDriverParamUInt
, &value
, NULL
, "Playback channels", NULL
);
661 jack_driver_descriptor_add_parameter(desc
, &filler
, "excl", 'e', JackDriverParamBool
, &value
, NULL
, "Exclusif (O_EXCL) access mode", NULL
);
663 strcpy(value
.str
, OSS_DRIVER_DEF_DEV
);
664 jack_driver_descriptor_add_parameter(desc
, &filler
, "capture", 'C', JackDriverParamString
, &value
, NULL
, "Input device", NULL
);
665 jack_driver_descriptor_add_parameter(desc
, &filler
, "playback", 'P', JackDriverParamString
, &value
, NULL
, "Output device", NULL
);
666 jack_driver_descriptor_add_parameter(desc
, &filler
, "device", 'd', JackDriverParamString
, &value
, NULL
, "OSS device name", NULL
);
669 jack_driver_descriptor_add_parameter(desc
, &filler
, "ignorehwbuf", 'b', JackDriverParamBool
, &value
, NULL
, "Ignore hardware period size", NULL
);
672 jack_driver_descriptor_add_parameter(desc
, &filler
, "quality", 'q', JackDriverParamInt
, &value
, NULL
, "Resample algorithm quality (0 - 4)", NULL
);
675 jack_driver_descriptor_add_parameter(desc
, &filler
, "ring-buffer", 'g', JackDriverParamInt
, &value
, NULL
, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)");