4
* Copyright (c) 2006 by Takashi Iwai <tiwai@suse.de>
6
* This library is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as
8
* published by the Free Software Foundation; either version 2.1 of
9
* the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#include <alsa/asoundlib.h>
26
#include <alsa/pcm_external.h>
27
#include <alsa/pcm_plugin.h>
28
#include AVCODEC_HEADER
29
#include <libavutil/avutil.h>
35
AVCodecContext *avctx;
36
snd_pcm_format_t format;
37
unsigned int channels;
41
unsigned char *outbuf;
43
snd_pcm_uframes_t transfer;
46
unsigned int slave_period_size;
47
unsigned int slave_buffer_size;
48
snd_pcm_hw_params_t *hw_params;
51
/* convert the PCM data to A52 stream in IEC958 */
52
static void convert_data(struct a52_ctx *rec)
56
out_bytes = avcodec_encode_audio(rec->avctx, rec->outbuf + 8,
59
rec->outbuf[0] = 0xf8; /* sync words */
60
rec->outbuf[1] = 0x72;
61
rec->outbuf[2] = 0x4e;
62
rec->outbuf[3] = 0x1f;
63
rec->outbuf[4] = rec->outbuf[13] & 7; /* bsmod */
64
rec->outbuf[5] = 0x01; /* data type */
65
rec->outbuf[6] = ((out_bytes * 8) >> 8) & 0xff;
66
rec->outbuf[7] = (out_bytes * 8) & 0xff;
67
/* swap bytes for little-endian 16bit */
68
if (rec->format == SND_PCM_FORMAT_S16_LE)
69
swab(rec->outbuf, rec->outbuf, out_bytes + 8);
70
memset(rec->outbuf + 8 + out_bytes, 0,
71
rec->outbuf_size - 8 - out_bytes);
72
rec->remain = rec->outbuf_size / 4;
76
/* write pending encoded data to the slave pcm */
77
static int write_out_pending(snd_pcm_ioplug_t *io, struct a52_ctx *rec)
85
err = snd_pcm_writei(rec->slave, rec->outbuf + ofs, rec->remain);
88
io->state = SND_PCM_STATE_XRUN;
92
if (err < rec->remain)
93
ofs += (rec->remain - err) * 4;
96
if (rec->remain && ofs)
97
memmove(rec->outbuf, rec->outbuf + ofs, rec->remain * 4);
104
static int a52_drain(snd_pcm_ioplug_t *io)
106
struct a52_ctx *rec = io->private_data;
110
if ((err = write_out_pending(io, rec)) < 0)
112
/* remaining data must be converted and sent out */
113
memset(rec->inbuf + rec->filled * io->channels, 0,
114
(rec->avctx->frame_size - rec->filled) * io->channels * 2);
117
err = write_out_pending(io, rec);
120
snd_pcm_drain(rec->slave);
124
/* check whether the areas consist of a continuous interleaved stream */
125
static int check_interleaved(const snd_pcm_channel_area_t *areas,
126
unsigned int channels)
130
if (channels > 4) /* we need re-routing for 6 channels */
133
for (ch = 0; ch < channels; ch++) {
134
if (areas[ch].addr != areas[0].addr ||
135
areas[ch].first != ch * 16 ||
136
areas[ch].step != channels * 16)
142
/* Fill the input PCM to the internal buffer until a52 frames,
143
* then covert and write it out.
145
* Returns the number of processed frames.
147
static int fill_data(snd_pcm_ioplug_t *io,
148
const snd_pcm_channel_area_t *areas,
149
unsigned int offset, unsigned int size,
152
struct a52_ctx *rec = io->private_data;
153
unsigned int len = rec->avctx->frame_size - rec->filled;
155
unsigned int src_step;
158
if ((err = write_out_pending(io, rec)) < 0)
164
dst = rec->inbuf + rec->filled * io->channels;
166
memcpy(dst, areas->addr + offset * io->channels * 2,
167
size * io->channels * 2);
169
unsigned int i, ch, dst_step;
171
static unsigned int ch_index[3][6] = {
174
#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 26)
175
/* current libavcodec expects SMPTE order */
176
{ 0, 1, 4, 5, 2, 3 },
178
/* libavcodec older than r18540 expects A52 order */
179
{ 0, 4, 1, 2, 3, 5 },
182
/* flatten copy to n-channel interleaved */
183
dst_step = io->channels;
184
for (ch = 0; ch < io->channels; ch++, dst++) {
185
const snd_pcm_channel_area_t *ap;
186
ap = &areas[ch_index[io->channels / 2 - 1][ch]];
188
src = (short *)(ap->addr +
189
(ap->first + offset * ap->step) / 8);
190
src_step = ap->step / 16; /* in word */
191
for (i = 0; i < size; i++) {
199
if (rec->filled == rec->avctx->frame_size) {
201
write_out_pending(io, rec);
209
static snd_pcm_sframes_t a52_transfer(snd_pcm_ioplug_t *io,
210
const snd_pcm_channel_area_t *areas,
211
snd_pcm_uframes_t offset,
212
snd_pcm_uframes_t size)
214
struct a52_ctx *rec = io->private_data;
215
snd_pcm_sframes_t result = 0;
217
int interleaved = check_interleaved(areas, io->channels);
220
err = fill_data(io, areas, offset, size, interleaved);
223
offset += (unsigned int)err;
224
size -= (unsigned int)err;
226
rec->transfer += err;
228
return result > 0 ? result : err;
234
* Calculate the current position from the delay of slave PCM
236
static snd_pcm_sframes_t a52_pointer(snd_pcm_ioplug_t *io)
238
struct a52_ctx *rec = io->private_data;
239
snd_pcm_sframes_t delay;
240
snd_pcm_state_t state;
243
state = snd_pcm_state(rec->slave);
245
case SND_PCM_STATE_RUNNING:
246
case SND_PCM_STATE_DRAINING:
247
if ((err = snd_pcm_delay(rec->slave, &delay)) < 0)
250
case SND_PCM_STATE_XRUN:
251
case SND_PCM_STATE_SUSPENDED:
257
if (delay < 0 || delay >= (snd_pcm_sframes_t)rec->slave_buffer_size)
259
delay = (snd_pcm_sframes_t)io->appl_ptr - delay;
261
delay += io->buffer_size;
265
delay %= io->buffer_size;
269
/* set up the fixed parameters of slave PCM hw_parmas */
270
static int a52_slave_hw_params_half(struct a52_ctx *rec)
274
if ((err = snd_pcm_hw_params_malloc(&rec->hw_params)) < 0)
277
if ((err = snd_pcm_hw_params_any(rec->slave, rec->hw_params)) < 0) {
278
SNDERR("Cannot get slave hw_params");
281
if ((err = snd_pcm_hw_params_set_access(rec->slave, rec->hw_params,
282
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
283
SNDERR("Cannot set slave access RW_INTERLEAVED");
286
if ((err = snd_pcm_hw_params_set_channels(rec->slave, rec->hw_params, 2)) < 0) {
287
SNDERR("Cannot set slave channels 2");
290
if ((err = snd_pcm_hw_params_set_format(rec->slave, rec->hw_params,
292
SNDERR("Cannot set slave format");
295
if ((err = snd_pcm_hw_params_set_rate(rec->slave, rec->hw_params, rec->rate, 0)) < 0) {
296
SNDERR("Cannot set slave rate %d", rec->rate);
302
free(rec->hw_params);
303
rec->hw_params = NULL;
310
* Set up slave PCM according to the current parameters
312
static int a52_hw_params(snd_pcm_ioplug_t *io,
313
snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED)
315
struct a52_ctx *rec = io->private_data;
316
snd_pcm_uframes_t period_size;
317
snd_pcm_uframes_t buffer_size;
320
if (! rec->hw_params) {
321
err = a52_slave_hw_params_half(rec);
325
period_size = io->period_size;
326
if ((err = snd_pcm_hw_params_set_period_size_near(rec->slave, rec->hw_params,
327
&period_size, NULL)) < 0) {
328
SNDERR("Cannot set slave period size %ld", period_size);
331
buffer_size = io->buffer_size;
332
if ((err = snd_pcm_hw_params_set_buffer_size_near(rec->slave, rec->hw_params,
333
&buffer_size)) < 0) {
334
SNDERR("Cannot set slave buffer size %ld", buffer_size);
337
if ((err = snd_pcm_hw_params(rec->slave, rec->hw_params)) < 0) {
338
SNDERR("Cannot set slave hw_params");
341
rec->slave_period_size = period_size;
342
rec->slave_buffer_size = buffer_size;
350
static int a52_hw_free(snd_pcm_ioplug_t *io)
352
struct a52_ctx *rec = io->private_data;
354
free(rec->hw_params);
355
rec->hw_params = NULL;
356
return snd_pcm_hw_free(rec->slave);
362
* Set up slave PCM sw_params
364
static int a52_sw_params(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params)
366
struct a52_ctx *rec = io->private_data;
367
snd_pcm_sw_params_t *sparams;
368
snd_pcm_uframes_t avail_min, start_threshold;
371
snd_pcm_sw_params_get_avail_min(params, &avail_min);
372
snd_pcm_sw_params_get_start_threshold(params, &start_threshold);
375
len += (int)rec->slave_buffer_size - (int)io->buffer_size;
380
snd_pcm_sw_params_alloca(&sparams);
381
snd_pcm_sw_params_current(rec->slave, sparams);
382
snd_pcm_sw_params_set_avail_min(rec->slave, sparams, avail_min);
383
snd_pcm_sw_params_set_start_threshold(rec->slave, sparams,
386
return snd_pcm_sw_params(rec->slave, sparams);
390
* start and stop callbacks - just trigger slave PCM
392
static int a52_start(snd_pcm_ioplug_t *io)
394
struct a52_ctx *rec = io->private_data;
396
snd_pcm_start(rec->slave);
400
static int a52_stop(snd_pcm_ioplug_t *io)
402
struct a52_ctx *rec = io->private_data;
404
snd_pcm_drop(rec->slave);
408
/* release resources */
409
static void a52_free(struct a52_ctx *rec)
412
avcodec_close(rec->avctx);
425
* Allocate internal buffers and set up libavcodec
427
static int a52_prepare(snd_pcm_ioplug_t *io)
429
struct a52_ctx *rec = io->private_data;
433
rec->avctx = avcodec_alloc_context();
437
rec->avctx->bit_rate = rec->bitrate * 1000;
438
rec->avctx->sample_rate = io->rate;
439
rec->avctx->channels = io->channels;
440
#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 95)
441
rec->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
443
rec->avctx->sample_fmt = SAMPLE_FMT_S16;
445
#if LIBAVCODEC_VERSION_MAJOR > 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR >= 3)
446
switch (io->channels) {
448
rec->avctx->channel_layout = CH_LAYOUT_STEREO;
451
rec->avctx->channel_layout = CH_LAYOUT_QUAD;
454
rec->avctx->channel_layout = CH_LAYOUT_5POINT1;
461
if (avcodec_open(rec->avctx, rec->codec) < 0)
464
rec->inbuf = malloc(rec->avctx->frame_size * 2 * io->channels);
467
rec->outbuf_size = rec->avctx->frame_size * 4;
468
rec->outbuf = malloc(rec->outbuf_size);
476
return snd_pcm_prepare(rec->slave);
480
* poll-related callbacks - just pass to slave PCM
482
static int a52_poll_descriptors_count(snd_pcm_ioplug_t *io)
484
struct a52_ctx *rec = io->private_data;
485
return snd_pcm_poll_descriptors_count(rec->slave);
488
static int a52_poll_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfd,
491
struct a52_ctx *rec = io->private_data;
492
return snd_pcm_poll_descriptors(rec->slave, pfd, space);
495
static int a52_poll_revents(snd_pcm_ioplug_t *io, struct pollfd *pfd,
496
unsigned int nfds, unsigned short *revents)
498
struct a52_ctx *rec = io->private_data;
499
return snd_pcm_poll_descriptors_revents(rec->slave, pfd, nfds, revents);
505
static int a52_close(snd_pcm_ioplug_t *io)
507
struct a52_ctx *rec = io->private_data;
511
snd_pcm_close(rec->slave);
518
static snd_pcm_ioplug_callback_t a52_ops = {
521
.pointer = a52_pointer,
522
.transfer = a52_transfer,
524
.hw_params = a52_hw_params,
525
.hw_free = a52_hw_free,
526
.sw_params = a52_sw_params,
527
.prepare = a52_prepare,
529
.poll_descriptors_count = a52_poll_descriptors_count,
530
.poll_descriptors = a52_poll_descriptors,
531
.poll_revents = a52_poll_revents,
535
* set up h/w constraints
537
* set the period size identical with A52 frame size.
538
* the max buffer size is calculated from the max buffer size
542
#define A52_FRAME_SIZE 1536
544
#define ARRAY_SIZE(ary) (sizeof(ary)/sizeof(ary[0]))
546
static int a52_set_hw_constraint(struct a52_ctx *rec)
548
unsigned int accesses[] = {
549
SND_PCM_ACCESS_MMAP_INTERLEAVED,
550
SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
551
SND_PCM_ACCESS_RW_INTERLEAVED,
552
SND_PCM_ACCESS_RW_NONINTERLEAVED
554
unsigned int formats[] = { SND_PCM_FORMAT_S16 };
556
snd_pcm_uframes_t buffer_max;
557
unsigned int period_bytes, max_periods;
559
if ((err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_ACCESS,
560
ARRAY_SIZE(accesses), accesses)) < 0 ||
561
(err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_FORMAT,
562
ARRAY_SIZE(formats), formats)) < 0 ||
563
(err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_CHANNELS,
564
rec->channels, rec->channels)) < 0 ||
565
(err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_RATE,
566
rec->rate, rec->rate)) < 0)
569
if ((err = a52_slave_hw_params_half(rec)) < 0)
572
snd_pcm_hw_params_get_buffer_size_max(rec->hw_params, &buffer_max);
573
period_bytes = A52_FRAME_SIZE * 2 * rec->channels;
574
max_periods = buffer_max / A52_FRAME_SIZE;
576
if ((err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES,
577
period_bytes, period_bytes)) < 0 ||
578
(err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_PERIODS,
579
2, max_periods)) < 0)
588
SND_PCM_PLUGIN_DEFINE_FUNC(a52)
590
snd_config_iterator_t i, next;
592
const char *card = NULL;
593
const char *pcm_string = NULL;
594
unsigned int rate = 48000;
595
unsigned int bitrate = 448;
596
unsigned int channels = 6;
597
snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
598
char devstr[128], tmpcard[8];
601
if (stream != SND_PCM_STREAM_PLAYBACK) {
602
SNDERR("a52 is only for playback");
606
snd_config_for_each(i, next, conf) {
607
snd_config_t *n = snd_config_iterator_entry(i);
609
if (snd_config_get_id(n, &id) < 0)
611
if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0 || strcmp(id, "hint") == 0)
613
if (strcmp(id, "card") == 0) {
614
if (snd_config_get_string(n, &card) < 0) {
616
err = snd_config_get_integer(n, &val);
618
SNDERR("Invalid type for %s", id);
621
snprintf(tmpcard, sizeof(tmpcard), "%ld", val);
626
if (strcmp(id, "slavepcm") == 0) {
627
if (snd_config_get_string(n, &pcm_string) < 0) {
628
SNDERR("a52 slavepcm must be a string");
633
if (strcmp(id, "rate") == 0) {
635
if (snd_config_get_integer(n, &val) < 0) {
636
SNDERR("Invalid type for %s", id);
640
if (rate != 44100 && rate != 48000) {
641
SNDERR("rate must be 44100 or 48000");
646
if (strcmp(id, "bitrate") == 0) {
648
if (snd_config_get_integer(n, &val) < 0) {
649
SNDERR("Invalid type for %s", id);
653
if (bitrate < 128 || bitrate > 1000) {
654
SNDERR("Invalid bitrate value %d", bitrate);
659
if (strcmp(id, "channels") == 0) {
661
if (snd_config_get_integer(n, &val) < 0) {
662
SNDERR("Invalid type for %s", id);
666
if (channels != 2 && channels != 4 && channels != 6) {
667
SNDERR("channels must be 2, 4 or 6");
672
if (strcmp(id, "format") == 0) {
674
err = snd_config_get_string(n, &str);
676
SNDERR("invalid type for %s", id);
679
format = snd_pcm_format_value(str);
680
if (format == SND_PCM_FORMAT_UNKNOWN) {
681
SNDERR("unknown format %s", str);
684
if (format != SND_PCM_FORMAT_S16_LE &&
685
format != SND_PCM_FORMAT_S16_BE) {
686
SNDERR("Only S16_LE/BE formats are allowed");
691
SNDERR("Unknown field %s", id);
695
rec = calloc(1, sizeof(*rec));
697
SNDERR("cannot allocate");
702
rec->bitrate = bitrate;
703
rec->channels = channels;
704
rec->format = format;
707
avcodec_register_all();
709
rec->codec = avcodec_find_encoder_by_name("ac3_fixed");
710
if (rec->codec == NULL)
711
rec->codec = avcodec_find_encoder_by_name("ac3");
712
if (rec->codec == NULL)
713
rec->codec = avcodec_find_encoder(CODEC_ID_AC3);
714
if (rec->codec == NULL) {
715
SNDERR("Cannot find codec engine");
721
snprintf(devstr, sizeof(devstr),
722
"iec958:{AES0 0x%x AES1 0x%x AES2 0x%x AES3 0x%x %s%s}",
723
IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO |
724
IEC958_AES0_CON_NOT_COPYRIGHT,
725
IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
726
0, rate == 48000 ? IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100,
727
card ? " CARD " : "",
729
err = snd_pcm_open(&rec->slave, devstr, stream, mode);
732
/* in case the slave doesn't support S16 format */
733
err = snd_pcm_linear_open(&rec->slave, NULL, SND_PCM_FORMAT_S16,
738
err = snd_pcm_open(&rec->slave, pcm_string, stream, mode);
743
rec->io.version = SND_PCM_IOPLUG_VERSION;
744
rec->io.name = "A52 Output Plugin";
746
rec->io.callback = &a52_ops;
747
rec->io.private_data = rec;
749
err = snd_pcm_ioplug_create(&rec->io, name, stream, mode);
753
if ((err = a52_set_hw_constraint(rec)) < 0) {
754
snd_pcm_ioplug_delete(&rec->io);
763
snd_pcm_close(rec->slave);
768
SND_PCM_PLUGIN_SYMBOL(a52);