2
Copyright (C) 2003-2010 Fons Adriaensen <fons@kokkinizita.net>
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.
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.
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.
21
#include "clalsadrv.h"
24
// Public members ----------------------------------------------------------------------
27
Alsa_driver::~Alsa_driver (void)
29
snd_pcm_sw_params_free (_capt_swpar);
30
snd_pcm_hw_params_free (_capt_hwpar);
31
snd_pcm_sw_params_free (_play_swpar);
32
snd_pcm_hw_params_free (_play_hwpar);
34
if (_play_handle) snd_pcm_close (_play_handle);
35
if (_capt_handle) snd_pcm_close (_capt_handle);
36
if (_ctrl_handle) snd_ctl_close (_ctrl_handle);
40
Alsa_driver::Alsa_driver (const char *play_name,
41
const char *capt_name,
42
const char *ctrl_name,
44
snd_pcm_uframes_t frsize,
45
unsigned int nfrags) :
63
initialise (play_name, capt_name, ctrl_name, rate, frsize, nfrags);
67
Alsa_driver::Alsa_driver (const char *name,
69
snd_pcm_uframes_t frsize,
91
initialise (play ? name : 0, capt ? name : 0, ctrl ? name : 0, rate, frsize, nfrags);
95
int Alsa_driver::pcm_start (void)
102
n = snd_pcm_avail_update (_play_handle);
103
if (n != _frsize * _nfrags)
105
fprintf (stderr, "Alsa_driver: full buffer not available at start.\n");
109
for (i = 0; i < _nfrags; i++)
112
for (j = 0; j < _play_nchan; j++) clear_chan (j, _frsize);
116
if ((err = snd_pcm_start (_play_handle)) < 0)
118
fprintf (stderr, "Alsa_driver: pcm_start(play): %s.\n", snd_strerror (err));
123
if (_capt_handle && !_synced && ((err = snd_pcm_start (_capt_handle)) < 0))
125
fprintf (stderr, "Alsa_driver: pcm_start(capt): %s.\n", snd_strerror (err));
133
int Alsa_driver::pcm_stop (void)
137
if (_play_handle && ((err = snd_pcm_drop (_play_handle)) < 0))
139
fprintf (stderr, "Alsa_driver: pcm_drop(play): %s.\n", snd_strerror (err));
143
if (_capt_handle && !_synced && ((err = snd_pcm_drop (_capt_handle)) < 0))
145
fprintf (stderr, "Alsa_driver: pcm_drop(capt): %s.\n", snd_strerror (err));
153
snd_pcm_sframes_t Alsa_driver::pcm_wait (void)
157
snd_pcm_sframes_t capt_av;
158
snd_pcm_sframes_t play_av;
163
need_capt = _capt_handle ? true : false;
164
need_play = _play_handle ? true : false;
166
while (need_play || need_capt)
171
snd_pcm_poll_descriptors (_play_handle, _pfd, _play_npfd);
177
snd_pcm_poll_descriptors (_capt_handle, _pfd + n1, _capt_npfd);
181
for (i = 0; i < n2; i++) _pfd [i].events |= POLLERR;
183
r = poll (_pfd, n2, 1000);
191
fprintf (stderr, "Alsa_driver: poll(): %s\n.", strerror (errno));
197
fprintf (stderr, "Alsa_driver: poll timed out\n.");
204
snd_pcm_poll_descriptors_revents (_play_handle, _pfd, n1, &rev);
207
fprintf (stderr, "Alsa_driver: error on playback pollfd.\n");
212
if (rev & POLLOUT) need_play = false;
216
snd_pcm_poll_descriptors_revents (_capt_handle, _pfd + n1, n2 - n1, &rev);
219
fprintf (stderr, "Alsa_driver: error on capture pollfd.\n");
224
if (rev & POLLIN) need_capt = false;
229
if (_play_handle && (play_av = snd_pcm_avail_update (_play_handle)) < 0)
237
if (_capt_handle && (capt_av = snd_pcm_avail_update (_capt_handle)) < 0)
244
return (capt_av < play_av) ? capt_av : play_av;
248
int Alsa_driver::pcm_idle (snd_pcm_uframes_t len)
251
snd_pcm_uframes_t n, k;
270
for (i = 0; i < _play_nchan; i++) clear_chan (i, k);
280
int Alsa_driver::play_init (snd_pcm_uframes_t len)
283
const snd_pcm_channel_area_t *a;
286
if ((err = snd_pcm_mmap_begin (_play_handle, &a, &_play_offs, &len)) < 0)
288
fprintf (stderr, "Alsa_driver: snd_pcm_mmap_begin(play): %s.\n", snd_strerror (err));
292
_play_step = (a->step) >> 3;
293
for (i = 0; i < _play_nchan; i++, a++)
295
_play_ptr [i] = (char *) a->addr + ((a->first + a->step * _play_offs) >> 3);
302
int Alsa_driver::capt_init (snd_pcm_uframes_t len)
305
const snd_pcm_channel_area_t *a;
308
if ((err = snd_pcm_mmap_begin (_capt_handle, &a, &_capt_offs, &len)) < 0)
310
fprintf (stderr, "Alsa_driver: snd_pcm_mmap_begin(capt): %s.\n", snd_strerror (err));
314
_capt_step = (a->step) >> 3;
315
for (i = 0; i < _capt_nchan; i++, a++)
317
_capt_ptr [i] = (char *) a->addr + ((a->first + a->step * _capt_offs) >> 3);
324
void Alsa_driver::printinfo (void)
326
fprintf (stderr, "playback :");
329
fprintf (stderr, "\n nchan : %d\n", _play_nchan);
330
fprintf (stderr, " rate : %d\n", _rate);
331
fprintf (stderr, " frsize : %ld\n", _frsize);
332
fprintf (stderr, " nfrags : %d\n", _nfrags);
333
fprintf (stderr, " format : %s\n", snd_pcm_format_name (_play_format));
335
else fprintf (stderr, " not enabled\n");
336
fprintf (stderr, "capture :");
339
fprintf (stderr, "\n nchan : %d\n", _capt_nchan);
340
fprintf (stderr, " rate : %d\n", _rate);
341
fprintf (stderr, " frsize : %ld\n", _frsize);
342
fprintf (stderr, " nfrags : %d\n", _nfrags);
343
fprintf (stderr, " format : %s\n", snd_pcm_format_name (_capt_format));
344
if (_play_handle) fprintf (stderr, "%s\n", _synced ? "synced" : "not synced");
346
else fprintf (stderr, " not enabled\n");
350
// Private members ---------------------------------------------------------------------
353
void Alsa_driver::initialise (const char *play_name,
354
const char *capt_name,
355
const char *ctrl_name,
357
snd_pcm_uframes_t frsize,
361
snd_ctl_card_info_t *card;
365
if (snd_pcm_open (&_play_handle, play_name, SND_PCM_STREAM_PLAYBACK, 0) < 0)
368
fprintf (stderr, "Alsa_driver: Cannot open PCM device %s for playback.\n", play_name);
374
if (snd_pcm_open (&_capt_handle, capt_name, SND_PCM_STREAM_CAPTURE, 0) < 0)
377
fprintf (stderr, "Alsa_driver: Cannot open PCM device %s for capture.\n", capt_name);
381
if (! _play_handle && ! _capt_handle) return;
385
snd_ctl_card_info_alloca (&card);
387
if ((err = snd_ctl_open (&_ctrl_handle, ctrl_name, 0)) < 0)
389
fprintf (stderr, "Alse_driver: ctl_open(): %s\n", snd_strerror (err));
393
if ((err = snd_ctl_card_info (_ctrl_handle, card)) < 0)
395
fprintf (stderr, "Alsa_driver: ctl_card_info(): %s\n", snd_strerror (err));
400
// check capabilities here
404
if (snd_pcm_hw_params_malloc (&_play_hwpar) < 0)
406
fprintf (stderr, "Alsa_driver: can't allocate playback hw params\n");
410
if (snd_pcm_sw_params_malloc (&_play_swpar) < 0)
412
fprintf (stderr, "Alsa_driver: can't allocate playback sw params\n");
416
if (set_hwpar (_play_handle, _play_hwpar, "playback", &_play_nchan) < 0) return;
418
if (_play_nchan > MAXPLAY)
420
fprintf (stderr, "Alsa_driver: detected %d playback channels, reset to %d.\n", _play_nchan, MAXPLAY);
421
_play_nchan = MAXPLAY;
424
if (set_swpar (_play_handle, _play_swpar, "playback") < 0) return;
429
if (snd_pcm_hw_params_malloc (&_capt_hwpar) < 0)
431
fprintf (stderr, "Alsa_driver: can't allocate capture hw params\n");
435
if (snd_pcm_sw_params_malloc (&_capt_swpar) < 0)
437
fprintf (stderr, "Alsa_driver: can't allocate capture sw params\n");
441
if (set_hwpar (_capt_handle, _capt_hwpar, "capture", &_capt_nchan) < 0) return;
443
if (_capt_nchan > MAXCAPT)
445
fprintf (stderr, "Alsa_driver: detected %d capture channels, reset to %d\n", _capt_nchan, MAXCAPT);
446
_capt_nchan = MAXCAPT;
449
if (set_swpar (_capt_handle, _capt_swpar, "capture") < 0) return;
454
if (snd_pcm_hw_params_get_rate (_play_hwpar, &rate, &dir) || (rate != _rate) || dir)
456
fprintf (stderr, "Alsa_driver: can't get requested sample rate for playback.\n");
460
if (snd_pcm_hw_params_get_period_size (_play_hwpar, &frsize, &dir) || (frsize != _frsize) || dir)
462
fprintf (stderr, "Alsa_driver: can't get requested period size for playback.\n");
466
if (snd_pcm_hw_params_get_periods (_play_hwpar, &nfrags, &dir) || (nfrags != _nfrags) || dir)
468
fprintf (stderr, "Alsa_driver: can't get requested number of periods for playback.\n");
472
snd_pcm_hw_params_get_format (_play_hwpar, &_play_format);
473
snd_pcm_hw_params_get_access (_play_hwpar, &_play_access);
475
switch (_play_format)
477
case SND_PCM_FORMAT_S32_LE:
478
_clear_func = clear_32le;
479
_play_func = play_32le;
482
case SND_PCM_FORMAT_S24_3LE:
483
_clear_func = clear_24le;
484
_play_func = play_24le;
487
case SND_PCM_FORMAT_S16_LE:
488
_clear_func = clear_16le;
489
_play_func = play_16le;
493
fprintf (stderr, "Alsa_driver: can't handle playback sample format.\n");
497
_play_npfd = snd_pcm_poll_descriptors_count (_play_handle);
502
if (snd_pcm_hw_params_get_rate (_capt_hwpar, &rate, &dir) || (rate != _rate) || dir)
504
fprintf (stderr, "Alsa_driver: can't get requested sample rate for capture.\n");
508
if (snd_pcm_hw_params_get_period_size (_capt_hwpar, &frsize, &dir) || (frsize != _frsize) || dir)
510
fprintf (stderr, "Alsa_driver: can't get requested period size for capture.\n");
514
if (snd_pcm_hw_params_get_periods (_capt_hwpar, &nfrags, &dir) || (nfrags != _nfrags) || dir)
516
fprintf (stderr, "Alsa_driver: can't get requested number of periods for capture.\n");
520
if (_play_handle) _synced = ! snd_pcm_link (_play_handle, _capt_handle);
522
snd_pcm_hw_params_get_format (_capt_hwpar, &_capt_format);
523
snd_pcm_hw_params_get_access (_capt_hwpar, &_capt_access);
525
switch (_capt_format)
527
case SND_PCM_FORMAT_S32_LE:
528
_capt_func = capt_32le;
531
case SND_PCM_FORMAT_S24_3LE:
532
_capt_func = capt_24le;
535
case SND_PCM_FORMAT_S16_LE:
536
_capt_func = capt_16le;
540
fprintf (stderr, "Alsa_driver: can't handle capture sample format.\n");
544
_capt_npfd = snd_pcm_poll_descriptors_count (_capt_handle);
547
if (_play_npfd + _capt_npfd > MAXPFD)
549
fprintf (stderr, "Alsa_driver: interface requires more than %d pollfd\n", MAXPFD);
557
int Alsa_driver::set_hwpar (snd_pcm_t *handle, snd_pcm_hw_params_t *hwpar, const char *sname, unsigned int *nchan)
562
if ((err = snd_pcm_hw_params_any (handle, hwpar)) < 0)
564
fprintf (stderr, "Alsa_driver: no %s hw configurations available: %s.\n", sname, snd_strerror (err));
568
if ((err = snd_pcm_hw_params_set_periods_integer (handle, hwpar)) < 0)
570
fprintf (stderr, "Alsa_driver: can't set %s period size to integral value.\n", sname);
574
if ( ((err = snd_pcm_hw_params_set_access (handle, hwpar, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) < 0)
575
&& ((err = snd_pcm_hw_params_set_access (handle, hwpar, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0)
576
&& ((err = snd_pcm_hw_params_set_access (handle, hwpar, SND_PCM_ACCESS_MMAP_COMPLEX)) < 0))
578
fprintf (stderr, "Alsa_driver: the %s interface doesn't support mmap-based access.\n", sname);
582
if ( ((err = snd_pcm_hw_params_set_format (handle, hwpar, SND_PCM_FORMAT_S32_LE)) < 0)
583
&& ((err = snd_pcm_hw_params_set_format (handle, hwpar, SND_PCM_FORMAT_S24_3LE)) < 0)
584
&& ((err = snd_pcm_hw_params_set_format (handle, hwpar, SND_PCM_FORMAT_S16_LE)) < 0))
586
fprintf (stderr, "Alsa_driver: the %s interface doesn't support 32, 24 or 16 bit access.\n.", sname);
590
if ((err = snd_pcm_hw_params_set_rate (handle, hwpar, _rate, 0)) < 0)
592
fprintf (stderr, "Alsa_driver: can't set %s sample rate to %u.\n", sname, _rate);
596
snd_pcm_hw_params_get_channels_max (hwpar, nchan);
600
fprintf (stderr, "Alsa_driver: detected more than 1024 %s channnels, reset to 2.\n", sname);
604
if ((err = snd_pcm_hw_params_set_channels (handle, hwpar, *nchan)) < 0)
606
fprintf (stderr, "Alsa_driver: can't set %s channel count to %u.\n", sname, *nchan);
611
if ((err = snd_pcm_hw_params_set_period_size (handle, hwpar, _frsize, 0)) < 0)
613
fprintf (stderr, "Alsa_driver: can't set %s period size to %lu.\n", sname, _frsize);
617
// This is to handle recent ALSA releases creating a default device with
618
// a large number of periods...
620
snd_pcm_hw_params_set_periods_min (handle, hwpar, &n, NULL);
621
if (_nfrags < n) _nfrags = n;
623
if ((err = snd_pcm_hw_params_set_periods_near (handle, hwpar, &_nfrags, 0)) < 0)
625
fprintf (stderr, "Alsa_driver: can't set %s periods to %u.\n", sname, _nfrags);
629
if ((err = snd_pcm_hw_params_set_buffer_size (handle, hwpar, _frsize * _nfrags)) < 0)
631
fprintf (stderr, "Alsa_driver: can't set %s buffer length to %lu.\n", sname, _frsize * _nfrags);
635
if ((err = snd_pcm_hw_params (handle, hwpar)) < 0)
637
fprintf (stderr, "Alsa_driver: can't set %s hardware parameters.\n", sname);
645
int Alsa_driver::set_swpar (snd_pcm_t *handle, snd_pcm_sw_params_t *swpar, const char *sname)
649
snd_pcm_sw_params_current (handle, swpar);
651
if ((err = snd_pcm_sw_params_set_tstamp_mode (handle, swpar, SND_PCM_TSTAMP_MMAP)) < 0)
653
fprintf (stderr, "Alsa_driver: can't set %s timestamp mode to %u.\n", sname, SND_PCM_TSTAMP_MMAP);
657
if ((err = snd_pcm_sw_params_set_avail_min (handle, swpar, _frsize)) < 0)
659
fprintf (stderr, "Alsa_driver: can't set %s availmin to %lu.\n", sname, _frsize);
663
if ((err = snd_pcm_sw_params (handle, swpar)) < 0)
665
fprintf (stderr, "Alsa_driver: can't set %s software parameters.\n", sname);
673
int Alsa_driver::recover (void)
676
snd_pcm_status_t *stat;
678
snd_pcm_status_alloca (&stat);
680
if ((err = snd_pcm_status (_play_handle ? _play_handle : _capt_handle, stat)) < 0)
682
fprintf (stderr, "Alsa_driver: pcm_status(): %s\n", snd_strerror (err));
684
else if (snd_pcm_status_get_state (stat) == SND_PCM_STATE_XRUN)
686
struct timeval tnow, trig;
688
gettimeofday (&tnow, 0);
689
snd_pcm_status_get_trigger_tstamp (stat, &trig);
690
fprintf (stderr, "Alsa_driver: stat = %02x, xrun of at least %8.3lf ms\n", _stat,
691
1e3 * tnow.tv_sec - 1e3 * trig.tv_sec + 1e-3 * tnow.tv_usec - 1e-3 * trig.tv_usec);
694
if (pcm_stop ()) return -1;
696
if (_play_handle && ((err = snd_pcm_prepare (_play_handle)) < 0))
698
fprintf (stderr, "Alsa_driver: pcm_prepare(play): %s\n", snd_strerror (err));
702
if (_capt_handle && !_synced && ((err = snd_pcm_prepare (_capt_handle)) < 0))
704
fprintf (stderr, "Alsa_driver: pcm_prepare(capt): %s\n", snd_strerror (err));
708
if (pcm_start ()) return -1;
714
// Static members ----------------------------------------------------------------------
717
char *Alsa_driver::clear_16le (char *dst, int step, int nfrm)
721
*((short int *) dst) = 0;
727
char *Alsa_driver::play_16le (const float *src, char *dst, int step, int nfrm)
735
if (s > 1) d = 0x7fff;
736
else if (s < -1) d = 0x8001;
737
else d = (short int)(0x7fff * s);
738
*((short int *) dst) = d;
744
const char *Alsa_driver::capt_16le (const char *src, float *dst, int step, int nfrm )
751
s = *((short int *) src);
752
d = (float) s / 0x7fff;
759
char *Alsa_driver::clear_24le (char *dst, int step, int nfrm)
771
char *Alsa_driver::play_24le (const float *src, char *dst, int step, int nfrm)
779
if (s > 1) d = 0x007fffff;
780
else if (s < -1) d = 0x00800001;
781
else d = (int)(0x007fffff * s);
790
const char *Alsa_driver::capt_24le (const char *src, float *dst, int step, int nfrm)
798
s += (src [1] & 0xFF) << 8;
799
s += (src [2] & 0xFF) << 16;
800
if (s & 0x00800000) s-= 0x01000000;
801
d = (float) s / 0x007fffff;
809
char *Alsa_driver::clear_32le (char *dst, int step, int nfrm)
819
char *Alsa_driver::play_32le (const float *src, char *dst, int step, int nfrm)
827
if (s > 1) d = 0x007fffff;
828
else if (s < -1) d = 0x00800001;
829
else d = (int)(0x007fffff * s);
830
*((int *) dst) = d << 8;
836
const char *Alsa_driver::capt_32le (const char *src, float *dst, int step, int nfrm)
844
d = (float) s / 0x7fffff00;