1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (C) 4Front Technologies 1996-2008.
23 *
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27 /*
28 * Purpose: Test sounds for osstest
29 *
30 * Nodoc:
31 */
32
33 #include <string.h>
34
35 #include "wavedata.h"
36
37 static int
le_int(const unsigned char * p,int l)38 le_int(const unsigned char *p, int l)
39 {
40 int i, val;
41
42 val = 0;
43
44 for (i = l - 1; i >= 0; i--) {
45 val = (val << 8) | p[i];
46 }
47
48 return (val);
49 }
50
51 int
uncompress_wave(short * outbuf)52 uncompress_wave(short *outbuf)
53 {
54 #define WAVE_FORMAT_ADPCM 0x0002
55
56 int i, n, dataleft, x, l = sizeof (inbuf);
57 const unsigned char *hdr = inbuf;
58 typedef struct {
59 int coeff1, coeff2;
60 }
61 adpcm_coeff;
62
63 adpcm_coeff coeff[32];
64 static int AdaptionTable[] = { 230, 230, 230, 230, 307, 409, 512, 614,
65 768, 614, 512, 409, 307, 230, 230, 230
66 };
67
68 unsigned char buf[4096];
69
70 int channels = 1;
71 int p = 12, outp = 0;
72 int nBlockAlign = 2048;
73 int wSamplesPerBlock = 2036, wNumCoeff = 7;
74 int nib;
75 int ppp;
76
77 /* filelen = le_int(&hdr[4], 4); */
78
79 while (p < l - 16 && memcmp(&hdr[p], "data", 4) != 0) {
80 n = le_int(&hdr[p + 4], 4);
81
82 if (memcmp(&hdr[p], "fmt ", 4) == 0) {
83
84 /* fmt = le_int(&hdr[p + 8], 2); */
85 channels = le_int(&hdr[p + 10], 2);
86 /* speed = le_int(&hdr[p + 12], 4); */
87 nBlockAlign = le_int(&hdr[p + 20], 2);
88 /* bytes_per_sample = le_int(&hdr[p + 20], 2); */
89
90 wSamplesPerBlock = le_int(&hdr[p + 26], 2);
91 wNumCoeff = le_int(&hdr[p + 28], 2);
92
93 x = p + 30;
94
95 for (i = 0; i < wNumCoeff; i++) {
96 coeff[i].coeff1 = (short)le_int(&hdr[x], 2);
97 x += 2;
98 coeff[i].coeff2 = (short)le_int(&hdr[x], 2);
99 x += 2;
100 }
101 }
102
103 p += n + 8;
104 }
105
106 if (p < l - 16 && memcmp(&hdr[p], "data", 4) == 0) {
107
108 dataleft = n = le_int(&hdr[p + 4], 4);
109 p += 8;
110
111 /*
112 * Playback procedure
113 */
114 #define OUT_SAMPLE(s) { \
115 if (s > 32767) \
116 s = 32767; \
117 else if (s < -32768) \
118 s = -32768; \
119 outbuf[outp++] = s; \
120 n += 2; \
121 }
122
123 #define GETNIBBLE \
124 ((nib == 0) ? \
125 (buf[x + nib++] >> 4) & 0x0f : buf[x++ + --nib] & 0x0f)
126
127 outp = 0;
128
129 ppp = p;
130 while (dataleft > nBlockAlign) {
131 int predictor[2], delta[2], samp1[2], samp2[2];
132
133 int x = 0;
134
135 (void) memcpy(buf, &inbuf[ppp], nBlockAlign);
136 ppp += nBlockAlign;
137 dataleft -= nBlockAlign;
138
139 nib = 0;
140 n = 0;
141
142 for (i = 0; i < channels; i++) {
143 predictor[i] = buf[x];
144 x++;
145 }
146
147 for (i = 0; i < channels; i++) {
148 delta[i] = (short)le_int(&buf[x], 2);
149 x += 2;
150 }
151
152 for (i = 0; i < channels; i++) {
153 samp1[i] = (short)le_int(&buf[x], 2);
154 x += 2;
155 OUT_SAMPLE(samp1[i]);
156 }
157
158 for (i = 0; i < channels; i++) {
159 samp2[i] = (short)le_int(&buf[x], 2);
160 x += 2;
161 OUT_SAMPLE(samp2[i]);
162 }
163
164 while (n < (wSamplesPerBlock * 2 * channels))
165 for (i = 0; i < channels; i++) {
166 int pred, new, error_delta, i_delta;
167
168 pred = ((samp1[i] *
169 coeff[predictor[i]].coeff1)
170 + (samp2[i] *
171 coeff[predictor[i]].coeff2)) / 256;
172 i_delta = error_delta = GETNIBBLE;
173
174 /* Convert to signed */
175 if (i_delta & 0x08)
176 i_delta -= 0x10;
177
178 new = pred + (delta[i] * i_delta);
179 OUT_SAMPLE(new);
180
181 delta[i] = delta[i] *
182 AdaptionTable[error_delta] / 256;
183 if (delta[i] < 16)
184 delta[i] = 16;
185
186 samp2[i] = samp1[i];
187 samp1[i] = new;
188 }
189 }
190
191 }
192
193 return (outp * 2);
194 }
195