revert between 56095 -> 55830 in arch
[AROS.git] / workbench / classes / datatypes / wav / wave_ms_adpcm.c
blob4eee66cfaebece272ed6ee9e4b96fa6507fd507b
1 /*
2 * wave.datatype
3 * (c) Fredrik Wikstrom
4 */
6 // M$ ADPCM format
8 #include "wave_ms_adpcm.h"
9 #include "bitpack.h"
10 #include "endian.h"
12 #ifdef __GNUC__
13 #ifdef __PPC__
14 #pragma pack(2)
15 #endif
16 #elif defined(__VBCC__)
17 #pragma amiga-align
18 #endif
20 struct coefset {
21 WORD coef1;
22 WORD coef2;
25 struct MS_ADPCM_Format {
26 UWORD formatTag;
27 WORD numChannels;
28 LONG samplesPerSec;
29 LONG avgBytesPerSec;
30 WORD blockAlign; /* amount to read for each block */
31 WORD bitsPerSample; /* 4 */
33 WORD extraSize; /* 4+4*numCoefs */
34 WORD samplesPerBlock;
35 WORD numCoefs; // number of coef sets in file
36 struct coefset aCoef[]; // numCoef coef sets
39 #ifdef __GNUC__
40 #ifdef __PPC__
41 #pragma pack()
42 #endif
43 #elif defined(__VBCC__)
44 #pragma default-align
45 #endif
47 // Note: Coefs are fixed point 8.8 signed numbers.
49 /* block header:
51 * struct MS_ADPCM_Block {
52 * BYTE bpredictor[nchannels];
53 * WORD newdelta[nchannels];
54 * WORD isamp1[nchannels];
55 * WORD isamp2[nchannels];
56 * };
59 DEC_SETUPPROTO(SetupMS_ADPCM) {
60 struct MS_ADPCM_Format * fmt;
61 LONG i;
62 fmt = (struct MS_ADPCM_Format *)data->fmt;
64 if (fmt->bitsPerSample != 4)
65 return DTERROR_UNKNOWN_COMPRESSION;
66 fmt->numCoefs = read_le16(&fmt->numCoefs);
67 if (4 + (fmt->numCoefs << 2) == data->chunk.size)
68 return NOTOK;
69 /* change endianness of coefsets */
70 for (i = 0; i < fmt->numCoefs; i++) {
71 fmt->aCoef[i].coef1 = (WORD)read_le16(&fmt->aCoef[i].coef1);
72 fmt->aCoef[i].coef2 = (WORD)read_le16(&fmt->aCoef[i].coef2);
74 data->blockFrames = fmt->samplesPerBlock = read_le16(&fmt->samplesPerBlock);
75 return OK;
78 static const WORD adaptiontable[16] = {
79 230, 230, 230, 230, 307, 409, 512, 614,
80 768, 614, 512, 409, 307, 230, 230, 230
83 struct ms_adpcm_stat {
84 LONG nstep;
85 LONG samp1, samp2;
86 LONG coef1, coef2;
89 static LONG DecodeAdpcmSample (struct ms_adpcm_stat * stat, LONG err) {
90 LONG step, nsamp;
91 step = stat->nstep;
92 stat->nstep = (adaptiontable[err] * step) >> 8;
93 if (stat->nstep < 16) stat->nstep = 16;
94 if (err & 8) err -= 16;
95 nsamp = ((stat->samp1 * stat->coef1) + (stat->samp2 * stat->coef2)) >> 8;
96 nsamp += (err * step);
97 if (nsamp > 0x7FFF) nsamp = 0x7FFF;
98 if (nsamp < -0x8000) nsamp = -0x8000;
99 stat->samp2 = stat->samp1;
100 stat->samp1 = nsamp;
101 return nsamp;
104 DECODERPROTO(DecodeMS_ADPCM) {
105 struct ms_adpcm_stat stat[MAX_CHANNELS];
106 struct MS_ADPCM_Format *fmt_ext;
108 LONG numChan;
109 LONG numSamp, s, ch;
111 fmt_ext=(struct MS_ADPCM_Format *)fmt;
112 numChan = fmt_ext->numChannels;
114 for (ch = 0; ch < numChan; ch++) {
115 LONG bpred;
116 bpred = *(UBYTE *)Src; Src++;
117 if (bpred >= fmt_ext->numCoefs) bpred = 0;
118 stat[ch].coef1 = fmt_ext->aCoef[bpred].coef1;
119 stat[ch].coef2 = fmt_ext->aCoef[bpred].coef2;
121 for (ch = 0; ch < numChan; ch++) {
122 stat[ch].nstep = (WORD)read_le16(Src); Src+=2;
124 for (ch = 0; ch < numChan; ch++) {
125 stat[ch].samp1 = (WORD)read_le16(Src); Src+=2;
127 for (ch = 0; ch < numChan; ch++) {
128 stat[ch].samp2 = (WORD)read_le16(Src); Src+=2;
129 switch (numFrames) {
130 default:
131 Dst[ch][1] = stat[ch].samp1 >> 8;
132 case 1:
133 Dst[ch][0] = stat[ch].samp2 >> 8;
134 case 0:
135 break;
137 Dst[ch]+=2;
140 if (numFrames <= 2) return numFrames;
141 numSamp = (numFrames-2) * numChan;
142 ch = 0;
144 LONG tmp = numSamp >> 1;
145 for (s = 0; s < tmp; s++) {
146 *Dst[ch]++ = DecodeAdpcmSample(&stat[ch], *Src >> 4) >> 8;
147 if (++ch == numChan) ch = 0;
148 *Dst[ch]++ = DecodeAdpcmSample(&stat[ch], *Src & 0xF) >> 8;
149 if (++ch == numChan) ch = 0;
150 Src++;
153 if (numSamp & 1) {
154 *Dst[ch]++ = DecodeAdpcmSample(&stat[ch], *Src >> 4) >> 8;
157 return numFrames;