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); 
    72                         signed int *s32dst = (
signed int*)dst;
    74             sample_move_d24_sS((
char*)s32dst, src, nframes, chcount<<2, NULL); 
    78             signed int *s32dst = (
signed int*)dst;
    80             sample_move_d32u24_sS((
char*)s32dst, src, nframes, chcount<<2, NULL);
    86 void JackOSSAdapter::SetSampleFormat()
    91             fSampleFormat = AFMT_S24_NE;
    92             fSampleSize = 
sizeof(int);
    95             fSampleFormat = AFMT_S32_NE;
    96             fSampleSize = 
sizeof(int);
   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)
   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)) {
   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));
   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);
   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);
   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)) {
   485     if ((fRWMode & kRead) && (fRWMode & kWrite) && (fInputBufferSize != fOutputBufferSize)) {
   486        jack_error(
"JackOSSAdapter::OpenAux input and output buffer size are not the same!!");
   493     if (fThread.StartSync() < 0) {
   494         jack_error ( 
"Cannot start audioadapter thread" );
   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()
   570         memset(fOutputBuffer, 0, fOutputBufferSize);
   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()
   611     PushAndPull(fInputSampleBuffer, fOutputSampleBuffer, fAdaptedBufferSize);
   620 int JackOSSAdapter::SetBufferSize(jack_nframes_t buffer_size)
   622     JackAudioAdapterInterface::SetBufferSize(buffer_size);
   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)");
 
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)