msm6258.c revision 1.8 1 1.8 isaki /* $NetBSD: msm6258.c,v 1.8 2002/04/02 15:22:38 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 * 3. All advertising materials mentioning features or use of this software
15 1.1 minoura * must display the following acknowledgement:
16 1.1 minoura * This product includes software developed by Tetsuya Isaki.
17 1.1 minoura * 4. The name of the author may not be used to endorse or promote products
18 1.1 minoura * derived from this software without specific prior written permission
19 1.1 minoura *
20 1.1 minoura * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 1.1 minoura * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 1.1 minoura * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 1.1 minoura * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 1.1 minoura * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 1.1 minoura * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 1.1 minoura * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 1.1 minoura * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 1.1 minoura * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 1.1 minoura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 1.1 minoura * SUCH DAMAGE.
31 1.1 minoura */
32 1.1 minoura
33 1.1 minoura /*
34 1.1 minoura * OKI MSM6258 ADPCM voice synthesizer codec.
35 1.1 minoura */
36 1.5 lukem
37 1.5 lukem #include <sys/cdefs.h>
38 1.8 isaki __KERNEL_RCSID(0, "$NetBSD: msm6258.c,v 1.8 2002/04/02 15:22:38 isaki Exp $");
39 1.1 minoura
40 1.1 minoura #include <sys/systm.h>
41 1.1 minoura #include <sys/device.h>
42 1.1 minoura #include <sys/malloc.h>
43 1.1 minoura #include <sys/select.h>
44 1.1 minoura #include <sys/audioio.h>
45 1.1 minoura
46 1.1 minoura #include <dev/audio_if.h>
47 1.6 isaki #include <dev/auconv.h>
48 1.1 minoura #include <dev/audiovar.h>
49 1.4 minoura #include <dev/mulaw.h>
50 1.1 minoura #include <dev/ic/msm6258var.h>
51 1.1 minoura
52 1.1 minoura
53 1.1 minoura static inline u_char pcm2adpcm_step(short, short *, char *);
54 1.1 minoura static inline void adpcm2pcm_step(u_char, short *, char *);
55 1.1 minoura
56 1.1 minoura
57 1.1 minoura static int adpcm_estimindex[16] = {
58 1.7 isaki 1, 3, 5, 7, 9, 11, 13, 15,
59 1.7 isaki -1, -3, -5, -7, -9, -11, -13, -15
60 1.1 minoura };
61 1.1 minoura
62 1.1 minoura static int adpcm_estim[49] = {
63 1.1 minoura 16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
64 1.1 minoura 41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
65 1.1 minoura 107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
66 1.1 minoura 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
67 1.1 minoura 724, 796, 875, 963, 1060, 1166, 1282, 1411, 1552
68 1.1 minoura };
69 1.1 minoura
70 1.1 minoura static u_char adpcm_estimindex_correct[16] = {
71 1.1 minoura -1, -1, -1, -1, 2, 4, 6, 8,
72 1.1 minoura -1, -1, -1, -1, 2, 4, 6, 8
73 1.1 minoura };
74 1.1 minoura
75 1.1 minoura struct msm6258_codecvar {
76 1.1 minoura short mc_amp;
77 1.1 minoura char mc_estim;
78 1.1 minoura };
79 1.1 minoura
80 1.1 minoura struct msm6258_softc {
81 1.1 minoura struct device sc_dev;
82 1.1 minoura struct msm6258_codecvar *sc_mc;
83 1.1 minoura /* MD vars follow */
84 1.1 minoura };
85 1.1 minoura
86 1.1 minoura void *
87 1.1 minoura msm6258_codec_init (void)
88 1.1 minoura {
89 1.1 minoura struct msm6258_codecvar *r;
90 1.1 minoura
91 1.1 minoura r = malloc (sizeof(*r), M_DEVBUF, M_NOWAIT);
92 1.1 minoura if (r == 0)
93 1.1 minoura return 0;
94 1.1 minoura r->mc_amp = r->mc_estim = 0;
95 1.1 minoura
96 1.1 minoura return r;
97 1.8 isaki }
98 1.8 isaki
99 1.8 isaki int
100 1.8 isaki msm6258_codec_open(void *hdl)
101 1.8 isaki {
102 1.8 isaki struct msm6258_softc *sc = hdl;
103 1.8 isaki struct msm6258_codecvar *mc = sc->sc_mc;
104 1.8 isaki
105 1.8 isaki mc->mc_amp = 0;
106 1.8 isaki mc->mc_estim = 0;
107 1.8 isaki
108 1.8 isaki return 0;
109 1.1 minoura }
110 1.1 minoura
111 1.1 minoura static inline u_char
112 1.1 minoura pcm2adpcm_step(short a, short *y, char *x)
113 1.1 minoura {
114 1.1 minoura int c, d;
115 1.1 minoura register unsigned char b;
116 1.1 minoura
117 1.1 minoura a -= *y;
118 1.4 minoura d = adpcm_estim[(int) *x];
119 1.7 isaki c = a * 4 / d;
120 1.1 minoura
121 1.1 minoura if (c < 0) {
122 1.7 isaki b = (unsigned char)-c;
123 1.1 minoura if (b >= 8)
124 1.1 minoura b = 7;
125 1.1 minoura b |= 0x08;
126 1.1 minoura } else {
127 1.7 isaki b = (unsigned char)c;
128 1.1 minoura if (b >= 8)
129 1.1 minoura b = 7;
130 1.1 minoura }
131 1.1 minoura
132 1.7 isaki *y += (short)(adpcm_estimindex[b] * d / 8);
133 1.1 minoura *x += adpcm_estimindex_correct[b];
134 1.1 minoura if (*x < 0)
135 1.1 minoura *x = 0;
136 1.1 minoura else if (*x > 48)
137 1.1 minoura *x = 48;
138 1.1 minoura return b;
139 1.1 minoura }
140 1.1 minoura
141 1.1 minoura void
142 1.1 minoura msm6258_ulinear8_to_adpcm(void *hdl, u_char *p, int cc)
143 1.1 minoura {
144 1.1 minoura struct msm6258_softc *sc = hdl;
145 1.1 minoura struct msm6258_codecvar *mc = sc->sc_mc;
146 1.1 minoura char *x = &(mc->mc_estim);
147 1.1 minoura short *y = &(mc->mc_amp);
148 1.1 minoura register int i;
149 1.6 isaki u_char *d = p;
150 1.1 minoura u_char f;
151 1.1 minoura
152 1.6 isaki for (i = 0; i < cc; ) {
153 1.6 isaki f = pcm2adpcm_step(p[i++], y, x);
154 1.6 isaki *d++ = f + (pcm2adpcm_step(p[i++], y, x) << 4);
155 1.1 minoura }
156 1.1 minoura }
157 1.1 minoura
158 1.1 minoura void
159 1.1 minoura msm6258_mulaw_to_adpcm(void *hdl, u_char *p, int cc)
160 1.1 minoura {
161 1.1 minoura mulaw_to_ulinear8(hdl, p, cc);
162 1.1 minoura msm6258_ulinear8_to_adpcm(hdl, p, cc);
163 1.1 minoura }
164 1.1 minoura
165 1.1 minoura static inline void
166 1.1 minoura adpcm2pcm_step(u_char b, short *y, char *x)
167 1.1 minoura {
168 1.7 isaki short dl;
169 1.7 isaki short pcm = *y;
170 1.7 isaki int estim = *x;
171 1.7 isaki
172 1.7 isaki dl = adpcm_estim[estim] * adpcm_estimindex[b] / 8;
173 1.7 isaki pcm += dl;
174 1.7 isaki *y = pcm / 256;
175 1.7 isaki
176 1.7 isaki estim += adpcm_estimindex_correct[b];
177 1.7 isaki if (estim < 0)
178 1.7 isaki estim = 0;
179 1.7 isaki if (estim > 48)
180 1.7 isaki estim = 48;
181 1.7 isaki *x = estim;
182 1.1 minoura }
183 1.1 minoura
184 1.1 minoura /* ADPCM stream must be converted in order. */
185 1.1 minoura u_char tmpbuf[AU_RING_SIZE]; /* XXX */
186 1.1 minoura
187 1.1 minoura void
188 1.1 minoura msm6258_adpcm_to_ulinear8(void *hdl, u_char *p, int cc)
189 1.1 minoura {
190 1.1 minoura struct msm6258_softc *sc = hdl;
191 1.1 minoura struct msm6258_codecvar *mc = sc->sc_mc;
192 1.1 minoura char *x = &(mc->mc_estim);
193 1.1 minoura short *y = &(mc->mc_amp);
194 1.1 minoura u_char a, b;
195 1.1 minoura int i;
196 1.1 minoura
197 1.7 isaki /* cc may be even. XXX alignment? */
198 1.7 isaki memcpy(tmpbuf, p, cc/2);
199 1.7 isaki for (i = 0; i < cc/2;) {
200 1.7 isaki a = tmpbuf[i++];
201 1.1 minoura b = a & 0x0f;
202 1.1 minoura adpcm2pcm_step(b, y, x);
203 1.7 isaki *p++ = *y;
204 1.1 minoura b = a >> 4;
205 1.1 minoura adpcm2pcm_step(b, y, x);
206 1.7 isaki *p++ = *y;
207 1.1 minoura }
208 1.1 minoura }
209 1.1 minoura
210 1.1 minoura void
211 1.1 minoura msm6258_adpcm_to_mulaw(void *hdl, u_char *p, int cc)
212 1.1 minoura {
213 1.1 minoura msm6258_adpcm_to_ulinear8(hdl, p, cc);
214 1.1 minoura ulinear8_to_mulaw(hdl, p, cc*2);
215 1.1 minoura }
216