20 #ifndef __JackAlsaAdapter__    21 #define __JackAlsaAdapter__    26 #include <alsa/asoundlib.h>    27 #include "JackAudioAdapterInterface.h"    28 #include "JackPlatformPlug.h"    29 #include "JackError.h"    36     inline void* aligned_calloc ( 
size_t nmemb, 
size_t size ) { 
return ( 
void* ) calloc ( nmemb, size ); }
    38 #define max(x,y) (((x)>(y)) ? (x) : (y))    39 #define min(x,y) (((x)<(y)) ? (x) : (y))    41 #define check_error(err) if (err) { jack_error("%s:%d, alsa error %d : %s", __FILE__, __LINE__, err, snd_strerror(err)); return err; }    42 #define check_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); return err; }    43 #define display_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); }    51             const char*     fCardName;
    52             unsigned int    fFrequency;
    55             unsigned int    fSoftInputs;
    56             unsigned int    fSoftOutputs;
    67             AudioParam ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
    69                     fFrequency ( sample_rate ),
    70                     fBuffering ( buffer_size ),
    93             void setInputs ( 
int inputs )
   104             void setOutputs ( 
int outputs )
   106                 fSoftOutputs = outputs;
   123             snd_pcm_t*  fOutputDevice;
   124             snd_pcm_t*  fInputDevice;
   125             snd_pcm_hw_params_t* fInputParams;
   126             snd_pcm_hw_params_t* fOutputParams;
   129             snd_pcm_format_t fSampleFormat;
   130             snd_pcm_access_t fSampleAccess;
   133             const char*  fCaptureName;
   134             const char*  fPlaybackName;
   135             unsigned int fCardInputs;
   136             unsigned int fCardOutputs;
   139             unsigned int fPeriod;
   142             void* fInputCardBuffer;
   143             void* fOutputCardBuffer;
   146             void* fInputCardChannels[256];
   147             void* fOutputCardChannels[256];
   150             jack_default_audio_sample_t* fInputSoftChannels[256];
   151             jack_default_audio_sample_t* fOutputSoftChannels[256];
   155             const char* cardName()
   170             jack_default_audio_sample_t** inputSoftChannels()
   172                 return fInputSoftChannels;
   175             jack_default_audio_sample_t** outputSoftChannels()
   177                 return fOutputSoftChannels;
   188                 fPlaybackName   = NULL;
   190                 fInputCardBuffer = 0;
   191                 fOutputCardBuffer = 0;
   193                 for ( 
int i = 0; i < 256; i++ )
   195                     fInputCardChannels[i] = 0;
   196                     fOutputCardChannels[i] = 0;
   197                     fInputSoftChannels[i] = 0;
   198                     fOutputSoftChannels[i] = 0;
   202             AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
   205                 fInputCardBuffer = 0;
   206                 fOutputCardBuffer = 0;
   208                 fPlaybackName   = NULL;
   210                 for ( 
int i = 0; i < 256; i++ )
   212                     fInputCardChannels[i] = 0;
   213                     fOutputCardChannels[i] = 0;
   214                     fInputSoftChannels[i] = 0;
   215                     fOutputSoftChannels[i] = 0;
   225                 check_error ( snd_pcm_open ( &fInputDevice,  (fCaptureName == NULL) ? fCardName : fCaptureName, SND_PCM_STREAM_CAPTURE, 0 ) );
   226                 check_error ( snd_pcm_open ( &fOutputDevice, (fPlaybackName == NULL) ? fCardName : fPlaybackName, SND_PCM_STREAM_PLAYBACK, 0 ) );
   229                 check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) );
   230                 setAudioParams ( fInputDevice, fInputParams );
   233                 check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) )
   234                 setAudioParams ( fOutputDevice, fOutputParams );
   237                 fCardInputs     = fSoftInputs;
   238                 fCardOutputs    = fSoftOutputs;
   240                 snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
   241                 snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
   244                 check_error ( snd_pcm_hw_params ( fInputDevice,  fInputParams ) );
   245                 check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) );
   248                 if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED )
   250                     fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 );
   251                     fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 );
   255                     for ( 
unsigned int i = 0; i < fCardInputs; i++ )
   256                         fInputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fInputParams ), 1 );
   257                     for ( 
unsigned int i = 0; i < fCardOutputs; i++ )
   258                         fOutputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fOutputParams ), 1 );
   262                 fSoftInputs = max ( fSoftInputs, fCardInputs );
   263                 assert ( fSoftInputs < 256 );
   264                 fSoftOutputs = max ( fSoftOutputs, fCardOutputs );
   265                 assert ( fSoftOutputs < 256 );
   267                 for ( 
unsigned int i = 0; i < fSoftInputs; i++ )
   269                     fInputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, 
sizeof ( jack_default_audio_sample_t ) );
   270                     for ( 
int j = 0; j < fBuffering; j++ )
   271                         fInputSoftChannels[i][j] = 0.0;
   274                 for ( 
unsigned int i = 0; i < fSoftOutputs; i++ )
   276                     fOutputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, 
sizeof ( jack_default_audio_sample_t ) );
   277                     for ( 
int j = 0; j < fBuffering; j++ )
   278                         fOutputSoftChannels[i][j] = 0.0;
   285                 snd_pcm_hw_params_free ( fInputParams );
   286                 snd_pcm_hw_params_free ( fOutputParams );
   287                 snd_pcm_close ( fInputDevice );
   288                 snd_pcm_close ( fOutputDevice );
   290                 for ( 
unsigned int i = 0; i < fSoftInputs; i++ )
   291                     if ( fInputSoftChannels[i] )
   292                         free ( fInputSoftChannels[i] );
   294                 for ( 
unsigned int i = 0; i < fSoftOutputs; i++ )
   295                     if ( fOutputSoftChannels[i] )
   296                         free ( fOutputSoftChannels[i] );
   298                 for ( 
unsigned int i = 0; i < fCardInputs; i++ )
   299                     if ( fInputCardChannels[i] )
   300                         free ( fInputCardChannels[i] );
   302                 for ( 
unsigned int i = 0; i < fCardOutputs; i++ )
   303                     if ( fOutputCardChannels[i] )
   304                         free ( fOutputCardChannels[i] );
   306                 if ( fInputCardBuffer )
   307                     free ( fInputCardBuffer );
   308                 if ( fOutputCardBuffer )
   309                     free ( fOutputCardBuffer );
   314             int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params )
   317                 check_error_msg ( snd_pcm_hw_params_any ( stream, params ), 
"unable to init parameters" )
   320                 if ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ) )
   321                     check_error_msg ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ),
   322                                       "unable to set access mode neither to non-interleaved or to interleaved" );
   323                 snd_pcm_hw_params_get_access ( params, &fSampleAccess );
   326                 if ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S32 ) )
   327                     check_error_msg ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S16 ),
   328                                       "unable to set format to either 32-bits or 16-bits" );
   329                 snd_pcm_hw_params_get_format ( params, &fSampleFormat );
   332                 snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 );
   335                 check_error_msg ( snd_pcm_hw_params_set_period_size ( stream, params, fBuffering, 0 ), "period size not available" );
   336                 check_error_msg ( snd_pcm_hw_params_set_periods ( stream, params, fPeriod, 0 ), "number of periods not available" );
   341             ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params )
   343                 _snd_pcm_format format;
   344                 unsigned int channels;
   345                 snd_pcm_hw_params_get_format ( params, &format );
   346                 snd_pcm_uframes_t psize;
   347                 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
   348                 snd_pcm_hw_params_get_channels ( params, &channels );
   349                 ssize_t bsize = snd_pcm_format_size ( format, psize * channels );
   353             ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params )
   355                 _snd_pcm_format format;
   356                 snd_pcm_hw_params_get_format ( params, &format );
   357                 snd_pcm_uframes_t psize;
   358                 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
   359                 ssize_t bsize = snd_pcm_format_size ( format, psize );
   371                 switch ( fSampleAccess )
   373                     case SND_PCM_ACCESS_RW_INTERLEAVED :
   374                         count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering );
   377                             display_error_msg ( count, 
"reading samples" );
   378                             check_error_msg ( snd_pcm_prepare ( fInputDevice ), 
"preparing input stream" );
   380                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
   382                             short* buffer16b = ( 
short* ) fInputCardBuffer;
   383                             for ( s = 0; s < fBuffering; s++ )
   384                                 for ( c = 0; c < fCardInputs; c++ )
   385                                     fInputSoftChannels[c][s] = jack_default_audio_sample_t(buffer16b[c + s*fCardInputs]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX));
   389                             int32_t* buffer32b = ( int32_t* ) fInputCardBuffer;
   390                             for ( s = 0; s < fBuffering; s++ )
   391                                 for ( c = 0; c < fCardInputs; c++ )
   392                                     fInputSoftChannels[c][s] = jack_default_audio_sample_t(buffer32b[c + s*fCardInputs]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX));
   395                     case SND_PCM_ACCESS_RW_NONINTERLEAVED :
   396                         count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering );
   399                             display_error_msg ( count, 
"reading samples" );
   400                             check_error_msg ( snd_pcm_prepare ( fInputDevice ), 
"preparing input stream" );
   402                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
   405                             for ( c = 0; c < fCardInputs; c++ )
   407                                 chan16b = ( 
short* ) fInputCardChannels[c];
   408                                 for ( s = 0; s < fBuffering; s++ )
   409                                     fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan16b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX));
   415                             for ( c = 0; c < fCardInputs; c++ )
   417                                 chan32b = ( int32_t* ) fInputCardChannels[c];
   418                                 for ( s = 0; s < fBuffering; s++ )
   419                                     fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan32b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX));
   424                         check_error_msg ( -10000, 
"unknow access mode" );
   439                 switch ( fSampleAccess )
   441                     case SND_PCM_ACCESS_RW_INTERLEAVED :
   442                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
   444                             short* buffer16b = ( 
short* ) fOutputCardBuffer;
   445                             for ( f = 0; f < fBuffering; f++ )
   447                                 for ( 
unsigned int c = 0; c < fCardOutputs; c++ )
   449                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
   450                                     buffer16b[c + f * fCardOutputs] = short(max(min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX));
   456                             int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer;
   457                             for ( f = 0; f < fBuffering; f++ )
   459                                 for ( 
unsigned int c = 0; c < fCardOutputs; c++ )
   461                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
   462                                     buffer32b[c + f * fCardOutputs] = int32_t(max(min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX));
   466                         count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering );
   469                             display_error_msg ( count, 
"w3" );
   470                             int err = snd_pcm_prepare ( fOutputDevice );
   471                             check_error_msg ( err, 
"preparing output stream" );
   475                     case SND_PCM_ACCESS_RW_NONINTERLEAVED :
   476                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
   478                             for ( c = 0; c < fCardOutputs; c++ )
   480                                 short* chan16b = ( 
short* ) fOutputCardChannels[c];
   481                                 for ( f = 0; f < fBuffering; f++ )
   483                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
   484                                     chan16b[f] = short(max(min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX));
   490                             for ( c = 0; c < fCardOutputs; c++ )
   492                                 int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c];
   493                                 for ( f = 0; f < fBuffering; f++ )
   495                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
   496                                     chan32b[f] = int32_t(max(min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX));
   500                         count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering );
   503                             display_error_msg ( count, 
"w3" );
   504                             int err = snd_pcm_prepare ( fOutputDevice );
   505                             check_error_msg ( err, 
"preparing output stream" );
   510                         check_error_msg ( -10000, 
"unknow access mode" );
   522                 snd_ctl_card_info_t* card_info;
   523                 snd_ctl_t* ctl_handle;
   524                 err = snd_ctl_open ( &ctl_handle, fCardName, 0 );   check_error ( err );
   525                 snd_ctl_card_info_alloca ( &card_info );
   526                 err = snd_ctl_card_info ( ctl_handle, card_info );  check_error ( err );
   528                             snd_ctl_card_info_get_driver ( card_info ),
   529                             fCardInputs, fCardOutputs,
   530                             fFrequency, fBuffering,
   531                             snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) );
   532                 snd_ctl_close(ctl_handle);
   540                 snd_ctl_card_info_t* card_info;
   541                 snd_ctl_t* ctl_handle;
   544                 jack_info ( 
"Audio Interface Description :" );
   545                 jack_info ( 
"Sampling Frequency : %d, Sample Format : %s, buffering : %d, nperiod : %d",
   546                             fFrequency, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ), fBuffering, fPeriod );
   547                 jack_info ( 
"Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs );
   548                 jack_info ( 
"Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs );
   551                 check_error ( snd_ctl_open ( &ctl_handle, fCardName, 0 ) );
   552                 snd_ctl_card_info_alloca ( &card_info );
   553                 check_error ( snd_ctl_card_info ( ctl_handle, card_info ) );
   554                 printCardInfo ( card_info );
   557                 if ( fSoftInputs > 0 )
   558                     printHWParams ( fInputParams );
   559                 if ( fSoftOutputs > 0 )
   560                     printHWParams ( fOutputParams );
   561                 snd_ctl_close(ctl_handle);
   565             void printCardInfo ( snd_ctl_card_info_t* ci )
   567                 jack_info ( 
"Card info (address : %p)", ci );
   568                 jack_info ( 
"\tID         = %s", snd_ctl_card_info_get_id ( ci ) );
   569                 jack_info ( 
"\tDriver     = %s", snd_ctl_card_info_get_driver ( ci ) );
   570                 jack_info ( 
"\tName       = %s", snd_ctl_card_info_get_name ( ci ) );
   571                 jack_info ( 
"\tLongName   = %s", snd_ctl_card_info_get_longname ( ci ) );
   572                 jack_info ( 
"\tMixerName  = %s", snd_ctl_card_info_get_mixername ( ci ) );
   573                 jack_info ( 
"\tComponents = %s", snd_ctl_card_info_get_components ( ci ) );
   577             void printHWParams ( snd_pcm_hw_params_t* params )
   579                 jack_info ( 
"HW Params info (address : %p)\n", params );
   581                 jack_info ( 
"\tChannels    = %d", snd_pcm_hw_params_get_channels ( params, NULL ) );
   582                 jack_info ( 
"\tFormat      = %s", snd_pcm_format_name ( ( _snd_pcm_format ) snd_pcm_hw_params_get_format ( params, NULL ) ) );
   583                 jack_info ( 
"\tAccess      = %s", snd_pcm_access_name ( ( _snd_pcm_access ) snd_pcm_hw_params_get_access ( params, NULL ) ) );
   584                 jack_info ( 
"\tRate        = %d", snd_pcm_hw_params_get_rate ( params, NULL, NULL ) );
   585                 jack_info ( 
"\tPeriods     = %d", snd_pcm_hw_params_get_periods ( params, NULL, NULL ) );
   586                 jack_info ( 
"\tPeriod size = %d", ( 
int ) snd_pcm_hw_params_get_period_size ( params, NULL, NULL ) );
   587                 jack_info ( 
"\tPeriod time = %d", snd_pcm_hw_params_get_period_time ( params, NULL, NULL ) );
   588                 jack_info ( 
"\tBuffer size = %d", ( 
int ) snd_pcm_hw_params_get_buffer_size ( params, NULL ) );
   589                 jack_info ( 
"\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time ( params, NULL, NULL ) );
   614             virtual int SetSampleRate ( jack_nframes_t sample_rate );
   615             virtual int SetBufferSize ( jack_nframes_t buffer_size );
   618             virtual bool Execute();
   629 #include "JackCompilerDeps.h"   630 #include "driver_interface.h" 
Audio adapter using ALSA API.
The base class for runnable objects, that have an  Init  and  Execute  method to be called in a threa...
SERVER_EXPORT void jack_info(const char *fmt,...)
Base class for audio adapters.
Darwin threads. Real-time threads are actually "time constraint" threads.