20 #ifndef __JackAlsaAdapter__
21 #define __JackAlsaAdapter__
26 #include <alsa/asoundlib.h>
27 #include "JackAudioAdapterInterface.h"
28 #include "JackPlatformPlug.h"
29 #include "JackError.h"
36 inline void* aligned_calloc (
size_t nmemb,
size_t size ) {
return (
void* ) calloc ( nmemb, size ); }
38 #define max(x,y) (((x)>(y)) ? (x) : (y))
39 #define min(x,y) (((x)<(y)) ? (x) : (y))
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); }
51 const char* fCardName;
52 unsigned int fFrequency;
55 unsigned int fSoftInputs;
56 unsigned int fSoftOutputs;
67 AudioParam ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
69 fFrequency ( sample_rate ),
70 fBuffering ( buffer_size ),
93 void setInputs (
int inputs )
104 void setOutputs (
int outputs )
106 fSoftOutputs = outputs;
123 snd_pcm_t* fOutputDevice;
124 snd_pcm_t* fInputDevice;
125 snd_pcm_hw_params_t* fInputParams;
126 snd_pcm_hw_params_t* fOutputParams;
129 snd_pcm_format_t fSampleFormat;
130 snd_pcm_access_t fSampleAccess;
133 unsigned int fCardInputs;
134 unsigned int fCardOutputs;
137 unsigned int fPeriod;
140 void* fInputCardBuffer;
141 void* fOutputCardBuffer;
144 void* fInputCardChannels[256];
145 void* fOutputCardChannels[256];
148 jack_default_audio_sample_t* fInputSoftChannels[256];
149 jack_default_audio_sample_t* fOutputSoftChannels[256];
153 const char* cardName()
168 jack_default_audio_sample_t** inputSoftChannels()
170 return fInputSoftChannels;
173 jack_default_audio_sample_t** outputSoftChannels()
175 return fOutputSoftChannels;
186 fInputCardBuffer = 0;
187 fOutputCardBuffer = 0;
189 for (
int i = 0; i < 256; i++ )
191 fInputCardChannels[i] = 0;
192 fOutputCardChannels[i] = 0;
193 fInputSoftChannels[i] = 0;
194 fOutputSoftChannels[i] = 0;
198 AudioInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate ) :
201 fInputCardBuffer = 0;
202 fOutputCardBuffer = 0;
204 for (
int i = 0; i < 256; i++ )
206 fInputCardChannels[i] = 0;
207 fOutputCardChannels[i] = 0;
208 fInputSoftChannels[i] = 0;
209 fOutputSoftChannels[i] = 0;
219 check_error ( snd_pcm_open ( &fInputDevice, fCardName, SND_PCM_STREAM_CAPTURE, 0 ) );
220 check_error ( snd_pcm_open ( &fOutputDevice, fCardName, SND_PCM_STREAM_PLAYBACK, 0 ) );
223 check_error ( snd_pcm_hw_params_malloc ( &fInputParams ) );
224 setAudioParams ( fInputDevice, fInputParams );
227 check_error ( snd_pcm_hw_params_malloc ( &fOutputParams ) )
228 setAudioParams ( fOutputDevice, fOutputParams );
231 fCardInputs = fSoftInputs;
232 fCardOutputs = fSoftOutputs;
234 snd_pcm_hw_params_set_channels_near(fInputDevice, fInputParams, &fCardInputs);
235 snd_pcm_hw_params_set_channels_near(fOutputDevice, fOutputParams, &fCardOutputs);
238 check_error ( snd_pcm_hw_params ( fInputDevice, fInputParams ) );
239 check_error ( snd_pcm_hw_params ( fOutputDevice, fOutputParams ) );
242 if ( fSampleAccess == SND_PCM_ACCESS_RW_INTERLEAVED )
244 fInputCardBuffer = aligned_calloc ( interleavedBufferSize ( fInputParams ), 1 );
245 fOutputCardBuffer = aligned_calloc ( interleavedBufferSize ( fOutputParams ), 1 );
249 for (
unsigned int i = 0; i < fCardInputs; i++ )
250 fInputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fInputParams ), 1 );
251 for (
unsigned int i = 0; i < fCardOutputs; i++ )
252 fOutputCardChannels[i] = aligned_calloc ( noninterleavedBufferSize ( fOutputParams ), 1 );
256 fSoftInputs = max ( fSoftInputs, fCardInputs );
257 assert ( fSoftInputs < 256 );
258 fSoftOutputs = max ( fSoftOutputs, fCardOutputs );
259 assert ( fSoftOutputs < 256 );
261 for (
unsigned int i = 0; i < fSoftInputs; i++ )
263 fInputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering,
sizeof ( jack_default_audio_sample_t ) );
264 for (
int j = 0; j < fBuffering; j++ )
265 fInputSoftChannels[i][j] = 0.0;
268 for (
unsigned int i = 0; i < fSoftOutputs; i++ )
270 fOutputSoftChannels[i] = ( jack_default_audio_sample_t* ) aligned_calloc ( fBuffering,
sizeof ( jack_default_audio_sample_t ) );
271 for (
int j = 0; j < fBuffering; j++ )
272 fOutputSoftChannels[i][j] = 0.0;
279 snd_pcm_hw_params_free ( fInputParams );
280 snd_pcm_hw_params_free ( fOutputParams );
281 snd_pcm_close ( fInputDevice );
282 snd_pcm_close ( fOutputDevice );
284 for (
unsigned int i = 0; i < fSoftInputs; i++ )
285 if ( fInputSoftChannels[i] )
286 free ( fInputSoftChannels[i] );
288 for (
unsigned int i = 0; i < fSoftOutputs; i++ )
289 if ( fOutputSoftChannels[i] )
290 free ( fOutputSoftChannels[i] );
292 for (
unsigned int i = 0; i < fCardInputs; i++ )
293 if ( fInputCardChannels[i] )
294 free ( fInputCardChannels[i] );
296 for (
unsigned int i = 0; i < fCardOutputs; i++ )
297 if ( fOutputCardChannels[i] )
298 free ( fOutputCardChannels[i] );
300 if ( fInputCardBuffer )
301 free ( fInputCardBuffer );
302 if ( fOutputCardBuffer )
303 free ( fOutputCardBuffer );
308 int setAudioParams ( snd_pcm_t* stream, snd_pcm_hw_params_t* params )
311 check_error_msg ( snd_pcm_hw_params_any ( stream, params ),
"unable to init parameters" )
314 if ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_NONINTERLEAVED ) )
315 check_error_msg ( snd_pcm_hw_params_set_access ( stream, params, SND_PCM_ACCESS_RW_INTERLEAVED ),
316 "unable to set access mode neither to non-interleaved or to interleaved" );
317 snd_pcm_hw_params_get_access ( params, &fSampleAccess );
320 if ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S32 ) )
321 check_error_msg ( snd_pcm_hw_params_set_format ( stream, params, SND_PCM_FORMAT_S16 ),
322 "unable to set format to either 32-bits or 16-bits" );
323 snd_pcm_hw_params_get_format ( params, &fSampleFormat );
326 snd_pcm_hw_params_set_rate_near ( stream, params, &fFrequency, 0 );
329 check_error_msg ( snd_pcm_hw_params_set_period_size ( stream, params, fBuffering, 0 ), "period size not available" );
330 check_error_msg ( snd_pcm_hw_params_set_periods ( stream, params, fPeriod, 0 ), "number of periods not available" );
335 ssize_t interleavedBufferSize ( snd_pcm_hw_params_t* params )
337 _snd_pcm_format format;
338 unsigned int channels;
339 snd_pcm_hw_params_get_format ( params, &format );
340 snd_pcm_uframes_t psize;
341 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
342 snd_pcm_hw_params_get_channels ( params, &channels );
343 ssize_t bsize = snd_pcm_format_size ( format, psize * channels );
347 ssize_t noninterleavedBufferSize ( snd_pcm_hw_params_t* params )
349 _snd_pcm_format format;
350 snd_pcm_hw_params_get_format ( params, &format );
351 snd_pcm_uframes_t psize;
352 snd_pcm_hw_params_get_period_size ( params, &psize, NULL );
353 ssize_t bsize = snd_pcm_format_size ( format, psize );
365 switch ( fSampleAccess )
367 case SND_PCM_ACCESS_RW_INTERLEAVED :
368 count = snd_pcm_readi ( fInputDevice, fInputCardBuffer, fBuffering );
371 display_error_msg ( count,
"reading samples" );
372 check_error_msg ( snd_pcm_prepare ( fInputDevice ),
"preparing input stream" );
374 if ( fSampleFormat == SND_PCM_FORMAT_S16 )
376 short* buffer16b = (
short* ) fInputCardBuffer;
377 for ( s = 0; s < fBuffering; s++ )
378 for ( c = 0; c < fCardInputs; c++ )
379 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));
383 int32_t* buffer32b = ( int32_t* ) fInputCardBuffer;
384 for ( s = 0; s < fBuffering; s++ )
385 for ( c = 0; c < fCardInputs; c++ )
386 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));
389 case SND_PCM_ACCESS_RW_NONINTERLEAVED :
390 count = snd_pcm_readn ( fInputDevice, fInputCardChannels, fBuffering );
393 display_error_msg ( count,
"reading samples" );
394 check_error_msg ( snd_pcm_prepare ( fInputDevice ),
"preparing input stream" );
396 if ( fSampleFormat == SND_PCM_FORMAT_S16 )
399 for ( c = 0; c < fCardInputs; c++ )
401 chan16b = (
short* ) fInputCardChannels[c];
402 for ( s = 0; s < fBuffering; s++ )
403 fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan16b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(SHRT_MAX));
409 for ( c = 0; c < fCardInputs; c++ )
411 chan32b = ( int32_t* ) fInputCardChannels[c];
412 for ( s = 0; s < fBuffering; s++ )
413 fInputSoftChannels[c][s] = jack_default_audio_sample_t(chan32b[s]) * (jack_default_audio_sample_t(1.0)/jack_default_audio_sample_t(INT_MAX));
418 check_error_msg ( -10000,
"unknow access mode" );
433 switch ( fSampleAccess )
435 case SND_PCM_ACCESS_RW_INTERLEAVED :
436 if ( fSampleFormat == SND_PCM_FORMAT_S16 )
438 short* buffer16b = (
short* ) fOutputCardBuffer;
439 for ( f = 0; f < fBuffering; f++ )
441 for (
unsigned int c = 0; c < fCardOutputs; c++ )
443 jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
444 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));
450 int32_t* buffer32b = ( int32_t* ) fOutputCardBuffer;
451 for ( f = 0; f < fBuffering; f++ )
453 for (
unsigned int c = 0; c < fCardOutputs; c++ )
455 jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
456 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));
460 count = snd_pcm_writei ( fOutputDevice, fOutputCardBuffer, fBuffering );
463 display_error_msg ( count,
"w3" );
464 int err = snd_pcm_prepare ( fOutputDevice );
465 check_error_msg ( err,
"preparing output stream" );
469 case SND_PCM_ACCESS_RW_NONINTERLEAVED :
470 if ( fSampleFormat == SND_PCM_FORMAT_S16 )
472 for ( c = 0; c < fCardOutputs; c++ )
474 short* chan16b = (
short* ) fOutputCardChannels[c];
475 for ( f = 0; f < fBuffering; f++ )
477 jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
478 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));
484 for ( c = 0; c < fCardOutputs; c++ )
486 int32_t* chan32b = ( int32_t* ) fOutputCardChannels[c];
487 for ( f = 0; f < fBuffering; f++ )
489 jack_default_audio_sample_t x = fOutputSoftChannels[c][f];
490 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));
494 count = snd_pcm_writen ( fOutputDevice, fOutputCardChannels, fBuffering );
497 display_error_msg ( count,
"w3" );
498 int err = snd_pcm_prepare ( fOutputDevice );
499 check_error_msg ( err,
"preparing output stream" );
504 check_error_msg ( -10000,
"unknow access mode" );
516 snd_ctl_card_info_t* card_info;
517 snd_ctl_t* ctl_handle;
518 err = snd_ctl_open ( &ctl_handle, fCardName, 0 ); check_error ( err );
519 snd_ctl_card_info_alloca ( &card_info );
520 err = snd_ctl_card_info ( ctl_handle, card_info ); check_error ( err );
522 snd_ctl_card_info_get_driver ( card_info ),
523 fCardInputs, fCardOutputs,
524 fFrequency, fBuffering,
525 snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ) );
533 snd_ctl_card_info_t* card_info;
534 snd_ctl_t* ctl_handle;
537 jack_info (
"Audio Interface Description :" );
538 jack_info (
"Sampling Frequency : %d, Sample Format : %s, buffering : %d, nperiod : %d",
539 fFrequency, snd_pcm_format_name ( ( _snd_pcm_format ) fSampleFormat ), fBuffering, fPeriod );
540 jack_info (
"Software inputs : %2d, Software outputs : %2d", fSoftInputs, fSoftOutputs );
541 jack_info (
"Hardware inputs : %2d, Hardware outputs : %2d", fCardInputs, fCardOutputs );
544 check_error ( snd_ctl_open ( &ctl_handle, fCardName, 0 ) );
545 snd_ctl_card_info_alloca ( &card_info );
546 check_error ( snd_ctl_card_info ( ctl_handle, card_info ) );
547 printCardInfo ( card_info );
550 if ( fSoftInputs > 0 )
551 printHWParams ( fInputParams );
552 if ( fSoftOutputs > 0 )
553 printHWParams ( fOutputParams );
558 void printCardInfo ( snd_ctl_card_info_t* ci )
560 jack_info (
"Card info (address : %p)", ci );
561 jack_info (
"\tID = %s", snd_ctl_card_info_get_id ( ci ) );
562 jack_info (
"\tDriver = %s", snd_ctl_card_info_get_driver ( ci ) );
563 jack_info (
"\tName = %s", snd_ctl_card_info_get_name ( ci ) );
564 jack_info (
"\tLongName = %s", snd_ctl_card_info_get_longname ( ci ) );
565 jack_info (
"\tMixerName = %s", snd_ctl_card_info_get_mixername ( ci ) );
566 jack_info (
"\tComponents = %s", snd_ctl_card_info_get_components ( ci ) );
570 void printHWParams ( snd_pcm_hw_params_t* params )
572 jack_info (
"HW Params info (address : %p)\n", params );
574 jack_info (
"\tChannels = %d", snd_pcm_hw_params_get_channels ( params, NULL ) );
575 jack_info (
"\tFormat = %s", snd_pcm_format_name ( ( _snd_pcm_format ) snd_pcm_hw_params_get_format ( params, NULL ) ) );
576 jack_info (
"\tAccess = %s", snd_pcm_access_name ( ( _snd_pcm_access ) snd_pcm_hw_params_get_access ( params, NULL ) ) );
577 jack_info (
"\tRate = %d", snd_pcm_hw_params_get_rate ( params, NULL, NULL ) );
578 jack_info (
"\tPeriods = %d", snd_pcm_hw_params_get_periods ( params, NULL, NULL ) );
579 jack_info (
"\tPeriod size = %d", (
int ) snd_pcm_hw_params_get_period_size ( params, NULL, NULL ) );
580 jack_info (
"\tPeriod time = %d", snd_pcm_hw_params_get_period_time ( params, NULL, NULL ) );
581 jack_info (
"\tBuffer size = %d", (
int ) snd_pcm_hw_params_get_buffer_size ( params, NULL ) );
582 jack_info (
"\tBuffer time = %d", snd_pcm_hw_params_get_buffer_time ( params, NULL, NULL ) );
607 virtual int SetSampleRate ( jack_nframes_t sample_rate );
608 virtual int SetBufferSize ( jack_nframes_t buffer_size );
611 virtual bool Execute();
622 #include "JackCompilerDeps.h"
623 #include "driver_interface.h"