jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

632 lines
26KB

  1. /*
  2. Copyright (C) 2008 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #ifndef __JackAlsaAdapter__
  16. #define __JackAlsaAdapter__
  17. #include <math.h>
  18. #include <limits.h>
  19. #include <assert.h>
  20. #include <alsa/asoundlib.h>
  21. #include "JackAudioAdapterInterface.h"
  22. #include "JackPlatformPlug.h"
  23. #include "JackError.h"
  24. #include "jack.h"
  25. #include "jslist.h"
  26. namespace Jack
  27. {
  28. inline void* aligned_calloc ( size_t nmemb, size_t size ) { return ( void* ) calloc ( nmemb, size ); }
  29. #define max(x,y) (((x)>(y)) ? (x) : (y))
  30. #define min(x,y) (((x)<(y)) ? (x) : (y))
  31. #define check_error(err) if (err) { jack_error("%s:%d, alsa error %d : %s", __FILE__, __LINE__, err, snd_strerror(err)); return err; }
  32. #define check_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); return err; }
  33. #define display_error_msg(err,msg) if (err) { jack_error("%s:%d, %s : %s(%d)", __FILE__, __LINE__, msg, snd_strerror(err), err); }
  34. /**
  35. * A convenient class to pass parameters to AudioInterface
  36. */
  37. class AudioParam
  38. {
  39. public:
  40. const char* fCardName;
  41. unsigned int fFrequency;
  42. int fBuffering;
  43. unsigned int fSoftInputs;
  44. unsigned int fSoftOutputs;
  45. public:
  46. AudioParam() :
  47. fCardName ( "hw:0" ),
  48. fFrequency ( 44100 ),
  49. fBuffering ( 512 ),
  50. fSoftInputs ( 2 ),
  51. fSoftOutputs ( 2 )
  52. {}
  53. AudioParam ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
  54. fCardName ( "hw:0" ),
  55. fFrequency ( sample_rate ),
  56. fBuffering ( buffer_size ),
  57. fSoftInputs ( 2 ),
  58. fSoftOutputs ( 2 )
  59. {}
  60. AudioParam& cardName ( const char* n )
  61. {
  62. fCardName = n;
  63. return *this;
  64. }
  65. AudioParam& frequency ( int f )
  66. {
  67. fFrequency = f;
  68. return *this;
  69. }
  70. AudioParam& buffering ( int fpb )
  71. {
  72. fBuffering = fpb;
  73. return *this;
  74. }
  75. void setInputs ( int inputs )
  76. {
  77. fSoftInputs = inputs;
  78. }
  79. AudioParam& inputs ( int n )
  80. {
  81. fSoftInputs = n;
  82. return *this;
  83. }
  84. void setOutputs ( int outputs )
  85. {
  86. fSoftOutputs = outputs;
  87. }
  88. AudioParam& outputs ( int n )
  89. {
  90. fSoftOutputs = n;
  91. return *this;
  92. }
  93. };
  94. /**
  95. * An ALSA audio interface
  96. */
  97. class AudioInterface : public AudioParam
  98. {
  99. public:
  100. //device info
  101. snd_pcm_t* fOutputDevice;
  102. snd_pcm_t* fInputDevice;
  103. snd_pcm_hw_params_t* fInputParams;
  104. snd_pcm_hw_params_t* fOutputParams;
  105. //samples info
  106. snd_pcm_format_t fSampleFormat;
  107. snd_pcm_access_t fSampleAccess;
  108. //channels
  109. unsigned int fCardInputs;
  110. unsigned int fCardOutputs;
  111. //stream parameters
  112. unsigned int fPeriod;
  113. //interleaved mode audiocard buffers
  114. void* fInputCardBuffer;
  115. void* fOutputCardBuffer;
  116. //non-interleaved mode audiocard buffers
  117. void* fInputCardChannels[256];
  118. void* fOutputCardChannels[256];
  119. //non-interleaved mod, floating point software buffers
  120. jack_default_audio_sample_t* fInputSoftChannels[256];
  121. jack_default_audio_sample_t* fOutputSoftChannels[256];
  122. //public methods ---------------------------------------------------------
  123. const char* cardName()
  124. {
  125. return fCardName;
  126. }
  127. int frequency()
  128. {
  129. return fFrequency;
  130. }
  131. int buffering()
  132. {
  133. return fBuffering;
  134. }
  135. jack_default_audio_sample_t** inputSoftChannels()
  136. {
  137. return fInputSoftChannels;
  138. }
  139. jack_default_audio_sample_t** outputSoftChannels()
  140. {
  141. return fOutputSoftChannels;
  142. }
  143. AudioInterface ( const AudioParam& ap = AudioParam() ) : AudioParam ( ap )
  144. {
  145. fInputDevice = 0;
  146. fOutputDevice = 0;
  147. fInputParams = 0;
  148. fOutputParams = 0;
  149. fPeriod = 2;
  150. fInputCardBuffer = 0;
  151. fOutputCardBuffer = 0;
  152. for ( int i = 0; i < 256; i++ )
  153. {
  154. fInputCardChannels[i] = 0;
  155. fOutputCardChannels[i] = 0;
  156. fInputSoftChannels[i] = 0;
  157. fOutputSoftChannels[i] = 0;
  158. }
  159. }
  160. AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
  161. AudioParam ( buffer_size, sample_rate )
  162. {
  163. fInputCardBuffer = 0;
  164. fOutputCardBuffer = 0;
  165. for ( int i = 0; i < 256; i++ )
  166. {
  167. fInputCardChannels[i] = 0;
  168. fOutputCardChannels[i] = 0;
  169. fInputSoftChannels[i] = 0;
  170. fOutputSoftChannels[i] = 0;
  171. }
  172. }
  173. /**
  174. * Open the audio interface
  175. */
  176. int open()
  177. {
  178. //open input/output streams
  179. check_error ( snd_pcm_open ( &fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0 ) );
  180. check_error ( snd_pcm_open ( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ) );
  181. //get hardware input parameters
  182. check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) );
  183. setAudioParams ( fInputDevice, fInputParams );
  184. //get hardware output parameters
  185. check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) )
  186. setAudioParams ( fOutputDevice, fOutputParams );
  187. // set the number of physical input and output channels close to what we need
  188. fCardInputs = fSoftInputs;
  189. fCardOutputs = fSoftOutputs;
  190. snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
  191. snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
  192. //set input/output param
  193. check_error ( snd_pcm_hw_params ( fInputDevice, fInputParams ) );
  194. check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) );
  195. //set hardware buffers
  196. if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED )
  197. {
  198. fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 );
  199. fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 );
  200. }
  201. else
  202. {
  203. for ( unsigned int i = 0; i < fCardInputs; i++ )
  204. fInputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fInputParams ), 1 );
  205. for ( unsigned int i = 0; i < fCardOutputs; i++ )
  206. fOutputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fOutputParams ), 1 );
  207. }
  208. //set floating point buffers needed by the dsp code
  209. fSoftInputs = max ( fSoftInputs, fCardInputs );
  210. assert ( fSoftInputs < 256 );
  211. fSoftOutputs = max ( fSoftOutputs, fCardOutputs );
  212. assert ( fSoftOutputs < 256 );
  213. for ( unsigned int i = 0; i < fSoftInputs; i++ )
  214. {
  215. fInputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) );
  216. for ( int j = 0; j < fBuffering; j++ )
  217. fInputSoftChannels[i][j] = 0.0;
  218. }
  219. for ( unsigned int i = 0; i < fSoftOutputs; i++ )
  220. {
  221. fOutputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) );
  222. for ( int j = 0; j < fBuffering; j++ )
  223. fOutputSoftChannels[i][j] = 0.0;
  224. }
  225. return 0;
  226. }
  227. int close()
  228. {
  229. snd_pcm_hw_params_free ( fInputParams );
  230. snd_pcm_hw_params_free ( fOutputParams );
  231. snd_pcm_close ( fInputDevice );
  232. snd_pcm_close ( fOutputDevice );
  233. for ( unsigned int i = 0; i < fSoftInputs; i++ )
  234. if ( fInputSoftChannels[i] )
  235. free ( fInputSoftChannels[i] );
  236. for ( unsigned int i = 0; i < fSoftOutputs; i++ )
  237. if ( fOutputSoftChannels[i] )
  238. free ( fOutputSoftChannels[i] );
  239. for ( unsigned int i = 0; i < fCardInputs; i++ )
  240. if ( fInputCardChannels[i] )
  241. free ( fInputCardChannels[i] );
  242. for ( unsigned int i = 0; i < fCardOutputs; i++ )
  243. if ( fOutputCardChannels[i] )
  244. free ( fOutputCardChannels[i] );
  245. if ( fInputCardBuffer )
  246. free ( fInputCardBuffer );
  247. if ( fOutputCardBuffer )
  248. free ( fOutputCardBuffer );
  249. return 0;
  250. }
  251. int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params )
  252. {
  253. //set params record with initial values
  254. check_error_msg ( snd_pcm_hw_params_any ( stream, params ), "unable to init parameters" )
  255. //set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
  256. if ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ) )
  257. check_error_msg ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ),
  258. "unable to set access mode neither to non-interleaved or to interleaved" );
  259. snd_pcm_hw_params_get_access ( params, &fSampleAccess );
  260. //search for 32-bits or 16-bits format
  261. if ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S32 ) )
  262. check_error_msg ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S16 ),
  263. "unable to set format to either 32-bits or 16-bits" );
  264. snd_pcm_hw_params_get_format ( params, &fSampleFormat );
  265. //set sample frequency
  266. snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 );
  267. //set period and period size (buffering)
  268. check_error_msg ( snd_pcm_hw_params_set_period_size ( stream, params, fBuffering, 0 ), "period size not available" );
  269. check_error_msg ( snd_pcm_hw_params_set_periods ( stream, params, fPeriod, 0 ), "number of periods not available" );
  270. return 0;
  271. }
  272. ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params )
  273. {
  274. _snd_pcm_format format;
  275. unsigned int channels;
  276. snd_pcm_hw_params_get_format ( params, &format );
  277. snd_pcm_uframes_t psize;
  278. snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
  279. snd_pcm_hw_params_get_channels ( params, &channels );
  280. ssize_t bsize = snd_pcm_format_size ( format, psize * channels );
  281. return bsize;
  282. }
  283. ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params )
  284. {
  285. _snd_pcm_format format;
  286. snd_pcm_hw_params_get_format ( params, &format );
  287. snd_pcm_uframes_t psize;
  288. snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
  289. ssize_t bsize = snd_pcm_format_size ( format, psize );
  290. return bsize;
  291. }
  292. /**
  293. * Read audio samples from the audio card. Convert samples to floats and take
  294. * care of interleaved buffers
  295. */
  296. int read()
  297. {
  298. int count, s;
  299. unsigned int c;
  300. switch ( fSampleAccess )
  301. {
  302. case SND_PCM_ACCESS_RW_INTERLEAVED :
  303. count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering );
  304. if ( count < 0 )
  305. {
  306. display_error_msg ( count, "reading samples" );
  307. check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
  308. }
  309. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  310. {
  311. short* buffer16b = ( short* ) fInputCardBuffer;
  312. for ( s = 0; s < fBuffering; s++ )
  313. for ( c = 0; c < fCardInputs; c++ )
  314. 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));
  315. }
  316. else // SND_PCM_FORMAT_S32
  317. {
  318. int32_t* buffer32b = ( int32_t* ) fInputCardBuffer;
  319. for ( s = 0; s < fBuffering; s++ )
  320. for ( c = 0; c < fCardInputs; c++ )
  321. 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));
  322. }
  323. break;
  324. case SND_PCM_ACCESS_RW_NONINTERLEAVED :
  325. count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering );
  326. if ( count < 0 )
  327. {
  328. display_error_msg ( count, "reading samples" );
  329. check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
  330. }
  331. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  332. {
  333. short* chan16b;
  334. for ( c = 0; c < fCardInputs; c++ )
  335. {
  336. chan16b = ( short* ) fInputCardChannels[c];
  337. for ( s = 0; s < fBuffering; s++ )
  338. fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan16b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX));
  339. }
  340. }
  341. else // SND_PCM_FORMAT_S32
  342. {
  343. int32_t* chan32b;
  344. for ( c = 0; c < fCardInputs; c++ )
  345. {
  346. chan32b = ( int32_t* ) fInputCardChannels[c];
  347. for ( s = 0; s < fBuffering; s++ )
  348. fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan32b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX));
  349. }
  350. }
  351. break;
  352. default :
  353. check_error_msg ( -10000, "unknow access mode" );
  354. break;
  355. }
  356. return 0;
  357. }
  358. /**
  359. * write the output soft channels to the audio card. Convert sample
  360. * format and interleaves buffers when needed
  361. */
  362. int write()
  363. {
  364. int count, f;
  365. unsigned int c;
  366. recovery:
  367. switch ( fSampleAccess )
  368. {
  369. case SND_PCM_ACCESS_RW_INTERLEAVED :
  370. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  371. {
  372. short* buffer16b = ( short* ) fOutputCardBuffer;
  373. for ( f = 0; f < fBuffering; f++ )
  374. {
  375. for ( unsigned int c = 0; c < fCardOutputs; c++ )
  376. {
  377. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  378. 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));
  379. }
  380. }
  381. }
  382. else // SND_PCM_FORMAT_S32
  383. {
  384. int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer;
  385. for ( f = 0; f < fBuffering; f++ )
  386. {
  387. for ( unsigned int c = 0; c < fCardOutputs; c++ )
  388. {
  389. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  390. 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));
  391. }
  392. }
  393. }
  394. count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering );
  395. if ( count < 0 )
  396. {
  397. display_error_msg ( count, "w3" );
  398. int err = snd_pcm_prepare ( fOutputDevice );
  399. check_error_msg ( err, "preparing output stream" );
  400. goto recovery;
  401. }
  402. break;
  403. case SND_PCM_ACCESS_RW_NONINTERLEAVED :
  404. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  405. {
  406. for ( c = 0; c < fCardOutputs; c++ )
  407. {
  408. short* chan16b = ( short* ) fOutputCardChannels[c];
  409. for ( f = 0; f < fBuffering; f++ )
  410. {
  411. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  412. 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));
  413. }
  414. }
  415. }
  416. else
  417. {
  418. for ( c = 0; c < fCardOutputs; c++ )
  419. {
  420. int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c];
  421. for ( f = 0; f < fBuffering; f++ )
  422. {
  423. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  424. 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));
  425. }
  426. }
  427. }
  428. count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering );
  429. if ( count<0 )
  430. {
  431. display_error_msg ( count, "w3" );
  432. int err = snd_pcm_prepare ( fOutputDevice );
  433. check_error_msg ( err, "preparing output stream" );
  434. goto recovery;
  435. }
  436. break;
  437. default :
  438. check_error_msg ( -10000, "unknow access mode" );
  439. break;
  440. }
  441. return 0;
  442. }
  443. /**
  444. * print short information on the audio device
  445. */
  446. int shortinfo()
  447. {
  448. int err;
  449. snd_ctl_card_info_t* card_info;
  450. snd_ctl_t* ctl_handle;
  451. err = snd_ctl_open ( &ctl_handle, fCardName, 0 ); check_error ( err );
  452. snd_ctl_card_info_alloca ( &card_info );
  453. err = snd_ctl_card_info ( ctl_handle, card_info ); check_error ( err );
  454. jack_info ( "%s|%d|%d|%d|%d|%s",
  455. snd_ctl_card_info_get_driver ( card_info ),
  456. fCardInputs, fCardOutputs,
  457. fFrequency, fBuffering,
  458. snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) );
  459. }
  460. /**
  461. * print more detailled information on the audio device
  462. */
  463. int longinfo()
  464. {
  465. snd_ctl_card_info_t* card_info;
  466. snd_ctl_t* ctl_handle;
  467. //display info
  468. jack_info ( "Audio Interface Description :" );
  469. jack_info ( "Sampling Frequency : %d, Sample Format : %s, buffering : %d, nperiod : %d",
  470. fFrequency, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ), fBuffering, fPeriod );
  471. jack_info ( "Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs );
  472. jack_info ( "Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs );
  473. //get audio card info and display
  474. check_error ( snd_ctl_open ( &ctl_handle, fCardName, 0 ) );
  475. snd_ctl_card_info_alloca ( &card_info );
  476. check_error ( snd_ctl_card_info ( ctl_handle, card_info ) );
  477. printCardInfo ( card_info );
  478. //display input/output streams info
  479. if ( fSoftInputs > 0 )
  480. printHWParams ( fInputParams );
  481. if ( fSoftOutputs > 0 )
  482. printHWParams ( fOutputParams );
  483. return 0;
  484. }
  485. void printCardInfo ( snd_ctl_card_info_t* ci )
  486. {
  487. jack_info ( "Card info (address : %p)", ci );
  488. jack_info ( "\tID = %s", snd_ctl_card_info_get_id ( ci ) );
  489. jack_info ( "\tDriver = %s", snd_ctl_card_info_get_driver ( ci ) );
  490. jack_info ( "\tName = %s", snd_ctl_card_info_get_name ( ci ) );
  491. jack_info ( "\tLongName = %s", snd_ctl_card_info_get_longname ( ci ) );
  492. jack_info ( "\tMixerName = %s", snd_ctl_card_info_get_mixername ( ci ) );
  493. jack_info ( "\tComponents = %s", snd_ctl_card_info_get_components ( ci ) );
  494. jack_info ( "--------------" );
  495. }
  496. void printHWParams ( snd_pcm_hw_params_t* params )
  497. {
  498. jack_info ( "HW Params info (address : %p)\n", params );
  499. #if 0
  500. jack_info ( "\tChannels = %d", snd_pcm_hw_params_get_channels ( params, NULL ) );
  501. jack_info ( "\tFormat = %s", snd_pcm_format_name ( ( _snd_pcm_format ) snd_pcm_hw_params_get_format ( params, NULL ) ) );
  502. jack_info ( "\tAccess = %s", snd_pcm_access_name ( ( _snd_pcm_access ) snd_pcm_hw_params_get_access ( params, NULL ) ) );
  503. jack_info ( "\tRate = %d", snd_pcm_hw_params_get_rate ( params, NULL, NULL ) );
  504. jack_info ( "\tPeriods = %d", snd_pcm_hw_params_get_periods ( params, NULL, NULL ) );
  505. jack_info ( "\tPeriod size = %d", ( int ) snd_pcm_hw_params_get_period_size ( params, NULL, NULL ) );
  506. jack_info ( "\tPeriod time = %d", snd_pcm_hw_params_get_period_time ( params, NULL, NULL ) );
  507. jack_info ( "\tBuffer size = %d", ( int ) snd_pcm_hw_params_get_buffer_size ( params, NULL ) );
  508. jack_info ( "\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time ( params, NULL, NULL ) );
  509. #endif
  510. jack_info ( "--------------" );
  511. }
  512. };
  513. /*!
  514. \brief Audio adapter using ALSA API.
  515. */
  516. class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface
  517. {
  518. private:
  519. JackThread fThread;
  520. AudioInterface fAudioInterface;
  521. public:
  522. JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params );
  523. ~JackAlsaAdapter()
  524. {}
  525. virtual int Open();
  526. virtual int Close();
  527. virtual int SetSampleRate ( jack_nframes_t sample_rate );
  528. virtual int SetBufferSize ( jack_nframes_t buffer_size );
  529. virtual bool Init();
  530. virtual bool Execute();
  531. };
  532. }
  533. #ifdef __cplusplus
  534. extern "C"
  535. {
  536. #endif
  537. #include "JackCompilerDeps.h"
  538. #include "driver_interface.h"
  539. EXPORT jack_driver_desc_t* jack_get_descriptor();
  540. #ifdef __cplusplus
  541. }
  542. #endif
  543. #endif