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 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 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