Home | History | Annotate | Line # | Download | only in ic
msm6258.c revision 1.18
      1  1.18     isaki /*	$NetBSD: msm6258.c,v 1.18 2017/07/15 10:17:09 isaki 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.1   minoura  *
     15   1.1   minoura  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16   1.1   minoura  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17   1.1   minoura  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18   1.1   minoura  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19   1.1   minoura  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     20   1.1   minoura  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     21   1.1   minoura  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     22   1.1   minoura  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     23   1.1   minoura  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24   1.1   minoura  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25   1.1   minoura  * SUCH DAMAGE.
     26   1.1   minoura  */
     27   1.1   minoura 
     28   1.1   minoura /*
     29   1.1   minoura  * OKI MSM6258 ADPCM voice synthesizer codec.
     30   1.1   minoura  */
     31   1.5     lukem 
     32   1.5     lukem #include <sys/cdefs.h>
     33  1.18     isaki __KERNEL_RCSID(0, "$NetBSD: msm6258.c,v 1.18 2017/07/15 10:17:09 isaki Exp $");
     34   1.1   minoura 
     35   1.1   minoura #include <sys/systm.h>
     36   1.1   minoura #include <sys/device.h>
     37  1.17  jmcneill #include <sys/kmem.h>
     38   1.1   minoura #include <sys/select.h>
     39   1.1   minoura #include <sys/audioio.h>
     40   1.1   minoura 
     41   1.1   minoura #include <dev/audio_if.h>
     42   1.6     isaki #include <dev/auconv.h>
     43   1.1   minoura #include <dev/audiovar.h>
     44   1.4   minoura #include <dev/mulaw.h>
     45   1.1   minoura #include <dev/ic/msm6258var.h>
     46   1.1   minoura 
     47   1.9     isaki struct msm6258_codecvar {
     48  1.12      kent 	stream_filter_t	base;
     49  1.12      kent 	short		mc_amp;
     50  1.12      kent 	char		mc_estim;
     51   1.9     isaki };
     52   1.9     isaki 
     53  1.12      kent static stream_filter_t *msm6258_factory
     54  1.17  jmcneill 	(struct audio_softc *,
     55  1.17  jmcneill 	 int (*)(struct audio_softc *, stream_fetcher_t *, audio_stream_t *, int));
     56  1.12      kent static void msm6258_dtor(struct stream_filter *);
     57  1.15     perry static inline uint8_t	pcm2adpcm_step(struct msm6258_codecvar *, int16_t);
     58  1.15     perry static inline int16_t	adpcm2pcm_step(struct msm6258_codecvar *, uint8_t);
     59   1.1   minoura 
     60  1.12      kent static const int adpcm_estimindex[16] = {
     61   1.9     isaki 	 2,  6,  10,  14,  18,  22,  26,  30,
     62   1.9     isaki 	-2, -6, -10, -14, -18, -22, -26, -30
     63   1.1   minoura };
     64   1.1   minoura 
     65  1.12      kent static const int adpcm_estim[49] = {
     66   1.1   minoura 	 16,  17,  19,  21,  23,  25,  28,  31,  34,  37,
     67   1.1   minoura 	 41,  45,  50,  55,  60,  66,  73,  80,  88,  97,
     68   1.1   minoura 	107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
     69   1.1   minoura 	279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
     70  1.10     isaki 	724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
     71   1.1   minoura };
     72   1.1   minoura 
     73  1.12      kent static const int adpcm_estimstep[16] = {
     74   1.1   minoura 	-1, -1, -1, -1, 2, 4, 6, 8,
     75   1.1   minoura 	-1, -1, -1, -1, 2, 4, 6, 8
     76   1.1   minoura };
     77   1.1   minoura 
     78  1.12      kent static stream_filter_t *
     79  1.17  jmcneill msm6258_factory(struct audio_softc *asc,
     80  1.17  jmcneill     int (*fetch_to)(struct audio_softc *, stream_fetcher_t *, audio_stream_t *, int))
     81   1.1   minoura {
     82  1.12      kent 	struct msm6258_codecvar *this;
     83   1.1   minoura 
     84  1.17  jmcneill 	this = kmem_alloc(sizeof(struct msm6258_codecvar), KM_SLEEP);
     85  1.12      kent 	this->base.base.fetch_to = fetch_to;
     86  1.12      kent 	this->base.dtor = msm6258_dtor;
     87  1.12      kent 	this->base.set_fetcher = stream_filter_set_fetcher;
     88  1.12      kent 	this->base.set_inputbuffer = stream_filter_set_inputbuffer;
     89  1.12      kent 	return &this->base;
     90   1.8     isaki }
     91   1.8     isaki 
     92  1.12      kent static void
     93  1.12      kent msm6258_dtor(struct stream_filter *this)
     94   1.8     isaki {
     95  1.12      kent 	if (this != NULL)
     96  1.17  jmcneill 		kmem_free(this, sizeof(struct msm6258_codecvar));
     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.15     perry static inline uint8_t
    103  1.12      kent 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.12      kent 	uint8_t b;
    109  1.12      kent 	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.12      kent #define DEFINE_FILTER(name)	\
    136  1.12      kent static int \
    137  1.17  jmcneill name##_fetch_to(struct audio_softc *, stream_fetcher_t *, audio_stream_t *, int); \
    138  1.12      kent stream_filter_t * \
    139  1.12      kent name(struct audio_softc *sc, const audio_params_t *from, \
    140  1.12      kent      const audio_params_t *to) \
    141  1.12      kent { \
    142  1.17  jmcneill 	return msm6258_factory(sc, name##_fetch_to); \
    143  1.12      kent } \
    144  1.12      kent static int \
    145  1.17  jmcneill name##_fetch_to(struct audio_softc *asc, stream_fetcher_t *self, audio_stream_t *dst, int max_used)
    146  1.12      kent 
    147  1.12      kent DEFINE_FILTER(msm6258_slinear16_to_adpcm)
    148  1.12      kent {
    149  1.12      kent 	stream_filter_t *this;
    150  1.12      kent 	struct msm6258_codecvar *mc;
    151  1.12      kent 	uint8_t *d;
    152  1.12      kent 	const uint8_t *s;
    153  1.12      kent 	int m, err, enc_src;
    154  1.12      kent 
    155  1.12      kent 	this = (stream_filter_t *)self;
    156  1.12      kent 	mc = (struct msm6258_codecvar *)self;
    157  1.17  jmcneill 	if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used * 4)))
    158  1.12      kent 		return err;
    159  1.12      kent 	m = dst->end - dst->start;
    160  1.12      kent 	m = min(m, max_used);
    161  1.12      kent 	d = dst->inp;
    162  1.12      kent 	s = this->src->outp;
    163  1.12      kent 	enc_src = this->src->param.encoding;
    164  1.12      kent 	if (enc_src == AUDIO_ENCODING_SLINEAR_LE) {
    165  1.12      kent 		while (dst->used < m && this->src->used >= 4) {
    166  1.12      kent 			uint8_t f;
    167  1.12      kent 			int16_t ss;
    168  1.12      kent #if BYTE_ORDER == LITTLE_ENDIAN
    169  1.13        he 			ss = *(const int16_t*)s;
    170  1.12      kent 			s = audio_stream_add_outp(this->src, s, 2);
    171  1.12      kent 			f  = pcm2adpcm_step(mc, ss);
    172  1.13        he 			ss = *(const int16_t*)s;
    173  1.12      kent #else
    174  1.12      kent 			ss = (s[1] << 8) | s[0];
    175  1.12      kent 			s = audio_stream_add_outp(this->src, s, 2);
    176  1.12      kent 			f  = pcm2adpcm_step(mc, ss);
    177  1.12      kent 			ss = (s[1] << 8) | s[0];
    178  1.12      kent #endif
    179  1.12      kent 			f |= pcm2adpcm_step(mc, ss) << 4;
    180  1.12      kent 			*d = f;
    181  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    182  1.12      kent 			s = audio_stream_add_outp(this->src, s, 2);
    183  1.12      kent 		}
    184  1.18     isaki #if defined(DIAGNOSTIC)
    185  1.18     isaki 	} else if (enc_src == AUDIO_ENCODING_SLINEAR_BE) {
    186  1.18     isaki #else
    187  1.12      kent 	} else {
    188  1.18     isaki #endif
    189  1.12      kent 		while (dst->used < m && this->src->used >= 4) {
    190  1.12      kent 			uint8_t f;
    191  1.12      kent 			int16_t ss;
    192   1.9     isaki #if BYTE_ORDER == BIG_ENDIAN
    193  1.13        he 			ss = *(const int16_t*)s;
    194  1.12      kent 			s = audio_stream_add_outp(this->src, s, 2);
    195  1.12      kent 			f  = pcm2adpcm_step(mc, ss);
    196  1.13        he 			ss = *(const int16_t*)s;
    197  1.12      kent #else
    198  1.12      kent 			ss = (s[0] << 8) | s[1];
    199  1.12      kent 			s = audio_stream_add_outp(this->src, s, 2);
    200  1.12      kent 			f  = pcm2adpcm_step(mc, ss);
    201  1.12      kent 			ss = (s[0] << 8) | s[1];
    202   1.9     isaki #endif
    203  1.12      kent 			f |= pcm2adpcm_step(mc, ss) << 4;
    204  1.12      kent 			*d = f;
    205  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    206  1.12      kent 			s = audio_stream_add_outp(this->src, s, 2);
    207  1.12      kent 		}
    208  1.12      kent 	}
    209  1.18     isaki #if defined(DIAGNOSTIC)
    210  1.18     isaki 	else {
    211  1.18     isaki 		panic("msm6258_slinear16_to_adpcm: unsupported enc_src(%d)", enc_src);
    212  1.18     isaki 	}
    213  1.18     isaki #endif
    214  1.12      kent 	dst->inp = d;
    215  1.12      kent 	this->src->outp = s;
    216  1.12      kent 	return 0;
    217   1.9     isaki }
    218   1.1   minoura 
    219  1.12      kent DEFINE_FILTER(msm6258_linear8_to_adpcm)
    220   1.9     isaki {
    221  1.12      kent 	stream_filter_t *this;
    222  1.12      kent 	struct msm6258_codecvar *mc;
    223  1.12      kent 	uint8_t *d;
    224  1.12      kent 	const uint8_t *s;
    225  1.12      kent 	int m, err, enc_src;
    226  1.12      kent 
    227  1.12      kent 	this = (stream_filter_t *)self;
    228  1.12      kent 	mc = (struct msm6258_codecvar *)self;
    229  1.17  jmcneill 	if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used * 2)))
    230  1.12      kent 		return err;
    231  1.12      kent 	m = dst->end - dst->start;
    232  1.12      kent 	m = min(m, max_used);
    233  1.12      kent 	d = dst->inp;
    234  1.12      kent 	s = this->src->outp;
    235  1.12      kent 	enc_src = this->src->param.encoding;
    236  1.12      kent 	if (enc_src == AUDIO_ENCODING_SLINEAR_LE) {
    237  1.12      kent 		while (dst->used < m && this->src->used >= 4) {
    238  1.12      kent 			uint8_t f;
    239  1.12      kent 			int16_t ss;
    240  1.12      kent 			ss = ((int16_t)s[0]) * 256;
    241  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    242  1.12      kent 			f  = pcm2adpcm_step(mc, ss);
    243  1.12      kent 			ss = ((int16_t)s[0]) * 256;
    244  1.12      kent 			f |= pcm2adpcm_step(mc, ss) << 4;
    245  1.12      kent 			*d = f;
    246  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    247  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    248  1.12      kent 		}
    249  1.18     isaki #if defined(DIAGNOSTIC)
    250  1.18     isaki 	} else if (enc_src == AUDIO_ENCODING_ULINEAR_LE) {
    251  1.18     isaki #else
    252  1.12      kent 	} else {
    253  1.18     isaki #endif
    254  1.12      kent 		while (dst->used < m && this->src->used >= 4) {
    255  1.12      kent 			uint8_t f;
    256  1.12      kent 			int16_t ss;
    257  1.12      kent 			ss = ((int16_t)(s[0] ^ 0x80)) * 256;
    258  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    259  1.12      kent 			f  = pcm2adpcm_step(mc, ss);
    260  1.12      kent 			ss = ((int16_t)(s[0] ^ 0x80)) * 256;
    261  1.12      kent 			f |= pcm2adpcm_step(mc, ss) << 4;
    262  1.12      kent 			*d = f;
    263  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    264  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    265  1.12      kent 		}
    266   1.1   minoura 	}
    267  1.18     isaki #if defined(DIAGNOSTIC)
    268  1.18     isaki 	else {
    269  1.18     isaki 		panic("msm6258_linear8_to_adpcm: unsupported enc_src(%d)", enc_src);
    270  1.18     isaki 	}
    271  1.18     isaki #endif
    272  1.12      kent 	dst->inp = d;
    273  1.12      kent 	this->src->outp = s;
    274  1.12      kent 	return 0;
    275   1.1   minoura }
    276   1.1   minoura 
    277   1.9     isaki /*
    278   1.9     isaki  * OkiADPCM -> signed 16bit linear PCM
    279   1.9     isaki  */
    280  1.15     perry static inline int16_t
    281  1.12      kent adpcm2pcm_step(struct msm6258_codecvar *mc, uint8_t b)
    282   1.1   minoura {
    283   1.9     isaki 	int estim = (int)mc->mc_estim;
    284   1.7     isaki 
    285   1.9     isaki 	mc->mc_amp += adpcm_estim[estim] * adpcm_estimindex[b];
    286   1.9     isaki 	estim += adpcm_estimstep[b];
    287   1.7     isaki 
    288   1.7     isaki 	if (estim < 0)
    289   1.7     isaki 		estim = 0;
    290   1.9     isaki 	else if (estim > 48)
    291   1.7     isaki 		estim = 48;
    292   1.9     isaki 
    293   1.9     isaki 	mc->mc_estim = estim;
    294   1.9     isaki 
    295   1.9     isaki 	return mc->mc_amp;
    296   1.1   minoura }
    297   1.1   minoura 
    298  1.12      kent DEFINE_FILTER(msm6258_adpcm_to_slinear16)
    299   1.9     isaki {
    300  1.12      kent 	stream_filter_t *this;
    301  1.12      kent 	struct msm6258_codecvar *mc;
    302  1.12      kent 	uint8_t *d;
    303  1.12      kent 	const uint8_t *s;
    304  1.12      kent 	int m, err, enc_dst;
    305  1.12      kent 
    306  1.12      kent 	this = (stream_filter_t *)self;
    307  1.12      kent 	mc = (struct msm6258_codecvar *)self;
    308  1.12      kent 	max_used = (max_used + 3) & ~3; /* round up multiple of 4 */
    309  1.17  jmcneill 	if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used / 4)))
    310  1.12      kent 		return err;
    311  1.12      kent 	m = (dst->end - dst->start) & ~3;
    312  1.12      kent 	m = min(m, max_used);
    313  1.12      kent 	d = dst->inp;
    314  1.12      kent 	s = this->src->outp;
    315  1.12      kent 	enc_dst = dst->param.encoding;
    316  1.12      kent 	if (enc_dst == AUDIO_ENCODING_SLINEAR_LE) {
    317  1.12      kent 		while (dst->used < m && this->src->used >= 1) {
    318  1.12      kent 			uint8_t a;
    319  1.12      kent 			int16_t s1, s2;
    320  1.12      kent 			a = s[0];
    321  1.12      kent 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    322  1.12      kent 			s2 = adpcm2pcm_step(mc, a >> 4);
    323  1.12      kent #if BYTE_ORDER == LITTLE_ENDIAN
    324  1.12      kent 			*(int16_t*)d = s1;
    325  1.12      kent 			d = audio_stream_add_inp(dst, d, 2);
    326  1.12      kent 			*(int16_t*)d = s2;
    327  1.12      kent #else
    328  1.12      kent 			d[0] = s1;
    329  1.12      kent 			d[1] = s1 >> 8;
    330  1.12      kent 			d = audio_stream_add_inp(dst, d, 2);
    331  1.12      kent 			d[0] = s2;
    332  1.12      kent 			d[1] = s2 >> 8;
    333  1.12      kent #endif
    334  1.12      kent 			d = audio_stream_add_inp(dst, d, 2);
    335  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    336  1.12      kent 		}
    337  1.18     isaki #if defined(DIAGNOSTIC)
    338  1.18     isaki 	} else if (enc_dst == AUDIO_ENCODING_SLINEAR_BE) {
    339  1.18     isaki #else
    340  1.12      kent 	} else {
    341  1.18     isaki #endif
    342  1.12      kent 		while (dst->used < m && this->src->used >= 1) {
    343  1.12      kent 			uint8_t a;
    344  1.12      kent 			int16_t s1, s2;
    345  1.12      kent 			a = s[0];
    346  1.12      kent 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    347  1.12      kent 			s2 = adpcm2pcm_step(mc, a >> 4);
    348   1.9     isaki #if BYTE_ORDER == BIG_ENDIAN
    349  1.12      kent 			*(int16_t*)d = s1;
    350  1.12      kent 			d = audio_stream_add_inp(dst, d, 2);
    351  1.12      kent 			*(int16_t*)d = s2;
    352  1.12      kent #else
    353  1.12      kent 			d[1] = s1;
    354  1.12      kent 			d[0] = s1 >> 8;
    355  1.12      kent 			d = audio_stream_add_inp(dst, d, 2);
    356  1.12      kent 			d[1] = s2;
    357  1.12      kent 			d[0] = s2 >> 8;
    358   1.9     isaki #endif
    359  1.12      kent 			d = audio_stream_add_inp(dst, d, 2);
    360  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    361  1.12      kent 		}
    362  1.12      kent 	}
    363  1.18     isaki #if defined(DIAGNOSTIC)
    364  1.18     isaki 	else {
    365  1.18     isaki 		panic("msm6258_adpcm_to_slinear16: unsupported enc_dst(%d)", enc_dst);
    366  1.18     isaki 	}
    367  1.18     isaki #endif
    368  1.12      kent 	dst->inp = d;
    369  1.12      kent 	this->src->outp = s;
    370  1.12      kent 	return 0;
    371   1.9     isaki }
    372   1.9     isaki 
    373  1.12      kent DEFINE_FILTER(msm6258_adpcm_to_linear8)
    374   1.9     isaki {
    375  1.12      kent 	stream_filter_t *this;
    376  1.12      kent 	struct msm6258_codecvar *mc;
    377  1.12      kent 	uint8_t *d;
    378  1.12      kent 	const uint8_t *s;
    379  1.12      kent 	int m, err, enc_dst;
    380  1.12      kent 
    381  1.12      kent 	this = (stream_filter_t *)self;
    382  1.12      kent 	mc = (struct msm6258_codecvar *)self;
    383  1.12      kent 	max_used = (max_used + 1) & ~1; /* round up multiple of 4 */
    384  1.17  jmcneill 	if ((err = this->prev->fetch_to(asc, this->prev, this->src, max_used / 2)))
    385  1.12      kent 		return err;
    386  1.12      kent 	m = (dst->end - dst->start) & ~1;
    387  1.12      kent 	m = min(m, max_used);
    388  1.12      kent 	d = dst->inp;
    389  1.12      kent 	s = this->src->outp;
    390  1.12      kent 	enc_dst = dst->param.encoding;
    391  1.12      kent 	if (enc_dst == AUDIO_ENCODING_SLINEAR_LE) {
    392  1.12      kent 		while (dst->used < m && this->src->used >= 1) {
    393  1.12      kent 			uint8_t a;
    394  1.12      kent 			int16_t s1, s2;
    395  1.12      kent 			a = s[0];
    396  1.12      kent 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    397  1.12      kent 			s2 = adpcm2pcm_step(mc, a >> 4);
    398  1.12      kent 			d[0] = s1 / 266;
    399  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    400  1.12      kent 			d[0] = s2 / 266;
    401  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    402  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    403  1.12      kent 		}
    404  1.18     isaki #if defined(DIAGNOSTIC)
    405  1.18     isaki 	} else if (enc_dst == AUDIO_ENCODING_ULINEAR_LE) {
    406  1.18     isaki #else
    407  1.12      kent 	} else {
    408  1.18     isaki #endif
    409  1.12      kent 		while (dst->used < m && this->src->used >= 1) {
    410  1.12      kent 			uint8_t a;
    411  1.12      kent 			int16_t s1, s2;
    412  1.12      kent 			a = s[0];
    413  1.12      kent 			s1 = adpcm2pcm_step(mc, a & 0x0f);
    414  1.12      kent 			s2 = adpcm2pcm_step(mc, a >> 4);
    415  1.12      kent 			d[0] = (s1 / 266) ^ 0x80;
    416  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    417  1.12      kent 			d[0] = (s2 / 266) ^ 0x80;
    418  1.12      kent 			d = audio_stream_add_inp(dst, d, 1);
    419  1.12      kent 			s = audio_stream_add_outp(this->src, s, 1);
    420  1.12      kent 		}
    421   1.1   minoura 	}
    422  1.18     isaki #if defined(DIAGNOSTIC)
    423  1.18     isaki 	else {
    424  1.18     isaki 		panic("msm6258_adpcm_to_linear8: unsupported enc_dst(%d)", enc_dst);
    425  1.18     isaki 	}
    426  1.18     isaki #endif
    427  1.12      kent 	dst->inp = d;
    428  1.12      kent 	this->src->outp = s;
    429  1.12      kent 	return 0;
    430   1.1   minoura }
    431