Jack2  1.9.10
JackAlsaAdapter.h
00001 /*
00002 Copyright (C) 2008 Grame
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #ifndef __JackAlsaAdapter__
00021 #define __JackAlsaAdapter__
00022 
00023 #include <math.h>
00024 #include <limits.h>
00025 #include <assert.h>
00026 #include <alsa/asoundlib.h>
00027 #include "JackAudioAdapterInterface.h"
00028 #include "JackPlatformPlug.h"
00029 #include "JackError.h"
00030 #include "jack.h"
00031 #include "jslist.h"
00032 
00033 namespace Jack
00034 {
00035 
00036     inline void* aligned_calloc ( size_t nmemb, size_t size ) { return ( void* ) calloc ( nmemb, size ); }
00037 
00038 #define max(x,y) (((x)>(y)) ? (x) : (y))
00039 #define min(x,y) (((x)<(y)) ? (x) : (y))
00040 
00041 #define check_error(err) if (err) { jack_error("%s:%d, alsa error %d : %s", __FILE__, __LINE__, err, snd_strerror(err)); return err; }
00042 #define check_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); return err; }
00043 #define display_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); }
00044 
00048     class AudioParam
00049     {
00050         public:
00051             const char*     fCardName;
00052             unsigned int    fFrequency;
00053             int             fBuffering;
00054 
00055             unsigned int    fSoftInputs;
00056             unsigned int    fSoftOutputs;
00057 
00058         public:
00059             AudioParam() :
00060                     fCardName ( "hw:0" ),
00061                     fFrequency ( 44100 ),
00062                     fBuffering ( 512 ),
00063                     fSoftInputs ( 2 ),
00064                     fSoftOutputs ( 2 )
00065             {}
00066 
00067             AudioParam ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
00068                     fCardName ( "hw:0" ),
00069                     fFrequency ( sample_rate ),
00070                     fBuffering ( buffer_size ),
00071                     fSoftInputs ( 2 ),
00072                     fSoftOutputs ( 2 )
00073             {}
00074 
00075             AudioParam& cardName ( const char* n )
00076             {
00077                 fCardName = n;
00078                 return *this;
00079             }
00080 
00081             AudioParam& frequency ( int f )
00082             {
00083                 fFrequency = f;
00084                 return *this;
00085             }
00086 
00087             AudioParam& buffering ( int fpb )
00088             {
00089                 fBuffering = fpb;
00090                 return *this;
00091             }
00092 
00093             void setInputs ( int inputs )
00094             {
00095                 fSoftInputs = inputs;
00096             }
00097 
00098             AudioParam& inputs ( int n )
00099             {
00100                 fSoftInputs = n;
00101                 return *this;
00102             }
00103 
00104             void setOutputs ( int outputs )
00105             {
00106                 fSoftOutputs = outputs;
00107             }
00108 
00109             AudioParam& outputs ( int n )
00110             {
00111                 fSoftOutputs = n;
00112                 return *this;
00113             }
00114     };
00115 
00119     class AudioInterface : public AudioParam
00120     {
00121         public:
00122             //device info
00123             snd_pcm_t*  fOutputDevice;
00124             snd_pcm_t*  fInputDevice;
00125             snd_pcm_hw_params_t* fInputParams;
00126             snd_pcm_hw_params_t* fOutputParams;
00127 
00128             //samples info
00129             snd_pcm_format_t fSampleFormat;
00130             snd_pcm_access_t fSampleAccess;
00131 
00132             //channels
00133             const char*  fCaptureName;
00134             const char*  fPlaybackName;
00135             unsigned int fCardInputs;
00136             unsigned int fCardOutputs;
00137 
00138             //stream parameters
00139             unsigned int fPeriod;
00140 
00141             //interleaved mode audiocard buffers
00142             void* fInputCardBuffer;
00143             void* fOutputCardBuffer;
00144 
00145             //non-interleaved mode audiocard buffers
00146             void* fInputCardChannels[256];
00147             void* fOutputCardChannels[256];
00148 
00149             //non-interleaved mod, floating point software buffers
00150             jack_default_audio_sample_t* fInputSoftChannels[256];
00151             jack_default_audio_sample_t* fOutputSoftChannels[256];
00152 
00153             //public methods ---------------------------------------------------------
00154 
00155             const char* cardName()
00156             {
00157                 return fCardName;
00158             }
00159 
00160             int frequency()
00161             {
00162                 return fFrequency;
00163             }
00164 
00165             int buffering()
00166             {
00167                 return fBuffering;
00168             }
00169 
00170             jack_default_audio_sample_t** inputSoftChannels()
00171             {
00172                 return fInputSoftChannels;
00173             }
00174 
00175             jack_default_audio_sample_t** outputSoftChannels()
00176             {
00177                 return fOutputSoftChannels;
00178             }
00179 
00180             AudioInterface ( const AudioParam& ap = AudioParam() ) : AudioParam ( ap )
00181             {
00182                 fInputDevice    = 0;
00183                 fOutputDevice   = 0;
00184                 fInputParams    = 0;
00185                 fOutputParams   = 0;
00186                 fPeriod = 2;
00187                 fCaptureName    = NULL;
00188                 fPlaybackName   = NULL;
00189 
00190                 fInputCardBuffer = 0;
00191                 fOutputCardBuffer = 0;
00192 
00193                 for ( int i = 0; i < 256; i++ )
00194                 {
00195                     fInputCardChannels[i] = 0;
00196                     fOutputCardChannels[i] = 0;
00197                     fInputSoftChannels[i] = 0;
00198                     fOutputSoftChannels[i] = 0;
00199                 }
00200             }
00201 
00202             AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
00203                     AudioParam ( buffer_size, sample_rate )
00204             {
00205                 fInputCardBuffer = 0;
00206                 fOutputCardBuffer = 0;
00207                 fCaptureName    = NULL;
00208                 fPlaybackName   = NULL;
00209 
00210                 for ( int i = 0; i < 256; i++ )
00211                 {
00212                     fInputCardChannels[i] = 0;
00213                     fOutputCardChannels[i] = 0;
00214                     fInputSoftChannels[i] = 0;
00215                     fOutputSoftChannels[i] = 0;
00216                 }
00217             }
00218 
00222             int open()
00223             {
00224                 //open input/output streams
00225                 check_error ( snd_pcm_open ( &fInputDevice,  (fCaptureName == NULL) ? fCardName : fCaptureName, SND_PCM_STREAM_CAPTURE, 0 ) );
00226                 check_error ( snd_pcm_open ( &fOutputDevice, (fPlaybackName == NULL) ? fCardName : fPlaybackName, SND_PCM_STREAM_PLAYBACK, 0 ) );
00227 
00228                 //get hardware input parameters
00229                 check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) );
00230                 setAudioParams ( fInputDevice, fInputParams );
00231 
00232                 //get hardware output parameters
00233                 check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) )
00234                 setAudioParams ( fOutputDevice, fOutputParams );
00235 
00236                 // set the number of physical input and output channels close to what we need
00237                 fCardInputs     = fSoftInputs;
00238                 fCardOutputs    = fSoftOutputs;
00239 
00240                 snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
00241                 snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
00242 
00243                 //set input/output param
00244                 check_error ( snd_pcm_hw_params ( fInputDevice,  fInputParams ) );
00245                 check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) );
00246 
00247                 //set hardware buffers
00248                 if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED )
00249                 {
00250                     fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 );
00251                     fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 );
00252                 }
00253                 else
00254                 {
00255                     for ( unsigned int i = 0; i < fCardInputs; i++ )
00256                         fInputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fInputParams ), 1 );
00257                     for ( unsigned int i = 0; i < fCardOutputs; i++ )
00258                         fOutputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fOutputParams ), 1 );
00259                 }
00260 
00261                 //set floating point buffers needed by the dsp code
00262                 fSoftInputs = max ( fSoftInputs, fCardInputs );
00263                 assert ( fSoftInputs < 256 );
00264                 fSoftOutputs = max ( fSoftOutputs, fCardOutputs );
00265                 assert ( fSoftOutputs < 256 );
00266 
00267                 for ( unsigned int i = 0; i < fSoftInputs; i++ )
00268                 {
00269                     fInputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) );
00270                     for ( int j = 0; j < fBuffering; j++ )
00271                         fInputSoftChannels[i][j] = 0.0;
00272                 }
00273 
00274                 for ( unsigned int i = 0; i < fSoftOutputs; i++ )
00275                 {
00276                     fOutputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) );
00277                     for ( int j = 0; j < fBuffering; j++ )
00278                         fOutputSoftChannels[i][j] = 0.0;
00279                 }
00280                 return 0;
00281             }
00282 
00283             int close()
00284             {
00285                 snd_pcm_hw_params_free ( fInputParams );
00286                 snd_pcm_hw_params_free ( fOutputParams );
00287                 snd_pcm_close ( fInputDevice );
00288                 snd_pcm_close ( fOutputDevice );
00289 
00290                 for ( unsigned int i = 0; i < fSoftInputs; i++ )
00291                     if ( fInputSoftChannels[i] )
00292                         free ( fInputSoftChannels[i] );
00293 
00294                 for ( unsigned int i = 0; i < fSoftOutputs; i++ )
00295                     if ( fOutputSoftChannels[i] )
00296                         free ( fOutputSoftChannels[i] );
00297 
00298                 for ( unsigned int i = 0; i < fCardInputs; i++ )
00299                     if ( fInputCardChannels[i] )
00300                         free ( fInputCardChannels[i] );
00301 
00302                 for ( unsigned int i = 0; i < fCardOutputs; i++ )
00303                     if ( fOutputCardChannels[i] )
00304                         free ( fOutputCardChannels[i] );
00305 
00306                 if ( fInputCardBuffer )
00307                     free ( fInputCardBuffer );
00308                 if ( fOutputCardBuffer )
00309                     free ( fOutputCardBuffer );
00310 
00311                 return 0;
00312             }
00313 
00314             int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params )
00315             {
00316                 //set params record with initial values
00317                 check_error_msg ( snd_pcm_hw_params_any ( stream, params ), "unable to init parameters" )
00318 
00319                 //set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
00320                 if ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ) )
00321                     check_error_msg ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ),
00322                                       "unable to set access mode neither to non-interleaved or to interleaved" );
00323                 snd_pcm_hw_params_get_access ( params, &fSampleAccess );
00324 
00325                 //search for 32-bits or 16-bits format
00326                 if ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S32 ) )
00327                     check_error_msg ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S16 ),
00328                                       "unable to set format to either 32-bits or 16-bits" );
00329                 snd_pcm_hw_params_get_format ( params, &fSampleFormat );
00330 
00331                 //set sample frequency
00332                 snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 );
00333 
00334                 //set period and period size (buffering)
00335                 check_error_msg ( snd_pcm_hw_params_set_period_size ( stream, params, fBuffering, 0 ), "period size not available" );
00336                 check_error_msg ( snd_pcm_hw_params_set_periods ( stream, params, fPeriod, 0 ), "number of periods not available" );
00337 
00338                 return 0;
00339             }
00340 
00341             ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params )
00342             {
00343                 _snd_pcm_format format;
00344                 unsigned int channels;
00345                 snd_pcm_hw_params_get_format ( params, &format );
00346                 snd_pcm_uframes_t psize;
00347                 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
00348                 snd_pcm_hw_params_get_channels ( params, &channels );
00349                 ssize_t bsize = snd_pcm_format_size ( format, psize * channels );
00350                 return bsize;
00351             }
00352 
00353             ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params )
00354             {
00355                 _snd_pcm_format format;
00356                 snd_pcm_hw_params_get_format ( params, &format );
00357                 snd_pcm_uframes_t psize;
00358                 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
00359                 ssize_t bsize = snd_pcm_format_size ( format, psize );
00360                 return bsize;
00361             }
00362 
00367             int read()
00368             {
00369                 int count, s;
00370                 unsigned int c;
00371                 switch ( fSampleAccess )
00372                 {
00373                     case SND_PCM_ACCESS_RW_INTERLEAVED :
00374                         count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering );
00375                         if ( count < 0 )
00376                         {
00377                             display_error_msg ( count, "reading samples" );
00378                             check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
00379                         }
00380                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00381                         {
00382                             short* buffer16b = ( short* ) fInputCardBuffer;
00383                             for ( s = 0; s < fBuffering; s++ )
00384                                 for ( c = 0; c < fCardInputs; c++ )
00385                                     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));
00386                         }
00387                         else   // SND_PCM_FORMAT_S32
00388                         {
00389                             int32_t* buffer32b = ( int32_t* ) fInputCardBuffer;
00390                             for ( s = 0; s < fBuffering; s++ )
00391                                 for ( c = 0; c < fCardInputs; c++ )
00392                                     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));
00393                         }
00394                         break;
00395                     case SND_PCM_ACCESS_RW_NONINTERLEAVED :
00396                         count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering );
00397                         if ( count < 0 )
00398                         {
00399                             display_error_msg ( count, "reading samples" );
00400                             check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
00401                         }
00402                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00403                         {
00404                             short* chan16b;
00405                             for ( c = 0; c < fCardInputs; c++ )
00406                             {
00407                                 chan16b = ( short* ) fInputCardChannels[c];
00408                                 for ( s = 0; s < fBuffering; s++ )
00409                                     fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan16b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX));
00410                             }
00411                         }
00412                         else   // SND_PCM_FORMAT_S32
00413                         {
00414                             int32_t* chan32b;
00415                             for ( c = 0; c < fCardInputs; c++ )
00416                             {
00417                                 chan32b = ( int32_t* ) fInputCardChannels[c];
00418                                 for ( s = 0; s < fBuffering; s++ )
00419                                     fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan32b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX));
00420                             }
00421                         }
00422                         break;
00423                     default :
00424                         check_error_msg ( -10000, "unknow access mode" );
00425                         break;
00426                 }
00427                 return 0;
00428             }
00429 
00434             int write()
00435             {
00436                 int count, f;
00437                 unsigned int c;
00438             recovery:
00439                 switch ( fSampleAccess )
00440                 {
00441                     case SND_PCM_ACCESS_RW_INTERLEAVED :
00442                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00443                         {
00444                             short* buffer16b = ( short* ) fOutputCardBuffer;
00445                             for ( f = 0; f < fBuffering; f++ )
00446                             {
00447                                 for ( unsigned int c = 0; c < fCardOutputs; c++ )
00448                                 {
00449                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
00450                                     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));
00451                                 }
00452                             }
00453                         }
00454                         else   // SND_PCM_FORMAT_S32
00455                         {
00456                             int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer;
00457                             for ( f = 0; f < fBuffering; f++ )
00458                             {
00459                                 for ( unsigned int c = 0; c < fCardOutputs; c++ )
00460                                 {
00461                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
00462                                     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));
00463                                 }
00464                             }
00465                         }
00466                         count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering );
00467                         if ( count < 0 )
00468                         {
00469                             display_error_msg ( count, "w3" );
00470                             int err = snd_pcm_prepare ( fOutputDevice );
00471                             check_error_msg ( err, "preparing output stream" );
00472                             goto recovery;
00473                         }
00474                         break;
00475                     case SND_PCM_ACCESS_RW_NONINTERLEAVED :
00476                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00477                         {
00478                             for ( c = 0; c < fCardOutputs; c++ )
00479                             {
00480                                 short* chan16b = ( short* ) fOutputCardChannels[c];
00481                                 for ( f = 0; f < fBuffering; f++ )
00482                                 {
00483                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
00484                                     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));
00485                                 }
00486                             }
00487                         }
00488                         else
00489                         {
00490                             for ( c = 0; c < fCardOutputs; c++ )
00491                             {
00492                                 int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c];
00493                                 for ( f = 0; f < fBuffering; f++ )
00494                                 {
00495                                     jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
00496                                     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));
00497                                 }
00498                             }
00499                         }
00500                         count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering );
00501                         if ( count<0 )
00502                         {
00503                             display_error_msg ( count, "w3" );
00504                             int err = snd_pcm_prepare ( fOutputDevice );
00505                             check_error_msg ( err, "preparing output stream" );
00506                             goto recovery;
00507                         }
00508                         break;
00509                     default :
00510                         check_error_msg ( -10000, "unknow access mode" );
00511                         break;
00512                 }
00513                 return 0;
00514             }
00515 
00519             int shortinfo()
00520             {
00521                 int err;
00522                 snd_ctl_card_info_t* card_info;
00523                 snd_ctl_t* ctl_handle;
00524                 err = snd_ctl_open ( &ctl_handle, fCardName, 0 );   check_error ( err );
00525                 snd_ctl_card_info_alloca ( &card_info );
00526                 err = snd_ctl_card_info ( ctl_handle, card_info );  check_error ( err );
00527                 jack_info ( "%s|%d|%d|%d|%d|%s",
00528                             snd_ctl_card_info_get_driver ( card_info ),
00529                             fCardInputs, fCardOutputs,
00530                             fFrequency, fBuffering,
00531                             snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) );
00532                 snd_ctl_close(ctl_handle);
00533             }
00534 
00538             int longinfo()
00539             {
00540                 snd_ctl_card_info_t* card_info;
00541                 snd_ctl_t* ctl_handle;
00542 
00543                 //display info
00544                 jack_info ( "Audio Interface Description :" );
00545                 jack_info ( "Sampling Frequency : %d, Sample Format : %s, buffering : %d, nperiod : %d",
00546                             fFrequency, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ), fBuffering, fPeriod );
00547                 jack_info ( "Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs );
00548                 jack_info ( "Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs );
00549 
00550                 //get audio card info and display
00551                 check_error ( snd_ctl_open ( &ctl_handle, fCardName, 0 ) );
00552                 snd_ctl_card_info_alloca ( &card_info );
00553                 check_error ( snd_ctl_card_info ( ctl_handle, card_info ) );
00554                 printCardInfo ( card_info );
00555 
00556                 //display input/output streams info
00557                 if ( fSoftInputs > 0 )
00558                     printHWParams ( fInputParams );
00559                 if ( fSoftOutputs > 0 )
00560                     printHWParams ( fOutputParams );
00561                 snd_ctl_close(ctl_handle);
00562                 return 0;
00563             }
00564 
00565             void printCardInfo ( snd_ctl_card_info_t* ci )
00566             {
00567                 jack_info ( "Card info (address : %p)", ci );
00568                 jack_info ( "\tID         = %s", snd_ctl_card_info_get_id ( ci ) );
00569                 jack_info ( "\tDriver     = %s", snd_ctl_card_info_get_driver ( ci ) );
00570                 jack_info ( "\tName       = %s", snd_ctl_card_info_get_name ( ci ) );
00571                 jack_info ( "\tLongName   = %s", snd_ctl_card_info_get_longname ( ci ) );
00572                 jack_info ( "\tMixerName  = %s", snd_ctl_card_info_get_mixername ( ci ) );
00573                 jack_info ( "\tComponents = %s", snd_ctl_card_info_get_components ( ci ) );
00574                 jack_info ( "--------------" );
00575             }
00576 
00577             void printHWParams ( snd_pcm_hw_params_t* params )
00578             {
00579                 jack_info ( "HW Params info (address : %p)\n", params );
00580 #if 0
00581                 jack_info ( "\tChannels    = %d", snd_pcm_hw_params_get_channels ( params, NULL ) );
00582                 jack_info ( "\tFormat      = %s", snd_pcm_format_name ( ( _snd_pcm_format ) snd_pcm_hw_params_get_format ( params, NULL ) ) );
00583                 jack_info ( "\tAccess      = %s", snd_pcm_access_name ( ( _snd_pcm_access ) snd_pcm_hw_params_get_access ( params, NULL ) ) );
00584                 jack_info ( "\tRate        = %d", snd_pcm_hw_params_get_rate ( params, NULL, NULL ) );
00585                 jack_info ( "\tPeriods     = %d", snd_pcm_hw_params_get_periods ( params, NULL, NULL ) );
00586                 jack_info ( "\tPeriod size = %d", ( int ) snd_pcm_hw_params_get_period_size ( params, NULL, NULL ) );
00587                 jack_info ( "\tPeriod time = %d", snd_pcm_hw_params_get_period_time ( params, NULL, NULL ) );
00588                 jack_info ( "\tBuffer size = %d", ( int ) snd_pcm_hw_params_get_buffer_size ( params, NULL ) );
00589                 jack_info ( "\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time ( params, NULL, NULL ) );
00590 #endif
00591                 jack_info ( "--------------" );
00592             }
00593     };
00594 
00599     class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface
00600     {
00601 
00602         private:
00603             JackThread fThread;
00604             AudioInterface fAudioInterface;
00605 
00606         public:
00607             JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params );
00608             ~JackAlsaAdapter()
00609             {}
00610 
00611             virtual int Open();
00612             virtual int Close();
00613 
00614             virtual int SetSampleRate ( jack_nframes_t sample_rate );
00615             virtual int SetBufferSize ( jack_nframes_t buffer_size );
00616 
00617             virtual bool Init();
00618             virtual bool Execute();
00619 
00620     };
00621 
00622 }
00623 
00624 #ifdef __cplusplus
00625 extern "C"
00626 {
00627 #endif
00628 
00629 #include "JackCompilerDeps.h"
00630 #include "driver_interface.h"
00631 
00632 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor();
00633 
00634 #ifdef __cplusplus
00635 }
00636 #endif
00637 
00638 #endif