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.

639 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 jack_max(x,y) (((x)>(y)) ? (x) : (y))
  30. #define jack_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. const char* fCaptureName;
  110. const char* fPlaybackName;
  111. unsigned int fCardInputs;
  112. unsigned int fCardOutputs;
  113. //stream parameters
  114. unsigned int fPeriod;
  115. //interleaved mode audiocard buffers
  116. void* fInputCardBuffer;
  117. void* fOutputCardBuffer;
  118. //non-interleaved mode audiocard buffers
  119. void* fInputCardChannels[256];
  120. void* fOutputCardChannels[256];
  121. //non-interleaved mod, floating point software buffers
  122. jack_default_audio_sample_t* fInputSoftChannels[256];
  123. jack_default_audio_sample_t* fOutputSoftChannels[256];
  124. //public methods ---------------------------------------------------------
  125. const char* cardName()
  126. {
  127. return fCardName;
  128. }
  129. int frequency()
  130. {
  131. return fFrequency;
  132. }
  133. int buffering()
  134. {
  135. return fBuffering;
  136. }
  137. jack_default_audio_sample_t** inputSoftChannels()
  138. {
  139. return fInputSoftChannels;
  140. }
  141. jack_default_audio_sample_t** outputSoftChannels()
  142. {
  143. return fOutputSoftChannels;
  144. }
  145. AudioInterface ( const AudioParam& ap = AudioParam() ) : AudioParam ( ap )
  146. {
  147. fInputDevice = 0;
  148. fOutputDevice = 0;
  149. fInputParams = 0;
  150. fOutputParams = 0;
  151. fPeriod = 2;
  152. fCaptureName = NULL;
  153. fPlaybackName = NULL;
  154. fInputCardBuffer = 0;
  155. fOutputCardBuffer = 0;
  156. for ( int i = 0; i < 256; i++ )
  157. {
  158. fInputCardChannels[i] = 0;
  159. fOutputCardChannels[i] = 0;
  160. fInputSoftChannels[i] = 0;
  161. fOutputSoftChannels[i] = 0;
  162. }
  163. }
  164. AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
  165. AudioParam ( buffer_size, sample_rate )
  166. {
  167. fInputCardBuffer = 0;
  168. fOutputCardBuffer = 0;
  169. fCaptureName = NULL;
  170. fPlaybackName = NULL;
  171. for ( int i = 0; i < 256; i++ )
  172. {
  173. fInputCardChannels[i] = 0;
  174. fOutputCardChannels[i] = 0;
  175. fInputSoftChannels[i] = 0;
  176. fOutputSoftChannels[i] = 0;
  177. }
  178. }
  179. /**
  180. * Open the audio interface
  181. */
  182. int open()
  183. {
  184. //open input/output streams
  185. check_error ( snd_pcm_open ( &fInputDevice, (fCaptureName == NULL) ? fCardName : fCaptureName, SND_PCM_STREAM_CAPTURE, 0 ) );
  186. check_error ( snd_pcm_open ( &fOutputDevice, (fPlaybackName == NULL) ? fCardName : fPlaybackName, SND_PCM_STREAM_PLAYBACK, 0 ) );
  187. //get hardware input parameters
  188. check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) );
  189. setAudioParams ( fInputDevice, fInputParams );
  190. //get hardware output parameters
  191. check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) )
  192. setAudioParams ( fOutputDevice, fOutputParams );
  193. // set the number of physical input and output channels close to what we need
  194. fCardInputs = fSoftInputs;
  195. fCardOutputs = fSoftOutputs;
  196. snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
  197. snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
  198. //set input/output param
  199. check_error ( snd_pcm_hw_params ( fInputDevice, fInputParams ) );
  200. check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) );
  201. //set hardware buffers
  202. if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED )
  203. {
  204. fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 );
  205. fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 );
  206. }
  207. else
  208. {
  209. for ( unsigned int i = 0; i < fCardInputs; i++ )
  210. fInputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fInputParams ), 1 );
  211. for ( unsigned int i = 0; i < fCardOutputs; i++ )
  212. fOutputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fOutputParams ), 1 );
  213. }
  214. //set floating point buffers needed by the dsp code
  215. fSoftInputs = jack_max ( fSoftInputs, fCardInputs );
  216. assert ( fSoftInputs < 256 );
  217. fSoftOutputs = jack_max ( fSoftOutputs, fCardOutputs );
  218. assert ( fSoftOutputs < 256 );
  219. for ( unsigned int i = 0; i < fSoftInputs; i++ )
  220. {
  221. fInputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) );
  222. for ( int j = 0; j < fBuffering; j++ )
  223. fInputSoftChannels[i][j] = 0.0;
  224. }
  225. for ( unsigned int i = 0; i < fSoftOutputs; i++ )
  226. {
  227. fOutputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering, sizeof ( jack_default_audio_sample_t ) );
  228. for ( int j = 0; j < fBuffering; j++ )
  229. fOutputSoftChannels[i][j] = 0.0;
  230. }
  231. return 0;
  232. }
  233. int close()
  234. {
  235. snd_pcm_hw_params_free ( fInputParams );
  236. snd_pcm_hw_params_free ( fOutputParams );
  237. snd_pcm_close ( fInputDevice );
  238. snd_pcm_close ( fOutputDevice );
  239. for ( unsigned int i = 0; i < fSoftInputs; i++ )
  240. if ( fInputSoftChannels[i] )
  241. free ( fInputSoftChannels[i] );
  242. for ( unsigned int i = 0; i < fSoftOutputs; i++ )
  243. if ( fOutputSoftChannels[i] )
  244. free ( fOutputSoftChannels[i] );
  245. for ( unsigned int i = 0; i < fCardInputs; i++ )
  246. if ( fInputCardChannels[i] )
  247. free ( fInputCardChannels[i] );
  248. for ( unsigned int i = 0; i < fCardOutputs; i++ )
  249. if ( fOutputCardChannels[i] )
  250. free ( fOutputCardChannels[i] );
  251. if ( fInputCardBuffer )
  252. free ( fInputCardBuffer );
  253. if ( fOutputCardBuffer )
  254. free ( fOutputCardBuffer );
  255. return 0;
  256. }
  257. int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params )
  258. {
  259. //set params record with initial values
  260. check_error_msg ( snd_pcm_hw_params_any ( stream, params ), "unable to init parameters" )
  261. //set alsa access mode (and fSampleAccess field) either to non interleaved or interleaved
  262. if ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ) )
  263. check_error_msg ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ),
  264. "unable to set access mode neither to non-interleaved or to interleaved" );
  265. snd_pcm_hw_params_get_access ( params, &fSampleAccess );
  266. //search for 32-bits or 16-bits format
  267. if ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S32 ) )
  268. check_error_msg ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S16 ),
  269. "unable to set format to either 32-bits or 16-bits" );
  270. snd_pcm_hw_params_get_format ( params, &fSampleFormat );
  271. //set sample frequency
  272. snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 );
  273. //set period and period size (buffering)
  274. check_error_msg ( snd_pcm_hw_params_set_period_size ( stream, params, fBuffering, 0 ), "period size not available" );
  275. check_error_msg ( snd_pcm_hw_params_set_periods ( stream, params, fPeriod, 0 ), "number of periods not available" );
  276. return 0;
  277. }
  278. ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params )
  279. {
  280. _snd_pcm_format format;
  281. unsigned int channels;
  282. snd_pcm_hw_params_get_format ( params, &format );
  283. snd_pcm_uframes_t psize;
  284. snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
  285. snd_pcm_hw_params_get_channels ( params, &channels );
  286. ssize_t bsize = snd_pcm_format_size ( format, psize * channels );
  287. return bsize;
  288. }
  289. ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params )
  290. {
  291. _snd_pcm_format format;
  292. snd_pcm_hw_params_get_format ( params, &format );
  293. snd_pcm_uframes_t psize;
  294. snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
  295. ssize_t bsize = snd_pcm_format_size ( format, psize );
  296. return bsize;
  297. }
  298. /**
  299. * Read audio samples from the audio card. Convert samples to floats and take
  300. * care of interleaved buffers
  301. */
  302. int read()
  303. {
  304. int count, s;
  305. unsigned int c;
  306. switch ( fSampleAccess )
  307. {
  308. case SND_PCM_ACCESS_RW_INTERLEAVED :
  309. count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering );
  310. if ( count < 0 )
  311. {
  312. display_error_msg ( count, "reading samples" );
  313. check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
  314. }
  315. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  316. {
  317. short* buffer16b = ( short* ) fInputCardBuffer;
  318. for ( s = 0; s < fBuffering; s++ )
  319. for ( c = 0; c < fCardInputs; c++ )
  320. 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));
  321. }
  322. else // SND_PCM_FORMAT_S32
  323. {
  324. int32_t* buffer32b = ( int32_t* ) fInputCardBuffer;
  325. for ( s = 0; s < fBuffering; s++ )
  326. for ( c = 0; c < fCardInputs; c++ )
  327. 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));
  328. }
  329. break;
  330. case SND_PCM_ACCESS_RW_NONINTERLEAVED :
  331. count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering );
  332. if ( count < 0 )
  333. {
  334. display_error_msg ( count, "reading samples" );
  335. check_error_msg ( snd_pcm_prepare ( fInputDevice ), "preparing input stream" );
  336. }
  337. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  338. {
  339. short* chan16b;
  340. for ( c = 0; c < fCardInputs; c++ )
  341. {
  342. chan16b = ( short* ) fInputCardChannels[c];
  343. for ( s = 0; s < fBuffering; s++ )
  344. fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan16b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX));
  345. }
  346. }
  347. else // SND_PCM_FORMAT_S32
  348. {
  349. int32_t* chan32b;
  350. for ( c = 0; c < fCardInputs; c++ )
  351. {
  352. chan32b = ( int32_t* ) fInputCardChannels[c];
  353. for ( s = 0; s < fBuffering; s++ )
  354. fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan32b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX));
  355. }
  356. }
  357. break;
  358. default :
  359. check_error_msg ( -10000, "unknown access mode" );
  360. break;
  361. }
  362. return 0;
  363. }
  364. /**
  365. * write the output soft channels to the audio card. Convert sample
  366. * format and interleaves buffers when needed
  367. */
  368. int write()
  369. {
  370. int count, f;
  371. unsigned int c;
  372. recovery:
  373. switch ( fSampleAccess )
  374. {
  375. case SND_PCM_ACCESS_RW_INTERLEAVED :
  376. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  377. {
  378. short* buffer16b = ( short* ) fOutputCardBuffer;
  379. for ( f = 0; f < fBuffering; f++ )
  380. {
  381. for ( unsigned int c = 0; c < fCardOutputs; c++ )
  382. {
  383. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  384. 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));
  385. }
  386. }
  387. }
  388. else // SND_PCM_FORMAT_S32
  389. {
  390. int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer;
  391. for ( f = 0; f < fBuffering; f++ )
  392. {
  393. for ( unsigned int c = 0; c < fCardOutputs; c++ )
  394. {
  395. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  396. 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));
  397. }
  398. }
  399. }
  400. count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering );
  401. if ( count < 0 )
  402. {
  403. display_error_msg ( count, "w3" );
  404. int err = snd_pcm_prepare ( fOutputDevice );
  405. check_error_msg ( err, "preparing output stream" );
  406. goto recovery;
  407. }
  408. break;
  409. case SND_PCM_ACCESS_RW_NONINTERLEAVED :
  410. if ( fSampleFormat == SND_PCM_FORMAT_S16 )
  411. {
  412. for ( c = 0; c < fCardOutputs; c++ )
  413. {
  414. short* chan16b = ( short* ) fOutputCardChannels[c];
  415. for ( f = 0; f < fBuffering; f++ )
  416. {
  417. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  418. 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));
  419. }
  420. }
  421. }
  422. else
  423. {
  424. for ( c = 0; c < fCardOutputs; c++ )
  425. {
  426. int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c];
  427. for ( f = 0; f < fBuffering; f++ )
  428. {
  429. jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
  430. 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));
  431. }
  432. }
  433. }
  434. count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering );
  435. if ( count<0 )
  436. {
  437. display_error_msg ( count, "w3" );
  438. int err = snd_pcm_prepare ( fOutputDevice );
  439. check_error_msg ( err, "preparing output stream" );
  440. goto recovery;
  441. }
  442. break;
  443. default :
  444. check_error_msg ( -10000, "unknown access mode" );
  445. break;
  446. }
  447. return 0;
  448. }
  449. /**
  450. * print short information on the audio device
  451. */
  452. int shortinfo()
  453. {
  454. int err;
  455. snd_ctl_card_info_t* card_info;
  456. snd_ctl_t* ctl_handle;
  457. err = snd_ctl_open ( &ctl_handle, fCardName, 0 ); check_error ( err );
  458. snd_ctl_card_info_alloca ( &card_info );
  459. err = snd_ctl_card_info ( ctl_handle, card_info ); check_error ( err );
  460. jack_info ( "%s|%d|%d|%d|%d|%s",
  461. snd_ctl_card_info_get_driver ( card_info ),
  462. fCardInputs, fCardOutputs,
  463. fFrequency, fBuffering,
  464. snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) );
  465. snd_ctl_close(ctl_handle);
  466. }
  467. /**
  468. * print more detailed information on the audio device
  469. */
  470. int longinfo()
  471. {
  472. snd_ctl_card_info_t* card_info;
  473. snd_ctl_t* ctl_handle;
  474. //display info
  475. jack_info ( "Audio Interface Description :" );
  476. jack_info ( "Sampling Frequency : %d, Sample Format : %s, buffering : %d, nperiod : %d",
  477. fFrequency, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ), fBuffering, fPeriod );
  478. jack_info ( "Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs );
  479. jack_info ( "Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs );
  480. //get audio card info and display
  481. check_error ( snd_ctl_open ( &ctl_handle, fCardName, 0 ) );
  482. snd_ctl_card_info_alloca ( &card_info );
  483. check_error ( snd_ctl_card_info ( ctl_handle, card_info ) );
  484. printCardInfo ( card_info );
  485. //display input/output streams info
  486. if ( fSoftInputs > 0 )
  487. printHWParams ( fInputParams );
  488. if ( fSoftOutputs > 0 )
  489. printHWParams ( fOutputParams );
  490. snd_ctl_close(ctl_handle);
  491. return 0;
  492. }
  493. void printCardInfo ( snd_ctl_card_info_t* ci )
  494. {
  495. jack_info ( "Card info (address : %p)", ci );
  496. jack_info ( "\tID = %s", snd_ctl_card_info_get_id ( ci ) );
  497. jack_info ( "\tDriver = %s", snd_ctl_card_info_get_driver ( ci ) );
  498. jack_info ( "\tName = %s", snd_ctl_card_info_get_name ( ci ) );
  499. jack_info ( "\tLongName = %s", snd_ctl_card_info_get_longname ( ci ) );
  500. jack_info ( "\tMixerName = %s", snd_ctl_card_info_get_mixername ( ci ) );
  501. jack_info ( "\tComponents = %s", snd_ctl_card_info_get_components ( ci ) );
  502. jack_info ( "--------------" );
  503. }
  504. void printHWParams ( snd_pcm_hw_params_t* params )
  505. {
  506. jack_info ( "HW Params info (address : %p)\n", params );
  507. #if 0
  508. jack_info ( "\tChannels = %d", snd_pcm_hw_params_get_channels ( params, NULL ) );
  509. jack_info ( "\tFormat = %s", snd_pcm_format_name ( ( _snd_pcm_format ) snd_pcm_hw_params_get_format ( params, NULL ) ) );
  510. jack_info ( "\tAccess = %s", snd_pcm_access_name ( ( _snd_pcm_access ) snd_pcm_hw_params_get_access ( params, NULL ) ) );
  511. jack_info ( "\tRate = %d", snd_pcm_hw_params_get_rate ( params, NULL, NULL ) );
  512. jack_info ( "\tPeriods = %d", snd_pcm_hw_params_get_periods ( params, NULL, NULL ) );
  513. jack_info ( "\tPeriod size = %d", ( int ) snd_pcm_hw_params_get_period_size ( params, NULL, NULL ) );
  514. jack_info ( "\tPeriod time = %d", snd_pcm_hw_params_get_period_time ( params, NULL, NULL ) );
  515. jack_info ( "\tBuffer size = %d", ( int ) snd_pcm_hw_params_get_buffer_size ( params, NULL ) );
  516. jack_info ( "\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time ( params, NULL, NULL ) );
  517. #endif
  518. jack_info ( "--------------" );
  519. }
  520. };
  521. /*!
  522. \brief Audio adapter using ALSA API.
  523. */
  524. class JackAlsaAdapter : public JackAudioAdapterInterface, public JackRunnableInterface
  525. {
  526. private:
  527. JackThread fThread;
  528. AudioInterface fAudioInterface;
  529. public:
  530. JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params );
  531. ~JackAlsaAdapter()
  532. {}
  533. virtual int Open();
  534. virtual int Close();
  535. virtual int SetSampleRate ( jack_nframes_t sample_rate );
  536. virtual int SetBufferSize ( jack_nframes_t buffer_size );
  537. virtual bool Init();
  538. virtual bool Execute();
  539. };
  540. }
  541. #ifdef __cplusplus
  542. extern "C"
  543. {
  544. #endif
  545. #include "JackCompilerDeps.h"
  546. #include "driver_interface.h"
  547. SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor();
  548. #ifdef __cplusplus
  549. }
  550. #endif
  551. #endif