Jack2 1.9.6
|
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