1 /* 2 Copyright (C) 2008 Grame 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 18 */ 19 20 #ifndef __JackAlsaAdapter__ 21 #define __JackAlsaAdapter__ 22 23 #include <math.h> 24 #include <limits.h> 25 #include <assert.h> 26 #include <alsa/asoundlib.h> 27 #include "JackAudioAdapterInterface.h" 28 #include "JackPlatformPlug.h" 29 #include "JackError.h" 30 #include "jack.h" 31 #include "jslist.h" 32 33 namespace Jack 34 { 35 aligned_calloc(size_t nmemb,size_t size)36 inline void* aligned_calloc ( size_t nmemb, size_t size ) { return ( void* ) calloc ( nmemb, size ); } 37 38 #define jack_max(x,y) (((x)>(y)) ? (x) : (y)) 39 #define jack_min(x,y) (((x)<(y)) ? (x) : (y)) 40 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); } 44 45 /** 46 * A convenient class to pass parameters to AudioInterface 47 */ 48 class AudioParam 49 { 50 public: 51 const char* fCardName; 52 unsigned int fFrequency; 53 int fBuffering; 54 55 unsigned int fSoftInputs; 56 unsigned int fSoftOutputs; 57 58 public: AudioParam()59 AudioParam() : 60 fCardName ( "hw:0" ), 61 fFrequency ( 44100 ), 62 fBuffering ( 512 ), 63 fSoftInputs ( 2 ), 64 fSoftOutputs ( 2 ) 65 {} 66 AudioParam(jack_nframes_t buffer_size,jack_nframes_t sample_rate)67 AudioParam ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : 68 fCardName ( "hw:0" ), 69 fFrequency ( sample_rate ), 70 fBuffering ( buffer_size ), 71 fSoftInputs ( 2 ), 72 fSoftOutputs ( 2 ) 73 {} 74 cardName(const char * n)75 AudioParam& cardName ( const char* n ) 76 { 77 fCardName = n; 78 return *this; 79 } 80 frequency(int f)81 AudioParam& frequency ( int f ) 82 { 83 fFrequency = f; 84 return *this; 85 } 86 buffering(int fpb)87 AudioParam& buffering ( int fpb ) 88 { 89 fBuffering = fpb; 90 return *this; 91 } 92 setInputs(int inputs)93 void setInputs ( int inputs ) 94 { 95 fSoftInputs = inputs; 96 } 97 inputs(int n)98 AudioParam& inputs ( int n ) 99 { 100 fSoftInputs = n; 101 return *this; 102 } 103 setOutputs(int outputs)104 void setOutputs ( int outputs ) 105 { 106 fSoftOutputs = outputs; 107 } 108 outputs(int n)109 AudioParam& outputs ( int n ) 110 { 111 fSoftOutputs = n; 112 return *this; 113 } 114 }; 115 116 /** 117 * An ALSA audio interface 118 */ 119 class AudioInterface : public AudioParam 120 { 121 public: 122 //device info 123 snd_pcm_t* fOutputDevice; 124 snd_pcm_t* fInputDevice; 125 snd_pcm_hw_params_t* fInputParams; 126 snd_pcm_hw_params_t* fOutputParams; 127 128 //samples info 129 snd_pcm_format_t fSampleFormat; 130 snd_pcm_access_t fSampleAccess; 131 132 //channels 133 const char* fCaptureName; 134 const char* fPlaybackName; 135 unsigned int fCardInputs; 136 unsigned int fCardOutputs; 137 138 //stream parameters 139 unsigned int fPeriod; 140 141 //interleaved mode audiocard buffers 142 void* fInputCardBuffer; 143 void* fOutputCardBuffer; 144 145 //non-interleaved mode audiocard buffers 146 void* fInputCardChannels[256]; 147 void* fOutputCardChannels[256]; 148 149 //non-interleaved mod, floating point software buffers 150 jack_default_audio_sample_t* fInputSoftChannels[256]; 151 jack_default_audio_sample_t* fOutputSoftChannels[256]; 152 153 //public methods --------------------------------------------------------- 154 cardName()155 const char* cardName() 156 { 157 return fCardName; 158 } 159 frequency()160 int frequency() 161 { 162 return fFrequency; 163 } 164 buffering()165 int buffering() 166 { 167 return fBuffering; 168 } 169 inputSoftChannels()170 jack_default_audio_sample_t** inputSoftChannels() 171 { 172 return fInputSoftChannels; 173 } 174 outputSoftChannels()175 jack_default_audio_sample_t** outputSoftChannels() 176 { 177 return fOutputSoftChannels; 178 } 179 AudioParam(ap)180 AudioInterface ( const AudioParam& ap = AudioParam() ) : AudioParam ( ap ) 181 { 182 fInputDevice = 0; 183 fOutputDevice = 0; 184 fInputParams = 0; 185 fOutputParams = 0; 186 fPeriod = 2; 187 fCaptureName = NULL; 188 fPlaybackName = NULL; 189 190 fInputCardBuffer = 0; 191 fOutputCardBuffer = 0; 192 193 for ( int i = 0; i < 256; i++ ) 194 { 195 fInputCardChannels[i] = 0; 196 fOutputCardChannels[i] = 0; 197 fInputSoftChannels[i] = 0; 198 fOutputSoftChannels[i] = 0; 199 } 200 } 201 AudioInterface(jack_nframes_t buffer_size,jack_nframes_t sample_rate)202 AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) : 203 AudioParam ( buffer_size, sample_rate ) 204 { 205 fInputCardBuffer = 0; 206 fOutputCardBuffer = 0; 207 fCaptureName = NULL; 208 fPlaybackName = NULL; 209 210 for ( int i = 0; i < 256; i++ ) 211 { 212 fInputCardChannels[i] = 0; 213 fOutputCardChannels[i] = 0; 214 fInputSoftChannels[i] = 0; 215 fOutputSoftChannels[i] = 0; 216 } 217 } 218 219 /** 220 * Open the audio interface 221 */ open()222 int open() 223 { 224 //open input/output streams 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 ) ); 227 228 //get hardware input parameters 229 check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) ); 230 setAudioParams ( fInputDevice, fInputParams ); 231 232 //get hardware output parameters 233 check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) ) 234 setAudioParams ( fOutputDevice, fOutputParams ); 235 236 // set the number of physical input and output channels close to what we need 237 fCardInputs = fSoftInputs; 238 fCardOutputs = fSoftOutputs; 239 240 snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs); 241 snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs); 242 243 //set input/output param 244 check_error ( snd_pcm_hw_params ( fInputDevice, fInputParams ) ); 245 check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) ); 246 247 //set hardware buffers 248 if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED ) 249 { 250 fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 ); 251 fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 ); 252 } 253 else 254 { 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 ); 259 } 260 261 //set floating point buffers needed by the dsp code 262 fSoftInputs = jack_max ( fSoftInputs, fCardInputs ); 263 assert ( fSoftInputs < 256 ); 264 fSoftOutputs = jack_max ( fSoftOutputs, fCardOutputs ); 265 assert ( fSoftOutputs < 256 ); 266 267 for ( unsigned int i = 0; i < fSoftInputs; i++ ) 268 { 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; 272 } 273 274 for ( unsigned int i = 0; i < fSoftOutputs; i++ ) 275 { 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; 279 } 280 return 0; 281 } 282 close()283 int close() 284 { 285 snd_pcm_hw_params_free ( fInputParams ); 286 snd_pcm_hw_params_free ( fOutputParams ); 287 snd_pcm_close ( fInputDevice ); 288 snd_pcm_close ( fOutputDevice ); 289 290 for ( unsigned int i = 0; i < fSoftInputs; i++ ) 291 if ( fInputSoftChannels[i] ) 292 free ( fInputSoftChannels[i] ); 293 294 for ( unsigned int i = 0; i < fSoftOutputs; i++ ) 295 if ( fOutputSoftChannels[i] ) 296 free ( fOutputSoftChannels[i] ); 297 298 for ( unsigned int i = 0; i < fCardInputs; i++ ) 299 if ( fInputCardChannels[i] ) 300 free ( fInputCardChannels[i] ); 301 302 for ( unsigned int i = 0; i < fCardOutputs; i++ ) 303 if ( fOutputCardChannels[i] ) 304 free ( fOutputCardChannels[i] ); 305 306 if ( fInputCardBuffer ) 307 free ( fInputCardBuffer ); 308 if ( fOutputCardBuffer ) 309 free ( fOutputCardBuffer ); 310 311 return 0; 312 } 313 setAudioParams(snd_pcm_t * stream,snd_pcm_hw_params_t * params)314 int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params ) 315 { 316 //set params record with initial values 317 check_error_msg ( snd_pcm_hw_params_any ( stream, params ), "unable to init parameters" ) 318 319 //set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved 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 ); 324 325 //search for 32-bits or 16-bits format 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 ); 330 331 //set sample frequency 332 snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 ); 333 334 //set period and period size (buffering) 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" ); 337 338 return 0; 339 } 340 interleavedBufferSize(snd_pcm_hw_params_t * params)341 ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params ) 342 { 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 ); 350 return bsize; 351 } 352 noninterleavedBufferSize(snd_pcm_hw_params_t * params)353 ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params ) 354 { 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 ); 360 return bsize; 361 } 362 363 /** 364 * Read audio samples from the audio card. Convert samples to floats and take 365 * care of interleaved buffers 366 */ read()367 int read() 368 { 369 int count, s; 370 unsigned int c; 371 switch ( fSampleAccess ) 372 { 373 case SND_PCM_ACCESS_RW_INTERLEAVED : 374 count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering ); 375 if ( count < 0 ) 376 { 377 display_error_msg ( count, "reading samples" ); 378 check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" ); 379 } 380 if ( fSampleFormat == SND_PCM_FORMAT_S16 ) 381 { 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)); 386 } 387 else // SND_PCM_FORMAT_S32 388 { 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)); 393 } 394 break; 395 case SND_PCM_ACCESS_RW_NONINTERLEAVED : 396 count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering ); 397 if ( count < 0 ) 398 { 399 display_error_msg ( count, "reading samples" ); 400 check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" ); 401 } 402 if ( fSampleFormat == SND_PCM_FORMAT_S16 ) 403 { 404 short* chan16b; 405 for ( c = 0; c < fCardInputs; c++ ) 406 { 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)); 410 } 411 } 412 else // SND_PCM_FORMAT_S32 413 { 414 int32_t* chan32b; 415 for ( c = 0; c < fCardInputs; c++ ) 416 { 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)); 420 } 421 } 422 break; 423 default : 424 check_error_msg ( -10000, "unknown access mode" ); 425 break; 426 } 427 return 0; 428 } 429 430 /** 431 * write the output soft channels to the audio card. Convert sample 432 * format and interleaves buffers when needed 433 */ write()434 int write() 435 { 436 int count, f; 437 unsigned int c; 438 recovery: 439 switch ( fSampleAccess ) 440 { 441 case SND_PCM_ACCESS_RW_INTERLEAVED : 442 if ( fSampleFormat == SND_PCM_FORMAT_S16 ) 443 { 444 short* buffer16b = ( short* ) fOutputCardBuffer; 445 for ( f = 0; f < fBuffering; f++ ) 446 { 447 for ( unsigned int c = 0; c < fCardOutputs; c++ ) 448 { 449 jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; 450 buffer16b[c + f * fCardOutputs] = short(jack_max(jack_min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX)); 451 } 452 } 453 } 454 else // SND_PCM_FORMAT_S32 455 { 456 int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer; 457 for ( f = 0; f < fBuffering; f++ ) 458 { 459 for ( unsigned int c = 0; c < fCardOutputs; c++ ) 460 { 461 jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; 462 buffer32b[c + f * fCardOutputs] = int32_t(jack_max(jack_min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX)); 463 } 464 } 465 } 466 count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering ); 467 if ( count < 0 ) 468 { 469 display_error_msg ( count, "w3" ); 470 int err = snd_pcm_prepare ( fOutputDevice ); 471 check_error_msg ( err, "preparing output stream" ); 472 goto recovery; 473 } 474 break; 475 case SND_PCM_ACCESS_RW_NONINTERLEAVED : 476 if ( fSampleFormat == SND_PCM_FORMAT_S16 ) 477 { 478 for ( c = 0; c < fCardOutputs; c++ ) 479 { 480 short* chan16b = ( short* ) fOutputCardChannels[c]; 481 for ( f = 0; f < fBuffering; f++ ) 482 { 483 jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; 484 chan16b[f] = short(jack_max(jack_min (x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(SHRT_MAX)); 485 } 486 } 487 } 488 else 489 { 490 for ( c = 0; c < fCardOutputs; c++ ) 491 { 492 int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c]; 493 for ( f = 0; f < fBuffering; f++ ) 494 { 495 jack_default_audio_sample_t x = fOutputSoftChannels[c][f]; 496 chan32b[f] = int32_t(jack_max(jack_min(x, jack_default_audio_sample_t(1.0)), jack_default_audio_sample_t(-1.0)) * jack_default_audio_sample_t(INT_MAX)); 497 } 498 } 499 } 500 count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering ); 501 if ( count<0 ) 502 { 503 display_error_msg ( count, "w3" ); 504 int err = snd_pcm_prepare ( fOutputDevice ); 505 check_error_msg ( err, "preparing output stream" ); 506 goto recovery; 507 } 508 break; 509 default : 510 check_error_msg ( -10000, "unknown access mode" ); 511 break; 512 } 513 return 0; 514 } 515 516 /** 517 * print short information on the audio device 518 */ shortinfo()519 int shortinfo() 520 { 521 int err; 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 ); 527 jack_info ( "%s|%d|%d|%d|%d|%s", 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); 533 } 534 535 /** 536 * print more detailed information on the audio device 537 */ longinfo()538 int longinfo() 539 { 540 snd_ctl_card_info_t* card_info; 541 snd_ctl_t* ctl_handle; 542 543 //display info 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 ); 549 550 //get audio card info and display 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 ); 555 556 //display input/output streams info 557 if ( fSoftInputs > 0 ) 558 printHWParams ( fInputParams ); 559 if ( fSoftOutputs > 0 ) 560 printHWParams ( fOutputParams ); 561 snd_ctl_close(ctl_handle); 562 return 0; 563 } 564 printCardInfo(snd_ctl_card_info_t * ci)565 void printCardInfo ( snd_ctl_card_info_t* ci ) 566 { 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 ) ); 574 jack_info ( "--------------" ); 575 } 576 printHWParams(snd_pcm_hw_params_t * params)577 void printHWParams ( snd_pcm_hw_params_t* params ) 578 { 579 jack_info ( "HW Params info (address : %p)\n", params ); 580 #if 0 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 ) ); 590 #endif 591 jack_info ( "--------------" ); 592 } 593 }; 594 595 /*! 596 \brief Audio adapter using ALSA API. 597 */ 598 599 class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface 600 { 601 602 private: 603 JackThread fThread; 604 AudioInterface fAudioInterface; 605 606 public: 607 JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ); ~JackAlsaAdapter()608 ~JackAlsaAdapter() 609 {} 610 611 virtual int Open(); 612 virtual int Close(); 613 614 virtual int SetSampleRate ( jack_nframes_t sample_rate ); 615 virtual int SetBufferSize ( jack_nframes_t buffer_size ); 616 617 virtual bool Init(); 618 virtual bool Execute(); 619 620 }; 621 622 } 623 624 #ifdef __cplusplus 625 extern "C" 626 { 627 #endif 628 629 #include "JackCompilerDeps.h" 630 #include "driver_interface.h" 631 632 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor(); 633 634 #ifdef __cplusplus 635 } 636 #endif 637 638 #endif 639