2 * \file pcm/pcm_adpcm.c
4 * \brief PCM Ima-ADPCM Conversion Plugin Interface
5 * \author Abramo Bagnara <abramo@alsa-project.org>
6 * \author Uros Bizjak <uros@kss-loka.si>
7 * \author Jaroslav Kysela <perex@suse.cz>
11 * PCM - Ima-ADPCM conversion
12 * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
13 * Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
14 * Jaroslav Kysela <perex@suse.cz>
16 * Based on Version 1.2, 18-Dec-92 implementation of Intel/DVI ADPCM code
17 * by Jack Jansen, CWI, Amsterdam <Jack.Jansen@cwi.nl>, Copyright 1992
18 * by Stichting Mathematisch Centrum, Amsterdam, The Netherlands.
20 * This library is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU Lesser General Public License as
22 * published by the Free Software Foundation; either version 2.1 of
23 * the License, or (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU Lesser General Public License for more details.
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 These routines convert 16 bit linear PCM samples to 4 bit ADPCM code
38 and vice versa. The ADPCM code used is the Intel/DVI ADPCM code which
39 is being recommended by the IMA Digital Audio Technical Working Group.
41 The algorithm for this coder was taken from:
42 Proposal for Standardized Audio Interstreamge Formats,
43 IMA compatibility project proceedings, Vol 2, Issue 2, May 1992.
45 - No, this is *not* a G.721 coder/decoder. The algorithm used by G.721
46 is very complicated, requiring oodles of floating-point ops per
47 sample (resulting in very poor performance). I have not done any
48 tests myself but various people have assured my that 721 quality is
49 actually lower than DVI quality.
51 - No, it probably isn't a RIFF ADPCM decoder either. Trying to decode
52 RIFF ADPCM with these routines seems to result in something
53 recognizable but very distorted.
55 - No, it is not a CDROM-XA coder either, as far as I know. I haven't
56 come across a good description of XA yet.
60 #include "pcm_local.h"
61 #include "pcm_plugin.h"
63 #include "plugin_ops.h"
66 /* entry for static linking */
67 const char *_snd_module_pcm_adpcm = "";
72 typedef void (*adpcm_f)(const snd_pcm_channel_area_t *dst_areas,
73 snd_pcm_uframes_t dst_offset,
74 const snd_pcm_channel_area_t *src_areas,
75 snd_pcm_uframes_t src_offset,
76 unsigned int channels, snd_pcm_uframes_t frames,
77 unsigned int getputidx,
78 snd_pcm_adpcm_state_t *states);
81 /* This field need to be the first */
82 snd_pcm_plugin_t plug;
83 unsigned int getput_idx;
85 snd_pcm_format_t sformat;
86 snd_pcm_adpcm_state_t *states;
91 /* First table lookup for Ima-ADPCM quantizer */
92 static char IndexAdjust[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
94 /* Second table lookup for Ima-ADPCM quantizer */
95 static short StepSize[89] = {
96 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
97 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
98 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
99 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
100 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
101 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
102 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
103 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
104 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
107 static char adpcm_encoder(int sl, snd_pcm_adpcm_state_t * state)
109 short diff; /* Difference between sl and predicted sample */
110 short pred_diff; /* Predicted difference to next sample */
112 unsigned char sign; /* sign of diff */
113 short step; /* holds previous StepSize value */
114 unsigned char adjust_idx; /* Index to IndexAdjust lookup table */
118 /* Compute difference to previous predicted value */
119 diff = sl - state->pred_val;
120 sign = (diff < 0) ? 0x8 : 0x0;
126 * This code *approximately* computes:
127 * adjust_idx = diff * 4 / step;
128 * pred_diff = (adjust_idx + 0.5) * step / 4;
130 * But in shift step bits are dropped. The net result of this is
131 * that even if you have fast mul/div hardware you cannot put it to
132 * good use since the fix-up would be too expensive.
135 step = StepSize[state->step_idx];
137 /* Divide and clamp */
138 pred_diff = step >> 3;
139 for (adjust_idx = 0, i = 0x4; i; i >>= 1, step >>= 1) {
147 /* Update and clamp previous predicted value */
148 state->pred_val += sign ? -pred_diff : pred_diff;
150 if (state->pred_val > 32767) {
151 state->pred_val = 32767;
152 } else if (state->pred_val < -32768) {
153 state->pred_val = -32768;
156 /* Update and clamp StepSize lookup table index */
157 state->step_idx += IndexAdjust[adjust_idx];
159 if (state->step_idx < 0) {
161 } else if (state->step_idx > 88) {
162 state->step_idx = 88;
164 return (sign | adjust_idx);
168 static int adpcm_decoder(unsigned char code, snd_pcm_adpcm_state_t * state)
170 short pred_diff; /* Predicted difference to next sample */
171 short step; /* holds previous StepSize value */
176 /* Separate sign and magnitude */
181 * Computes pred_diff = (code + 0.5) * step / 4,
182 * but see comment in adpcm_coder.
185 step = StepSize[state->step_idx];
187 /* Compute difference and new predicted value */
188 pred_diff = step >> 3;
189 for (i = 0x4; i; i >>= 1, step >>= 1) {
194 state->pred_val += (sign) ? -pred_diff : pred_diff;
196 /* Clamp output value */
197 if (state->pred_val > 32767) {
198 state->pred_val = 32767;
199 } else if (state->pred_val < -32768) {
200 state->pred_val = -32768;
203 /* Find new StepSize index value */
204 state->step_idx += IndexAdjust[code];
206 if (state->step_idx < 0) {
208 } else if (state->step_idx > 88) {
209 state->step_idx = 88;
211 return (state->pred_val);
216 void snd_pcm_adpcm_decode(const snd_pcm_channel_area_t *dst_areas,
217 snd_pcm_uframes_t dst_offset,
218 const snd_pcm_channel_area_t *src_areas,
219 snd_pcm_uframes_t src_offset,
220 unsigned int channels, snd_pcm_uframes_t frames,
222 snd_pcm_adpcm_state_t *states)
225 #include "plugin_ops.h"
227 void *put = put16_labels[putidx];
228 unsigned int channel;
229 for (channel = 0; channel < channels; ++channel, ++states) {
233 int src_step, srcbit_step, dst_step;
234 snd_pcm_uframes_t frames1;
235 const snd_pcm_channel_area_t *src_area = &src_areas[channel];
236 const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
237 srcbit = src_area->first + src_area->step * src_offset;
238 src = (const char *) src_area->addr + srcbit / 8;
240 src_step = src_area->step / 8;
241 srcbit_step = src_area->step % 8;
242 dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
243 dst_step = snd_pcm_channel_area_step(dst_area);
245 while (frames1-- > 0) {
251 v = (*src >> 4) & 0x0f;
252 sample = adpcm_decoder(v, states);
254 #define PUT16_END after
255 #include "plugin_ops.h"
259 srcbit += srcbit_step;
269 void snd_pcm_adpcm_encode(const snd_pcm_channel_area_t *dst_areas,
270 snd_pcm_uframes_t dst_offset,
271 const snd_pcm_channel_area_t *src_areas,
272 snd_pcm_uframes_t src_offset,
273 unsigned int channels, snd_pcm_uframes_t frames,
275 snd_pcm_adpcm_state_t *states)
278 #include "plugin_ops.h"
280 void *get = get16_labels[getidx];
281 unsigned int channel;
283 for (channel = 0; channel < channels; ++channel, ++states) {
287 int src_step, dst_step, dstbit_step;
288 snd_pcm_uframes_t frames1;
289 const snd_pcm_channel_area_t *src_area = &src_areas[channel];
290 const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
291 src = snd_pcm_channel_area_addr(src_area, src_offset);
292 src_step = snd_pcm_channel_area_step(src_area);
293 dstbit = dst_area->first + dst_area->step * dst_offset;
294 dst = (char *) dst_area->addr + dstbit / 8;
296 dst_step = dst_area->step / 8;
297 dstbit_step = dst_area->step % 8;
299 while (frames1-- > 0) {
302 #define GET16_END after
303 #include "plugin_ops.h"
306 v = adpcm_encoder(sample, states);
308 *dst = (*dst & 0xf0) | v;
310 *dst = (*dst & 0x0f) | (v << 4);
313 dstbit += dstbit_step;
324 static int snd_pcm_adpcm_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
326 snd_pcm_adpcm_t *adpcm = pcm->private_data;
328 snd_pcm_access_mask_t access_mask = { SND_PCM_ACCBIT_SHM };
329 err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_ACCESS,
333 if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
334 snd_pcm_format_mask_t format_mask = { SND_PCM_FMTBIT_LINEAR };
335 err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_FORMAT,
338 err = _snd_pcm_hw_params_set_format(params,
339 SND_PCM_FORMAT_IMA_ADPCM);
343 err = _snd_pcm_hw_params_set_subformat(params,
344 SND_PCM_SUBFORMAT_STD);
347 params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
351 static int snd_pcm_adpcm_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *sparams)
353 snd_pcm_adpcm_t *adpcm = pcm->private_data;
354 snd_pcm_access_mask_t saccess_mask = { SND_PCM_ACCBIT_MMAP };
355 _snd_pcm_hw_params_any(sparams);
356 _snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
358 _snd_pcm_hw_params_set_format(sparams, adpcm->sformat);
359 _snd_pcm_hw_params_set_subformat(sparams, SND_PCM_SUBFORMAT_STD);
363 static int snd_pcm_adpcm_hw_refine_schange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params,
364 snd_pcm_hw_params_t *sparams)
367 unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
368 SND_PCM_HW_PARBIT_RATE |
369 SND_PCM_HW_PARBIT_PERIOD_SIZE |
370 SND_PCM_HW_PARBIT_BUFFER_SIZE |
371 SND_PCM_HW_PARBIT_PERIODS |
372 SND_PCM_HW_PARBIT_PERIOD_TIME |
373 SND_PCM_HW_PARBIT_BUFFER_TIME |
374 SND_PCM_HW_PARBIT_TICK_TIME);
375 err = _snd_pcm_hw_params_refine(sparams, links, params);
381 static int snd_pcm_adpcm_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params,
382 snd_pcm_hw_params_t *sparams)
385 unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
386 SND_PCM_HW_PARBIT_RATE |
387 SND_PCM_HW_PARBIT_PERIOD_SIZE |
388 SND_PCM_HW_PARBIT_BUFFER_SIZE |
389 SND_PCM_HW_PARBIT_PERIODS |
390 SND_PCM_HW_PARBIT_PERIOD_TIME |
391 SND_PCM_HW_PARBIT_BUFFER_TIME |
392 SND_PCM_HW_PARBIT_TICK_TIME);
393 err = _snd_pcm_hw_params_refine(params, links, sparams);
399 static int snd_pcm_adpcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
401 return snd_pcm_hw_refine_slave(pcm, params,
402 snd_pcm_adpcm_hw_refine_cprepare,
403 snd_pcm_adpcm_hw_refine_cchange,
404 snd_pcm_adpcm_hw_refine_sprepare,
405 snd_pcm_adpcm_hw_refine_schange,
406 snd_pcm_generic_hw_refine);
409 static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
411 snd_pcm_adpcm_t *adpcm = pcm->private_data;
412 snd_pcm_format_t format;
413 int err = snd_pcm_hw_params_slave(pcm, params,
414 snd_pcm_adpcm_hw_refine_cchange,
415 snd_pcm_adpcm_hw_refine_sprepare,
416 snd_pcm_adpcm_hw_refine_schange,
417 snd_pcm_generic_hw_params);
421 err = INTERNAL(snd_pcm_hw_params_get_format)(params, &format);
425 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
426 if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
427 adpcm->getput_idx = snd_pcm_linear_get_index(format, SND_PCM_FORMAT_S16);
428 adpcm->func = snd_pcm_adpcm_encode;
430 adpcm->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, adpcm->sformat);
431 adpcm->func = snd_pcm_adpcm_decode;
434 if (adpcm->sformat == SND_PCM_FORMAT_IMA_ADPCM) {
435 adpcm->getput_idx = snd_pcm_linear_put_index(SND_PCM_FORMAT_S16, format);
436 adpcm->func = snd_pcm_adpcm_decode;
438 adpcm->getput_idx = snd_pcm_linear_get_index(adpcm->sformat, SND_PCM_FORMAT_S16);
439 adpcm->func = snd_pcm_adpcm_encode;
442 assert(!adpcm->states);
443 adpcm->states = malloc(adpcm->plug.gen.slave->channels * sizeof(*adpcm->states));
444 if (adpcm->states == NULL)
449 static int snd_pcm_adpcm_hw_free(snd_pcm_t *pcm)
451 snd_pcm_adpcm_t *adpcm = pcm->private_data;
456 return snd_pcm_hw_free(adpcm->plug.gen.slave);
459 static int snd_pcm_adpcm_init(snd_pcm_t *pcm)
461 snd_pcm_adpcm_t *adpcm = pcm->private_data;
463 for (k = 0; k < pcm->channels; ++k) {
464 adpcm->states[k].pred_val = 0;
465 adpcm->states[k].step_idx = 0;
470 static snd_pcm_uframes_t
471 snd_pcm_adpcm_write_areas(snd_pcm_t *pcm,
472 const snd_pcm_channel_area_t *areas,
473 snd_pcm_uframes_t offset,
474 snd_pcm_uframes_t size,
475 const snd_pcm_channel_area_t *slave_areas,
476 snd_pcm_uframes_t slave_offset,
477 snd_pcm_uframes_t *slave_sizep)
479 snd_pcm_adpcm_t *adpcm = pcm->private_data;
480 if (size > *slave_sizep)
482 adpcm->func(slave_areas, slave_offset,
485 adpcm->getput_idx, adpcm->states);
490 static snd_pcm_uframes_t
491 snd_pcm_adpcm_read_areas(snd_pcm_t *pcm,
492 const snd_pcm_channel_area_t *areas,
493 snd_pcm_uframes_t offset,
494 snd_pcm_uframes_t size,
495 const snd_pcm_channel_area_t *slave_areas,
496 snd_pcm_uframes_t slave_offset,
497 snd_pcm_uframes_t *slave_sizep)
499 snd_pcm_adpcm_t *adpcm = pcm->private_data;
500 if (size > *slave_sizep)
502 adpcm->func(areas, offset,
503 slave_areas, slave_offset,
505 adpcm->getput_idx, adpcm->states);
510 static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out)
512 snd_pcm_adpcm_t *adpcm = pcm->private_data;
513 snd_output_printf(out, "Ima-ADPCM conversion PCM (%s)\n",
514 snd_pcm_format_name(adpcm->sformat));
516 snd_output_printf(out, "Its setup is:\n");
517 snd_pcm_dump_setup(pcm, out);
519 snd_output_printf(out, "Slave: ");
520 snd_pcm_dump(adpcm->plug.gen.slave, out);
523 static snd_pcm_ops_t snd_pcm_adpcm_ops = {
524 .close = snd_pcm_generic_close,
525 .info = snd_pcm_generic_info,
526 .hw_refine = snd_pcm_adpcm_hw_refine,
527 .hw_params = snd_pcm_adpcm_hw_params,
528 .hw_free = snd_pcm_adpcm_hw_free,
529 .sw_params = snd_pcm_generic_sw_params,
530 .channel_info = snd_pcm_generic_channel_info,
531 .dump = snd_pcm_adpcm_dump,
532 .nonblock = snd_pcm_generic_nonblock,
533 .async = snd_pcm_generic_async,
534 .mmap = snd_pcm_generic_mmap,
535 .munmap = snd_pcm_generic_munmap,
539 * \brief Creates a new Ima-ADPCM conversion PCM
540 * \param pcmp Returns created PCM handle
541 * \param name Name of PCM
542 * \param sformat Slave (destination) format
543 * \param slave Slave PCM handle
544 * \param close_slave When set, the slave PCM handle is closed with copy PCM
545 * \retval zero on success otherwise a negative error code
546 * \warning Using of this function might be dangerous in the sense
547 * of compatibility reasons. The prototype might be freely
550 int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave)
553 snd_pcm_adpcm_t *adpcm;
555 assert(pcmp && slave);
556 if (snd_pcm_format_linear(sformat) != 1 &&
557 sformat != SND_PCM_FORMAT_IMA_ADPCM)
559 adpcm = calloc(1, sizeof(snd_pcm_adpcm_t));
563 adpcm->sformat = sformat;
564 snd_pcm_plugin_init(&adpcm->plug);
565 adpcm->plug.read = snd_pcm_adpcm_read_areas;
566 adpcm->plug.write = snd_pcm_adpcm_write_areas;
567 adpcm->plug.init = snd_pcm_adpcm_init;
568 adpcm->plug.gen.slave = slave;
569 adpcm->plug.gen.close_slave = close_slave;
571 err = snd_pcm_new(&pcm, SND_PCM_TYPE_ADPCM, name, slave->stream, slave->mode);
576 pcm->ops = &snd_pcm_adpcm_ops;
577 pcm->fast_ops = &snd_pcm_plugin_fast_ops;
578 pcm->private_data = adpcm;
579 pcm->poll_fd = slave->poll_fd;
580 pcm->poll_events = slave->poll_events;
581 snd_pcm_set_hw_ptr(pcm, &adpcm->plug.hw_ptr, -1, 0);
582 snd_pcm_set_appl_ptr(pcm, &adpcm->plug.appl_ptr, -1, 0);
588 /*! \page pcm_plugins
590 \section pcm_plugins_adpcm Plugin: Ima-ADPCM
592 This plugin converts Ima-ADPCM samples to linear or linear to Ima-ADPCM samples
593 from master Ima-ADPCM conversion PCM to given slave PCM. The channel count,
594 format and rate must match for both of them.
598 type adpcm # Ima-ADPCM conversion PCM
599 slave STR # Slave name
601 slave { # Slave definition
602 pcm STR # Slave PCM name
604 pcm { } # Slave PCM definition
605 format STR # Slave format
610 \subsection pcm_plugins_adpcm_funcref Function reference
613 <LI>snd_pcm_adpcm_open()
614 <LI>_snd_pcm_adpcm_open()
620 * \brief Creates a new Ima-ADPCM conversion PCM
621 * \param pcmp Returns created PCM handle
622 * \param name Name of PCM
623 * \param root Root configuration node
624 * \param conf Configuration node with copy PCM description
625 * \param stream Stream type
626 * \param mode Stream mode
627 * \retval zero on success otherwise a negative error code
628 * \warning Using of this function might be dangerous in the sense
629 * of compatibility reasons. The prototype might be freely
632 int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
633 snd_config_t *root, snd_config_t *conf,
634 snd_pcm_stream_t stream, int mode)
636 snd_config_iterator_t i, next;
639 snd_config_t *slave = NULL, *sconf;
640 snd_pcm_format_t sformat;
641 snd_config_for_each(i, next, conf) {
642 snd_config_t *n = snd_config_iterator_entry(i);
644 if (snd_config_get_id(n, &id) < 0)
646 if (snd_pcm_conf_generic_id(id))
648 if (strcmp(id, "slave") == 0) {
652 SNDERR("Unknown field %s", id);
656 SNDERR("slave is not defined");
659 err = snd_pcm_slave_conf(root, slave, &sconf, 1,
660 SND_PCM_HW_PARAM_FORMAT, SCONF_MANDATORY, &sformat);
663 if (snd_pcm_format_linear(sformat) != 1 &&
664 sformat != SND_PCM_FORMAT_IMA_ADPCM) {
665 snd_config_delete(sconf);
666 SNDERR("invalid slave format");
669 err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
670 snd_config_delete(sconf);
673 err = snd_pcm_adpcm_open(pcmp, name, sformat, spcm, 1);
679 SND_DLSYM_BUILD_VERSION(_snd_pcm_adpcm_open, SND_PCM_DLSYM_VERSION);