Jack2 1.9.6

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             unsigned int fCardInputs;
00134             unsigned int fCardOutputs;
00135 
00136             //stream parameters
00137             unsigned int fPeriod;
00138 
00139             //interleaved mode audiocard buffers
00140             void* fInputCardBuffer;
00141             void* fOutputCardBuffer;
00142 
00143             //non-interleaved mode audiocard buffers
00144             void* fInputCardChannels[256];
00145             void* fOutputCardChannels[256];
00146 
00147             //non-interleaved mod, floating point software buffers
00148             float* fInputSoftChannels[256];
00149             float* fOutputSoftChannels[256];
00150 
00151             //public methods ---------------------------------------------------------
00152 
00153             const char* cardName()
00154             {
00155                 return fCardName;
00156             }
00157 
00158             int frequency()
00159             {
00160                 return fFrequency;
00161             }
00162 
00163             int buffering()
00164             {
00165                 return fBuffering;
00166             }
00167 
00168             float** inputSoftChannels()
00169             {
00170                 return fInputSoftChannels;
00171             }
00172 
00173             float** outputSoftChannels()
00174             {
00175                 return fOutputSoftChannels;
00176             }
00177 
00178             AudioInterface ( const AudioParam& ap = AudioParam() ) : AudioParam ( ap )
00179             {
00180                 fInputDevice    = 0;
00181                 fOutputDevice   = 0;
00182                 fInputParams    = 0;
00183                 fOutputParams   = 0;
00184                 fPeriod = 2;
00185                 
00186                 fInputCardBuffer = 0;
00187                 fOutputCardBuffer = 0;
00188                 
00189                 for ( int i = 0; i < 256; i++ )
00190                 {
00191                     fInputCardChannels[i] = 0;
00192                     fOutputCardChannels[i] = 0;
00193                     fInputSoftChannels[i] = 0;
00194                     fOutputSoftChannels[i] = 0;
00195                 }
00196             }
00197 
00198             AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
00199                     AudioParam ( buffer_size, sample_rate )
00200             {
00201                 fInputCardBuffer = 0;
00202                 fOutputCardBuffer = 0;
00203 
00204                 for ( int i = 0; i < 256; i++ )
00205                 {
00206                     fInputCardChannels[i] = 0;
00207                     fOutputCardChannels[i] = 0;
00208                     fInputSoftChannels[i] = 0;
00209                     fOutputSoftChannels[i] = 0;
00210                 }
00211             }
00212 
00216             int open()
00217             {
00218                 //open input/output streams
00219                 check_error ( snd_pcm_open ( &fInputDevice,  fCardName, SND_PCM_STREAM_CAPTURE, 0 ) );
00220                 check_error ( snd_pcm_open ( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ) );
00221 
00222                 //get hardware input parameters
00223                 check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) );
00224                 setAudioParams ( fInputDevice, fInputParams );
00225            
00226                 //get hardware output parameters
00227                 check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) )
00228                 setAudioParams ( fOutputDevice, fOutputParams );
00229                 
00230                 // set the number of physical input and output channels close to what we need
00231                 fCardInputs     = fSoftInputs;
00232                 fCardOutputs    = fSoftOutputs;
00233   
00234                 snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
00235                 snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
00236      
00237                 //set input/output param
00238                 check_error ( snd_pcm_hw_params ( fInputDevice,  fInputParams ) );
00239                 check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) );
00240 
00241                 //set hardware buffers
00242                 if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED )
00243                 {
00244                     fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 );
00245                     fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 );
00246                 }
00247                 else
00248                 {
00249                     for ( unsigned int i = 0; i < fCardInputs; i++ )
00250                         fInputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fInputParams ), 1 );
00251                     for ( unsigned int i = 0; i < fCardOutputs; i++ )
00252                         fOutputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fOutputParams ), 1 );
00253                 }
00254 
00255                 //set floating point buffers needed by the dsp code
00256                 fSoftInputs = max ( fSoftInputs, fCardInputs );
00257                 assert ( fSoftInputs < 256 );
00258                 fSoftOutputs = max ( fSoftOutputs, fCardOutputs );
00259                 assert ( fSoftOutputs < 256 );
00260 
00261                 for ( unsigned int i = 0; i < fSoftInputs; i++ )
00262                 {
00263                     fInputSoftChannels[i] = ( float* ) aligned_calloc ( fBuffering, sizeof ( float ) );
00264                     for ( int j = 0; j < fBuffering; j++ )
00265                         fInputSoftChannels[i][j] = 0.0;
00266                 }
00267 
00268                 for ( unsigned int i = 0; i < fSoftOutputs; i++ )
00269                 {
00270                     fOutputSoftChannels[i] = ( float* ) aligned_calloc ( fBuffering, sizeof ( float ) );
00271                     for ( int j = 0; j < fBuffering; j++ )
00272                         fOutputSoftChannels[i][j] = 0.0;
00273                 }
00274                 return 0;
00275             }
00276 
00277             int close()
00278             {
00279                 snd_pcm_hw_params_free ( fInputParams );
00280                 snd_pcm_hw_params_free ( fOutputParams );
00281                 snd_pcm_close ( fInputDevice );
00282                 snd_pcm_close ( fOutputDevice );
00283 
00284                 for ( unsigned int i = 0; i < fSoftInputs; i++ )
00285                     if ( fInputSoftChannels[i] )
00286                         free ( fInputSoftChannels[i] );
00287 
00288                 for ( unsigned int i = 0; i < fSoftOutputs; i++ )
00289                     if ( fOutputSoftChannels[i] )
00290                         free ( fOutputSoftChannels[i] );
00291 
00292                 for ( unsigned int i = 0; i < fCardInputs; i++ )
00293                     if ( fInputCardChannels[i] )
00294                         free ( fInputCardChannels[i] );
00295 
00296                 for ( unsigned int i = 0; i < fCardOutputs; i++ )
00297                     if ( fOutputCardChannels[i] )
00298                         free ( fOutputCardChannels[i] );
00299 
00300                 if ( fInputCardBuffer )
00301                     free ( fInputCardBuffer );
00302                 if ( fOutputCardBuffer )
00303                     free ( fOutputCardBuffer );
00304 
00305                 return 0;
00306             }
00307 
00308             int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params )
00309             {
00310                 //set params record with initial values
00311                 check_error_msg ( snd_pcm_hw_params_any ( stream, params ), "unable to init parameters" )
00312 
00313                 //set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
00314                 if ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ) )
00315                     check_error_msg ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ),
00316                                       "unable to set access mode neither to non-interleaved or to interleaved" );
00317                 snd_pcm_hw_params_get_access ( params, &fSampleAccess );
00318 
00319                 //search for 32-bits or 16-bits format
00320                 if ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S32 ) )
00321                     check_error_msg ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S16 ),
00322                                       "unable to set format to either 32-bits or 16-bits" );
00323                 snd_pcm_hw_params_get_format ( params, &fSampleFormat );
00324 
00325                 //set sample frequency
00326                 snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 );
00327 
00328                 //set period and period size (buffering)
00329                 check_error_msg ( snd_pcm_hw_params_set_period_size ( stream, params, fBuffering, 0 ), "period size not available" );
00330                 check_error_msg ( snd_pcm_hw_params_set_periods ( stream, params, fPeriod, 0 ), "number of periods not available" );
00331 
00332                 return 0;
00333             }
00334 
00335             ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params )
00336             {
00337                 _snd_pcm_format format;
00338                 unsigned int channels;
00339                 snd_pcm_hw_params_get_format ( params, &format );
00340                 snd_pcm_uframes_t psize;
00341                 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
00342                 snd_pcm_hw_params_get_channels ( params, &channels );
00343                 ssize_t bsize = snd_pcm_format_size ( format, psize * channels );
00344                 return bsize;
00345             }
00346 
00347             ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params )
00348             {
00349                 _snd_pcm_format format;
00350                 snd_pcm_hw_params_get_format ( params, &format );
00351                 snd_pcm_uframes_t psize;
00352                 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
00353                 ssize_t bsize = snd_pcm_format_size ( format, psize );
00354                 return bsize;
00355             }
00356 
00361             int read()
00362             {
00363                 int count, s;
00364                 unsigned int c;
00365                 switch ( fSampleAccess )
00366                 {
00367                     case SND_PCM_ACCESS_RW_INTERLEAVED :
00368                         count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering );
00369                         if ( count < 0 )
00370                         {
00371                             display_error_msg ( count, "reading samples" );
00372                             check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
00373                         }
00374                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00375                         {
00376                             short* buffer16b = ( short* ) fInputCardBuffer;
00377                             for ( s = 0; s < fBuffering; s++ )
00378                                 for ( c = 0; c < fCardInputs; c++ )
00379                                     fInputSoftChannels[c][s] = float ( buffer16b[c + s*fCardInputs] ) * ( 1.0/float ( SHRT_MAX ) );
00380                         }
00381                         else   // SND_PCM_FORMAT_S32
00382                         {
00383                             int32_t* buffer32b = ( int32_t* ) fInputCardBuffer;
00384                             for ( s = 0; s < fBuffering; s++ )
00385                                 for ( c = 0; c < fCardInputs; c++ )
00386                                     fInputSoftChannels[c][s] = float ( buffer32b[c + s*fCardInputs] ) * ( 1.0/float ( INT_MAX ) );
00387                         }
00388                         break;
00389                     case SND_PCM_ACCESS_RW_NONINTERLEAVED :
00390                         count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering );
00391                         if ( count < 0 )
00392                         {
00393                             display_error_msg ( count, "reading samples" );
00394                             check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
00395                         }
00396                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00397                         {
00398                             short* chan16b;
00399                             for ( c = 0; c < fCardInputs; c++ )
00400                             {
00401                                 chan16b = ( short* ) fInputCardChannels[c];
00402                                 for ( s = 0; s < fBuffering; s++ )
00403                                     fInputSoftChannels[c][s] = float ( chan16b[s] ) * ( 1.0/float ( SHRT_MAX ) );
00404                             }
00405                         }
00406                         else   // SND_PCM_FORMAT_S32
00407                         {
00408                             int32_t* chan32b;
00409                             for ( c = 0; c < fCardInputs; c++ )
00410                             {
00411                                 chan32b = ( int32_t* ) fInputCardChannels[c];
00412                                 for ( s = 0; s < fBuffering; s++ )
00413                                     fInputSoftChannels[c][s] = float ( chan32b[s] ) * ( 1.0/float ( INT_MAX ) );
00414                             }
00415                         }
00416                         break;
00417                     default :
00418                         check_error_msg ( -10000, "unknow access mode" );
00419                         break;
00420                 }
00421                 return 0;
00422             }
00423 
00428             int write()
00429             {
00430                 int count, f;
00431                 unsigned int c;
00432             recovery:
00433                 switch ( fSampleAccess )
00434                 {
00435                     case SND_PCM_ACCESS_RW_INTERLEAVED :
00436                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00437                         {
00438                             short* buffer16b = ( short* ) fOutputCardBuffer;
00439                             for ( f = 0; f < fBuffering; f++ )
00440                             {
00441                                 for ( unsigned int c = 0; c < fCardOutputs; c++ )
00442                                 {
00443                                     float x = fOutputSoftChannels[c][f];
00444                                     buffer16b[c + f * fCardOutputs] = short ( max ( min ( x, 1.0 ), -1.0 ) * float ( SHRT_MAX ) );
00445                                 }
00446                             }
00447                         }
00448                         else   // SND_PCM_FORMAT_S32
00449                         {
00450                             int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer;
00451                             for ( f = 0; f < fBuffering; f++ )
00452                             {
00453                                 for ( unsigned int c = 0; c < fCardOutputs; c++ )
00454                                 {
00455                                     float x = fOutputSoftChannels[c][f];
00456                                     buffer32b[c + f * fCardOutputs] = int32_t ( max ( min ( x, 1.0 ), -1.0 ) * float ( INT_MAX ) );
00457                                 }
00458                             }
00459                         }
00460                         count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering );
00461                         if ( count < 0 )
00462                         {
00463                             display_error_msg ( count, "w3" );
00464                             int err = snd_pcm_prepare ( fOutputDevice );
00465                             check_error_msg ( err, "preparing output stream" );
00466                             goto recovery;
00467                         }
00468                         break;
00469                     case SND_PCM_ACCESS_RW_NONINTERLEAVED :
00470                         if ( fSampleFormat == SND_PCM_FORMAT_S16 )
00471                         {
00472                             for ( c = 0; c < fCardOutputs; c++ )
00473                             {
00474                                 short* chan16b = ( short* ) fOutputCardChannels[c];
00475                                 for ( f = 0; f < fBuffering; f++ )
00476                                 {
00477                                     float x = fOutputSoftChannels[c][f];
00478                                     chan16b[f] = short ( max ( min ( x,1.0 ), -1.0 ) * float ( SHRT_MAX ) ) ;
00479                                 }
00480                             }
00481                         }
00482                         else
00483                         {
00484                             for ( c = 0; c < fCardOutputs; c++ )
00485                             {
00486                                 int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c];
00487                                 for ( f = 0; f < fBuffering; f++ )
00488                                 {
00489                                     float x = fOutputSoftChannels[c][f];
00490                                     chan32b[f] = int32_t ( max ( min ( x,1.0 ),-1.0 ) * float ( INT_MAX ) ) ;
00491                                 }
00492                             }
00493                         }
00494                         count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering );
00495                         if ( count<0 )
00496                         {
00497                             display_error_msg ( count, "w3" );
00498                             int err = snd_pcm_prepare ( fOutputDevice );
00499                             check_error_msg ( err, "preparing output stream" );
00500                             goto recovery;
00501                         }
00502                         break;
00503                     default :
00504                         check_error_msg ( -10000, "unknow access mode" );
00505                         break;
00506                 }
00507                 return 0;
00508             }
00509 
00513             int shortinfo()
00514             {
00515                 int err;
00516                 snd_ctl_card_info_t* card_info;
00517                 snd_ctl_t* ctl_handle;
00518                 err = snd_ctl_open ( &ctl_handle, fCardName, 0 );   check_error ( err );
00519                 snd_ctl_card_info_alloca ( &card_info );
00520                 err = snd_ctl_card_info ( ctl_handle, card_info );  check_error ( err );
00521                 jack_info ( "%s|%d|%d|%d|%d|%s",
00522                             snd_ctl_card_info_get_driver ( card_info ),
00523                             fCardInputs, fCardOutputs,
00524                             fFrequency, fBuffering,
00525                             snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) );
00526             }
00527 
00531             int longinfo()
00532             {
00533                 snd_ctl_card_info_t* card_info;
00534                 snd_ctl_t* ctl_handle;
00535 
00536                 //display info
00537                 jack_info ( "Audio Interface Description :" );
00538                 jack_info ( "Sampling Frequency : %d, Sample Format : %s, buffering : %d, nperiod : %d",
00539                             fFrequency, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ), fBuffering, fPeriod );
00540                 jack_info ( "Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs );
00541                 jack_info ( "Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs );
00542 
00543                 //get audio card info and display
00544                 check_error ( snd_ctl_open ( &ctl_handle, fCardName, 0 ) );
00545                 snd_ctl_card_info_alloca ( &card_info );
00546                 check_error ( snd_ctl_card_info ( ctl_handle, card_info ) );
00547                 printCardInfo ( card_info );
00548 
00549                 //display input/output streams info
00550                 if ( fSoftInputs > 0 )
00551                     printHWParams ( fInputParams );
00552                 if ( fSoftOutputs > 0 )
00553                     printHWParams ( fOutputParams );
00554 
00555                 return 0;
00556             }
00557 
00558             void printCardInfo ( snd_ctl_card_info_t* ci )
00559             {
00560                 jack_info ( "Card info (address : %p)", ci );
00561                 jack_info ( "\tID         = %s", snd_ctl_card_info_get_id ( ci ) );
00562                 jack_info ( "\tDriver     = %s", snd_ctl_card_info_get_driver ( ci ) );
00563                 jack_info ( "\tName       = %s", snd_ctl_card_info_get_name ( ci ) );
00564                 jack_info ( "\tLongName   = %s", snd_ctl_card_info_get_longname ( ci ) );
00565                 jack_info ( "\tMixerName  = %s", snd_ctl_card_info_get_mixername ( ci ) );
00566                 jack_info ( "\tComponents = %s", snd_ctl_card_info_get_components ( ci ) );
00567                 jack_info ( "--------------" );
00568             }
00569 
00570             void printHWParams ( snd_pcm_hw_params_t* params )
00571             {
00572                 jack_info ( "HW Params info (address : %p)\n", params );
00573 #if 0
00574                 jack_info ( "\tChannels    = %d", snd_pcm_hw_params_get_channels ( params, NULL ) );
00575                 jack_info ( "\tFormat      = %s", snd_pcm_format_name ( ( _snd_pcm_format ) snd_pcm_hw_params_get_format ( params, NULL ) ) );
00576                 jack_info ( "\tAccess      = %s", snd_pcm_access_name ( ( _snd_pcm_access ) snd_pcm_hw_params_get_access ( params, NULL ) ) );
00577                 jack_info ( "\tRate        = %d", snd_pcm_hw_params_get_rate ( params, NULL, NULL ) );
00578                 jack_info ( "\tPeriods     = %d", snd_pcm_hw_params_get_periods ( params, NULL, NULL ) );
00579                 jack_info ( "\tPeriod size = %d", ( int ) snd_pcm_hw_params_get_period_size ( params, NULL, NULL ) );
00580                 jack_info ( "\tPeriod time = %d", snd_pcm_hw_params_get_period_time ( params, NULL, NULL ) );
00581                 jack_info ( "\tBuffer size = %d", ( int ) snd_pcm_hw_params_get_buffer_size ( params, NULL ) );
00582                 jack_info ( "\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time ( params, NULL, NULL ) );
00583 #endif
00584                 jack_info ( "--------------" );
00585             }
00586     };
00587 
00592     class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface
00593     {
00594 
00595         private:
00596             JackThread fThread;
00597             AudioInterface fAudioInterface;
00598 
00599         public:
00600             JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params );
00601             ~JackAlsaAdapter()
00602             {}
00603 
00604             virtual int Open();
00605             virtual int Close();
00606 
00607             virtual int SetSampleRate ( jack_nframes_t sample_rate );
00608             virtual int SetBufferSize ( jack_nframes_t buffer_size );
00609 
00610             virtual bool Init();
00611             virtual bool Execute();
00612 
00613     };
00614 
00615 }
00616 
00617 #ifdef __cplusplus
00618 extern "C"
00619 {
00620 #endif
00621 
00622 #include "JackCompilerDeps.h"
00623 #include "driver_interface.h"
00624 
00625     EXPORT jack_driver_desc_t* jack_get_descriptor();
00626 
00627 #ifdef __cplusplus
00628 }
00629 #endif
00630 
00631 #endif