Home | History | Annotate | Line # | Download | only in ic
msm6258.c revision 1.10.10.4
      1  1.10.10.4    skrll /*	$NetBSD: msm6258.c,v 1.10.10.4 2005/01/17 19:30:40 skrll Exp $	*/
      2        1.1  minoura 
      3        1.1  minoura /*
      4        1.1  minoura  * Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
      5        1.1  minoura  *
      6        1.1  minoura  * Redistribution and use in source and binary forms, with or without
      7        1.1  minoura  * modification, are permitted provided that the following conditions
      8        1.1  minoura  * are met:
      9        1.1  minoura  * 1. Redistributions of source code must retain the above copyright
     10        1.1  minoura  *    notice, this list of conditions and the following disclaimer.
     11        1.1  minoura  * 2. Redistributions in binary form must reproduce the above copyright
     12        1.1  minoura  *    notice, this list of conditions and the following disclaimer in the
     13        1.1  minoura  *    documentation and/or other materials provided with the distribution.
     14  1.10.10.1    skrll  * 3. The name of the author may not be used to endorse or promote products
     15        1.1  minoura  *    derived from this software without specific prior written permission
     16        1.1  minoura  *
     17        1.1  minoura  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18        1.1  minoura  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19        1.1  minoura  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20        1.1  minoura  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21        1.1  minoura  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     22        1.1  minoura  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23        1.1  minoura  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     24        1.1  minoura  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     25        1.1  minoura  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26        1.1  minoura  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27        1.1  minoura  * SUCH DAMAGE.
     28        1.1  minoura  */
     29        1.1  minoura 
     30        1.1  minoura /*
     31        1.1  minoura  * OKI MSM6258 ADPCM voice synthesizer codec.
     32        1.1  minoura  */
     33        1.5    lukem 
     34        1.5    lukem #include <sys/cdefs.h>
     35  1.10.10.4    skrll __KERNEL_RCSID(0, "$NetBSD: msm6258.c,v 1.10.10.4 2005/01/17 19:30:40 skrll Exp $");
     36        1.1  minoura 
     37        1.1  minoura #include <sys/systm.h>
     38        1.1  minoura #include <sys/device.h>
     39        1.1  minoura #include <sys/malloc.h>
     40        1.1  minoura #include <sys/select.h>
     41        1.1  minoura #include <sys/audioio.h>
     42        1.1  minoura 
     43        1.1  minoura #include <dev/audio_if.h>
     44        1.6    isaki #include <dev/auconv.h>
     45        1.1  minoura #include <dev/audiovar.h>
     46        1.4  minoura #include <dev/mulaw.h>
     47        1.1  minoura #include <dev/ic/msm6258var.h>
     48        1.1  minoura 
     49        1.9    isaki struct msm6258_codecvar {
     50  1.10.10.4    skrll 	stream_filter_t	base;
     51  1.10.10.4    skrll 	short		mc_amp;
     52  1.10.10.4    skrll 	char		mc_estim;
     53        1.9    isaki };
     54        1.9    isaki 
     55  1.10.10.4    skrll static stream_filter_t *msm6258_factory
     56  1.10.10.4    skrll 	(int (*)(stream_fetcher_t *, audio_stream_t *, int));
     57  1.10.10.4    skrll static void msm6258_dtor(struct stream_filter *);
     58  1.10.10.4    skrll static __inline uint8_t	pcm2adpcm_step(struct msm6258_codecvar *, int16_t);
     59  1.10.10.4    skrll static __inline int16_t	adpcm2pcm_step(struct msm6258_codecvar *, uint8_t);
     60        1.1  minoura 
     61  1.10.10.4    skrll static const int adpcm_estimindex[16] = {
     62        1.9    isaki 	 2,  6,  10,  14,  18,  22,  26,  30,
     63        1.9    isaki 	-2, -6, -10, -14, -18, -22, -26, -30
     64        1.1  minoura };
     65        1.1  minoura 
     66  1.10.10.4    skrll static const int adpcm_estim[49] = {
     67        1.1  minoura 	 16,  17,  19,  21,  23,  25,  28,  31,  34,  37,
     68        1.1  minoura 	 41,  45,  50,  55,  60,  66,  73,  80,  88,  97,
     69        1.1  minoura 	107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
     70        1.1  minoura 	279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
     71       1.10    isaki 	724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
     72        1.1  minoura };
     73        1.1  minoura 
     74  1.10.10.4    skrll static const int adpcm_estimstep[16] = {
     75        1.1  minoura 	-1, -1, -1, -1, 2, 4, 6, 8,
     76        1.1  minoura 	-1, -1, -1, -1, 2, 4, 6, 8
     77        1.1  minoura };
     78        1.1  minoura 
     79  1.10.10.4    skrll static stream_filter_t *
     80  1.10.10.4    skrll msm6258_factory(int (*fetch_to)(stream_fetcher_t *, audio_stream_t *, int))
     81        1.1  minoura {
     82  1.10.10.4    skrll 	struct msm6258_codecvar *this;
     83        1.1  minoura 
     84  1.10.10.4    skrll 	this = malloc(sizeof(*this), M_DEVBUF, M_WAITOK | M_ZERO);
     85  1.10.10.4    skrll 	this->base.base.fetch_to = fetch_to;
     86  1.10.10.4    skrll 	this->base.dtor = msm6258_dtor;
     87  1.10.10.4    skrll 	this->base.set_fetcher = stream_filter_set_fetcher;
     88  1.10.10.4    skrll 	this->base.set_inputbuffer = stream_filter_set_inputbuffer;
     89  1.10.10.4    skrll 	return &this->base;
     90        1.8    isaki }
     91        1.8    isaki 
     92  1.10.10.4    skrll static void
     93  1.10.10.4    skrll msm6258_dtor(struct stream_filter *this)
     94        1.8    isaki {
     95  1.10.10.4    skrll 	if (this != NULL)
     96  1.10.10.4    skrll 		free(this, M_DEVBUF);
     97        1.1  minoura }
     98        1.1  minoura 
     99        1.9    isaki /*
    100        1.9    isaki  * signed 16bit linear PCM -> OkiADPCM
    101        1.9    isaki  */
    102  1.10.10.4    skrll static __inline uint8_t
    103  1.10.10.4    skrll pcm2adpcm_step(struct msm6258_codecvar *mc, int16_t a)
    104        1.9    isaki {
    105        1.9    isaki 	int estim = (int)mc->mc_estim;
    106        1.9    isaki 	int df;
    107        1.9    isaki 	short dl, c;
    108  1.10.10.4    skrll 	uint8_t b;
    109  1.10.10.4    skrll 	uint8_t s;
    110        1.9    isaki 
    111        1.9    isaki 	df = a - mc->mc_amp;
    112        1.9    isaki 	dl = adpcm_estim[estim];
    113        1.9    isaki 	c = (df / 16) * 8 / dl;
    114        1.9    isaki 	if (df < 0) {
    115        1.9    isaki 		b = (unsigned char)(-c) / 2;
    116        1.9    isaki 		s = 0x08;
    117        1.9    isaki 	} else {
    118        1.9    isaki 		b = (unsigned char)(c) / 2;
    119        1.9    isaki 		s = 0;
    120        1.9    isaki 	}
    121        1.9    isaki 	if (b > 7)
    122        1.9    isaki 		b = 7;
    123        1.9    isaki 	s |= b;
    124        1.9    isaki 	mc->mc_amp += (short)(adpcm_estimindex[(int)s] * dl);
    125        1.9    isaki 	estim += adpcm_estimstep[b];
    126        1.9    isaki 	if (estim < 0)
    127        1.9    isaki 		estim = 0;
    128        1.9    isaki 	else if (estim > 48)
    129        1.9    isaki 		estim = 48;
    130        1.9    isaki 
    131        1.9    isaki 	mc->mc_estim = estim;
    132        1.9    isaki 	return s;
    133        1.9    isaki }
    134        1.9    isaki 
    135  1.10.10.4    skrll #define DEFINE_FILTER(name)	\
    136  1.10.10.4    skrll static int \
    137  1.10.10.4    skrll name##_fetch_to(stream_fetcher_t *, audio_stream_t *, int); \
    138  1.10.10.4    skrll stream_filter_t * \
    139  1.10.10.4    skrll name(struct audio_softc *sc, const audio_params_t *from, \
    140  1.10.10.4    skrll      const audio_params_t *to) \
    141  1.10.10.4    skrll { \
    142  1.10.10.4    skrll 	return msm6258_factory(name##_fetch_to); \
    143  1.10.10.4    skrll } \
    144  1.10.10.4    skrll static int \
    145  1.10.10.4    skrll name##_fetch_to(stream_fetcher_t *self, audio_stream_t *dst, int max_used)
    146  1.10.10.4    skrll 
    147  1.10.10.4    skrll DEFINE_FILTER(msm6258_slinear16_to_adpcm)
    148  1.10.10.4    skrll {
    149  1.10.10.4    skrll 	stream_filter_t *this;
    150  1.10.10.4    skrll 	struct msm6258_codecvar *mc;
    151  1.10.10.4    skrll 	uint8_t *d;
    152  1.10.10.4    skrll 	const uint8_t *s;
    153  1.10.10.4    skrll 	int m, err, enc_src;
    154  1.10.10.4    skrll 
    155  1.10.10.4    skrll 	this = (stream_filter_t *)self;
    156  1.10.10.4    skrll 	mc = (struct msm6258_codecvar *)self;
    157  1.10.10.4    skrll 	if ((err = this->prev->fetch_to(this->prev, this->src, max_used * 4)))
    158  1.10.10.4    skrll 		return err;
    159  1.10.10.4    skrll 	m = dst->end - dst->start;
    160  1.10.10.4    skrll 	m = min(m, max_used);
    161  1.10.10.4    skrll 	d = dst->inp;
    162  1.10.10.4    skrll 	s = this->src->outp;
    163  1.10.10.4    skrll 	enc_src = this->src->param.encoding;
    164  1.10.10.4    skrll 	if (enc_src == AUDIO_ENCODING_SLINEAR_LE) {
    165  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 4) {
    166  1.10.10.4    skrll 			uint8_t f;
    167  1.10.10.4    skrll 			int16_t ss;
    168        1.9    isaki #if BYTE_ORDER == LITTLE_ENDIAN
    169  1.10.10.4    skrll 			ss = *(int16_t*)s;
    170  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 2);
    171  1.10.10.4    skrll 			f  = pcm2adpcm_step(mc, ss);
    172  1.10.10.4    skrll 			ss = *(int16_t*)s;
    173  1.10.10.4    skrll #else
    174  1.10.10.4    skrll 			ss = (s[1] << 8) | s[0];
    175  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 2);
    176  1.10.10.4    skrll 			f  = pcm2adpcm_step(mc, ss);
    177  1.10.10.4    skrll 			ss = (s[1] << 8) | s[0];
    178        1.9    isaki #endif
    179  1.10.10.4    skrll 			f |= pcm2adpcm_step(mc, ss) << 4;
    180  1.10.10.4    skrll 			*d = f;
    181  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    182  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 2);
    183  1.10.10.4    skrll 		}
    184  1.10.10.4    skrll 	} else {
    185  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 4) {
    186  1.10.10.4    skrll 			uint8_t f;
    187  1.10.10.4    skrll 			int16_t ss;
    188  1.10.10.4    skrll #if BYTE_ORDER == BIG_ENDIAN
    189  1.10.10.4    skrll 			ss = *(int16_t*)s;
    190  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 2);
    191  1.10.10.4    skrll 			f  = pcm2adpcm_step(mc, ss);
    192  1.10.10.4    skrll 			ss = *(int16_t*)s;
    193  1.10.10.4    skrll #else
    194  1.10.10.4    skrll 			ss = (s[0] << 8) | s[1];
    195  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 2);
    196  1.10.10.4    skrll 			f  = pcm2adpcm_step(mc, ss);
    197  1.10.10.4    skrll 			ss = (s[0] << 8) | s[1];
    198  1.10.10.4    skrll #endif
    199  1.10.10.4    skrll 			f |= pcm2adpcm_step(mc, ss) << 4;
    200  1.10.10.4    skrll 			*d = f;
    201  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    202  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 2);
    203  1.10.10.4    skrll 		}
    204        1.1  minoura 	}
    205  1.10.10.4    skrll 	dst->inp = d;
    206  1.10.10.4    skrll 	this->src->outp = s;
    207  1.10.10.4    skrll 	return 0;
    208        1.1  minoura }
    209        1.1  minoura 
    210  1.10.10.4    skrll DEFINE_FILTER(msm6258_linear8_to_adpcm)
    211        1.1  minoura {
    212  1.10.10.4    skrll 	stream_filter_t *this;
    213  1.10.10.4    skrll 	struct msm6258_codecvar *mc;
    214  1.10.10.4    skrll 	uint8_t *d;
    215  1.10.10.4    skrll 	const uint8_t *s;
    216  1.10.10.4    skrll 	int m, err, enc_src;
    217  1.10.10.4    skrll 
    218  1.10.10.4    skrll 	this = (stream_filter_t *)self;
    219  1.10.10.4    skrll 	mc = (struct msm6258_codecvar *)self;
    220  1.10.10.4    skrll 	if ((err = this->prev->fetch_to(this->prev, this->src, max_used * 2)))
    221  1.10.10.4    skrll 		return err;
    222  1.10.10.4    skrll 	m = dst->end - dst->start;
    223  1.10.10.4    skrll 	m = min(m, max_used);
    224  1.10.10.4    skrll 	d = dst->inp;
    225  1.10.10.4    skrll 	s = this->src->outp;
    226  1.10.10.4    skrll 	enc_src = this->src->param.encoding;
    227  1.10.10.4    skrll 	if (enc_src == AUDIO_ENCODING_SLINEAR_LE) {
    228  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 4) {
    229  1.10.10.4    skrll 			uint8_t f;
    230  1.10.10.4    skrll 			int16_t ss;
    231  1.10.10.4    skrll 			ss = ((int16_t)s[0]) * 256;
    232  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    233  1.10.10.4    skrll 			f  = pcm2adpcm_step(mc, ss);
    234  1.10.10.4    skrll 			ss = ((int16_t)s[0]) * 256;
    235  1.10.10.4    skrll 			f |= pcm2adpcm_step(mc, ss) << 4;
    236  1.10.10.4    skrll 			*d = f;
    237  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    238  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    239  1.10.10.4    skrll 		}
    240  1.10.10.4    skrll 	} else {
    241  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 4) {
    242  1.10.10.4    skrll 			uint8_t f;
    243  1.10.10.4    skrll 			int16_t ss;
    244  1.10.10.4    skrll 			ss = ((int16_t)(s[0] ^ 0x80)) * 256;
    245  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    246  1.10.10.4    skrll 			f  = pcm2adpcm_step(mc, ss);
    247  1.10.10.4    skrll 			ss = ((int16_t)(s[0] ^ 0x80)) * 256;
    248  1.10.10.4    skrll 			f |= pcm2adpcm_step(mc, ss) << 4;
    249  1.10.10.4    skrll 			*d = f;
    250  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    251  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    252  1.10.10.4    skrll 		}
    253  1.10.10.4    skrll 	}
    254  1.10.10.4    skrll 	dst->inp = d;
    255  1.10.10.4    skrll 	this->src->outp = s;
    256  1.10.10.4    skrll 	return 0;
    257        1.1  minoura }
    258        1.1  minoura 
    259        1.9    isaki /*
    260        1.9    isaki  * OkiADPCM -> signed 16bit linear PCM
    261        1.9    isaki  */
    262  1.10.10.4    skrll static __inline int16_t
    263  1.10.10.4    skrll adpcm2pcm_step(struct msm6258_codecvar *mc, uint8_t b)
    264        1.1  minoura {
    265        1.9    isaki 	int estim = (int)mc->mc_estim;
    266        1.7    isaki 
    267        1.9    isaki 	mc->mc_amp += adpcm_estim[estim] * adpcm_estimindex[b];
    268        1.9    isaki 	estim += adpcm_estimstep[b];
    269        1.7    isaki 
    270        1.7    isaki 	if (estim < 0)
    271        1.7    isaki 		estim = 0;
    272        1.9    isaki 	else if (estim > 48)
    273        1.7    isaki 		estim = 48;
    274        1.9    isaki 
    275        1.9    isaki 	mc->mc_estim = estim;
    276        1.9    isaki 
    277        1.9    isaki 	return mc->mc_amp;
    278        1.1  minoura }
    279        1.1  minoura 
    280  1.10.10.4    skrll DEFINE_FILTER(msm6258_adpcm_to_slinear16)
    281        1.9    isaki {
    282  1.10.10.4    skrll 	stream_filter_t *this;
    283  1.10.10.4    skrll 	struct msm6258_codecvar *mc;
    284  1.10.10.4    skrll 	uint8_t *d;
    285  1.10.10.4    skrll 	const uint8_t *s;
    286  1.10.10.4    skrll 	int m, err, enc_dst;
    287  1.10.10.4    skrll 
    288  1.10.10.4    skrll 	this = (stream_filter_t *)self;
    289  1.10.10.4    skrll 	mc = (struct msm6258_codecvar *)self;
    290  1.10.10.4    skrll 	max_used = (max_used + 3) & ~3; /* round up multiple of 4 */
    291  1.10.10.4    skrll 	if ((err = this->prev->fetch_to(this->prev, this->src, max_used / 4)))
    292  1.10.10.4    skrll 		return err;
    293  1.10.10.4    skrll 	m = (dst->end - dst->start) & ~3;
    294  1.10.10.4    skrll 	m = min(m, max_used);
    295  1.10.10.4    skrll 	d = dst->inp;
    296  1.10.10.4    skrll 	s = this->src->outp;
    297  1.10.10.4    skrll 	enc_dst = dst->param.encoding;
    298  1.10.10.4    skrll 	if (enc_dst == AUDIO_ENCODING_SLINEAR_LE) {
    299  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 1) {
    300  1.10.10.4    skrll 			uint8_t a;
    301  1.10.10.4    skrll 			int16_t s1, s2;
    302  1.10.10.4    skrll 			a = s[0];
    303  1.10.10.4    skrll 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    304  1.10.10.4    skrll 			s2 = adpcm2pcm_step(mc, a >> 4);
    305        1.9    isaki #if BYTE_ORDER == LITTLE_ENDIAN
    306  1.10.10.4    skrll 			*(int16_t*)d = s1;
    307  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 2);
    308  1.10.10.4    skrll 			*(int16_t*)d = s2;
    309  1.10.10.4    skrll #else
    310  1.10.10.4    skrll 			d[0] = s1;
    311  1.10.10.4    skrll 			d[1] = s1 >> 8;
    312  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 2);
    313  1.10.10.4    skrll 			d[0] = s2;
    314  1.10.10.4    skrll 			d[1] = s2 >> 8;
    315        1.9    isaki #endif
    316  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 2);
    317  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    318  1.10.10.4    skrll 		}
    319  1.10.10.4    skrll 	} else {
    320  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 1) {
    321  1.10.10.4    skrll 			uint8_t a;
    322  1.10.10.4    skrll 			int16_t s1, s2;
    323  1.10.10.4    skrll 			a = s[0];
    324  1.10.10.4    skrll 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    325  1.10.10.4    skrll 			s2 = adpcm2pcm_step(mc, a >> 4);
    326  1.10.10.4    skrll #if BYTE_ORDER == BIG_ENDIAN
    327  1.10.10.4    skrll 			*(int16_t*)d = s1;
    328  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 2);
    329  1.10.10.4    skrll 			*(int16_t*)d = s2;
    330  1.10.10.4    skrll #else
    331  1.10.10.4    skrll 			d[1] = s1;
    332  1.10.10.4    skrll 			d[0] = s1 >> 8;
    333  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 2);
    334  1.10.10.4    skrll 			d[1] = s2;
    335  1.10.10.4    skrll 			d[0] = s2 >> 8;
    336  1.10.10.4    skrll #endif
    337  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 2);
    338  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    339  1.10.10.4    skrll 		}
    340        1.1  minoura 	}
    341  1.10.10.4    skrll 	dst->inp = d;
    342  1.10.10.4    skrll 	this->src->outp = s;
    343  1.10.10.4    skrll 	return 0;
    344        1.1  minoura }
    345        1.1  minoura 
    346  1.10.10.4    skrll DEFINE_FILTER(msm6258_adpcm_to_linear8)
    347        1.1  minoura {
    348  1.10.10.4    skrll 	stream_filter_t *this;
    349  1.10.10.4    skrll 	struct msm6258_codecvar *mc;
    350  1.10.10.4    skrll 	uint8_t *d;
    351  1.10.10.4    skrll 	const uint8_t *s;
    352  1.10.10.4    skrll 	int m, err, enc_dst;
    353  1.10.10.4    skrll 
    354  1.10.10.4    skrll 	this = (stream_filter_t *)self;
    355  1.10.10.4    skrll 	mc = (struct msm6258_codecvar *)self;
    356  1.10.10.4    skrll 	max_used = (max_used + 1) & ~1; /* round up multiple of 4 */
    357  1.10.10.4    skrll 	if ((err = this->prev->fetch_to(this->prev, this->src, max_used / 2)))
    358  1.10.10.4    skrll 		return err;
    359  1.10.10.4    skrll 	m = (dst->end - dst->start) & ~1;
    360  1.10.10.4    skrll 	m = min(m, max_used);
    361  1.10.10.4    skrll 	d = dst->inp;
    362  1.10.10.4    skrll 	s = this->src->outp;
    363  1.10.10.4    skrll 	enc_dst = dst->param.encoding;
    364  1.10.10.4    skrll 	if (enc_dst == AUDIO_ENCODING_SLINEAR_LE) {
    365  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 1) {
    366  1.10.10.4    skrll 			uint8_t a;
    367  1.10.10.4    skrll 			int16_t s1, s2;
    368  1.10.10.4    skrll 			a = s[0];
    369  1.10.10.4    skrll 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    370  1.10.10.4    skrll 			s2 = adpcm2pcm_step(mc, a >> 4);
    371  1.10.10.4    skrll 			d[0] = s1 / 266;
    372  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    373  1.10.10.4    skrll 			d[0] = s2 / 266;
    374  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    375  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    376  1.10.10.4    skrll 		}
    377  1.10.10.4    skrll 	} else {
    378  1.10.10.4    skrll 		while (dst->used < m && this->src->used >= 1) {
    379  1.10.10.4    skrll 			uint8_t a;
    380  1.10.10.4    skrll 			int16_t s1, s2;
    381  1.10.10.4    skrll 			a = s[0];
    382  1.10.10.4    skrll 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    383  1.10.10.4    skrll 			s2 = adpcm2pcm_step(mc, a >> 4);
    384  1.10.10.4    skrll 			d[0] = (s1 / 266) ^ 0x80;
    385  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    386  1.10.10.4    skrll 			d[0] = (s2 / 266) ^ 0x80;
    387  1.10.10.4    skrll 			d = audio_stream_add_inp(dst, d, 1);
    388  1.10.10.4    skrll 			s = audio_stream_add_outp(this->src, s, 1);
    389  1.10.10.4    skrll 		}
    390  1.10.10.4    skrll 	}
    391  1.10.10.4    skrll 	dst->inp = d;
    392  1.10.10.4    skrll 	this->src->outp = s;
    393  1.10.10.4    skrll 	return 0;
    394        1.1  minoura }
    395