annotate adpcm.c @ 3763:81d84039dd17

fixed stereo IMA4 decoding
author melanson
date Wed, 26 Dec 2001 13:22:03 +0000
parents 734d0c0a8ab0
children 55603340d1b2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3756
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
1 /*
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
2 Unified ADPCM Decoder for MPlayer
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
3
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
4 (C) 2001 Mike Melanson
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
5 */
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
6
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
7 #include "config.h"
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
8 #include "bswap.h"
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
9 #include "adpcm.h"
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
10
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
11 #define BE_16(x) (be2me_16(*(unsigned short *)(x)))
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
12 #define BE_32(x) (be2me_32(*(unsigned int *)(x)))
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
13 #define LE_16(x) (le2me_16(*(unsigned short *)(x)))
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
14 #define LE_32(x) (le2me_32(*(unsigned int *)(x)))
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
15
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
16 // clamp a number between 0 and 88
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
17 #define CLAMP_0_TO_88(x) if (x < 0) x = 0; else if (x > 88) x = 88;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
18 // clamp a number within a signed 16-bit range
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
19 #define CLAMP_S16(x) if (x < -32768) x = -32768; \
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
20 else if (x > 32767) x = 32767;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
21 // sign extend a 16-bit value
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
22 #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
23
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
24 void ima_dvi_decode_nibbles(unsigned short *output, int channels,
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
25 int predictor_l, int index_l,
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
26 int predictor_r, int index_r)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
27 {
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
28 int step[2];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
29 int predictor[2];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
30 int index[2];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
31 int diff;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
32 int i;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
33 int sign;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
34 int delta;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
35 int channel_number = 0;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
36
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
37 step[0] = adpcm_step[index_l];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
38 step[1] = adpcm_step[index_r];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
39 predictor[0] = predictor_l;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
40 predictor[1] = predictor_r;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
41 index[0] = index_l;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
42 index[1] = index_r;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
43
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
44 for (i = 0; i < IMA_ADPCM_SAMPLES_PER_BLOCK * channels; i++)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
45 {
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
46 delta = output[i];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
47
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
48 index[channel_number] += adpcm_index[delta];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
49 CLAMP_0_TO_88(index[channel_number]);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
50
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
51 sign = delta & 8;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
52 delta = delta & 7;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
53
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
54 diff = step[channel_number] >> 3;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
55 if (delta & 4) diff += step[channel_number];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
56 if (delta & 2) diff += step[channel_number] >> 1;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
57 if (delta & 1) diff += step[channel_number] >> 2;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
58
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
59 if (sign)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
60 predictor[channel_number] -= diff;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
61 else
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
62 predictor[channel_number] += diff;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
63
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
64 CLAMP_S16(predictor[channel_number]);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
65 output[i] = predictor[channel_number];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
66 step[channel_number] = adpcm_step[index[channel_number]];
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
67
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
68 // toggle channel
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
69 channel_number ^= channels - 1;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
70 }
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
71 }
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
72
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
73 int ima_adpcm_decode_block(unsigned short *output, unsigned char *input,
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
74 int channels)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
75 {
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
76 int initial_predictor_l = 0;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
77 int initial_predictor_r = 0;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
78 int initial_index_l = 0;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
79 int initial_index_r = 0;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
80 int i;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
81
3763
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
82 initial_predictor_l = BE_16(&input[0]);
3756
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
83 initial_index_l = initial_predictor_l;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
84
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
85 // mask, sign-extend, and clamp the predictor portion
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
86 initial_predictor_l &= 0xFF80;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
87 SE_16BIT(initial_predictor_l);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
88 CLAMP_S16(initial_predictor_l);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
89
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
90 // mask and clamp the index portion
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
91 initial_index_l &= 0x7F;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
92 CLAMP_0_TO_88(initial_index_l);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
93
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
94 // handle stereo
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
95 if (channels > 1)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
96 {
3763
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
97 initial_predictor_r = BE_16(&input[IMA_ADPCM_BLOCK_SIZE]);
3756
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
98 initial_index_r = initial_predictor_r;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
99
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
100 // mask, sign-extend, and clamp the predictor portion
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
101 initial_predictor_r &= 0xFF80;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
102 SE_16BIT(initial_predictor_r);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
103 CLAMP_S16(initial_predictor_r);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
104
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
105 // mask and clamp the index portion
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
106 initial_index_r &= 0x7F;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
107 CLAMP_0_TO_88(initial_index_r);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
108 }
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
109
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
110 // break apart all of the nibbles in the block
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
111 if (channels == 1)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
112 for (i = 0; i < IMA_ADPCM_SAMPLES_PER_BLOCK / 2; i++)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
113 {
3763
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
114 output[i * 2 + 0] = input[2 + i] & 0x0F;
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
115 output[i * 2 + 1] = input[2 + i] >> 4;
3756
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
116 }
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
117 else
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
118 for (i = 0; i < IMA_ADPCM_SAMPLES_PER_BLOCK / 2 * 2; i++)
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
119 {
3763
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
120 output[i * 4 + 0] = input[2 + i] & 0x0F;
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
121 output[i * 4 + 1] = input[2 + IMA_ADPCM_BLOCK_SIZE + i] & 0x0F;
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
122 output[i * 4 + 2] = input[2 + i] >> 4;
81d84039dd17 fixed stereo IMA4 decoding
melanson
parents: 3756
diff changeset
123 output[i * 4 + 3] = input[2 + IMA_ADPCM_BLOCK_SIZE + i] >> 4;
3756
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
124 }
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
125
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
126 ima_dvi_decode_nibbles(output, channels,
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
127 initial_predictor_l, initial_index_l,
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
128 initial_predictor_r, initial_index_r);
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
129
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
130 return IMA_ADPCM_SAMPLES_PER_BLOCK * channels;
734d0c0a8ab0 Initial support for unified ADPCM decoder
melanson
parents:
diff changeset
131 }