1 |
2 |
motilito |
function out_pcm = ima_adpcm_enc(in_samp)
|
2 |
|
|
// This function encodes the input samples audio vector using IMA ADPCM algorithm. The
|
3 |
|
|
// input is assumed to be sampled using 16 bits per sample. The output vector is a
|
4 |
|
|
// compressed version of the input audio signal which requires only 4 bits per input
|
5 |
|
|
// sample.
|
6 |
|
|
// The function will scale the input vector to 16 bits per sample automatically if all
|
7 |
|
|
// values in the vector are in the range [-1:1].
|
8 |
|
|
//
|
9 |
|
|
// Author: Moti Litochevski
|
10 |
|
|
// Date: February 17, 2010
|
11 |
|
|
//
|
12 |
|
|
|
13 |
|
|
// check the input vector samples range
|
14 |
|
|
if (abs(in_samp) <= 1),
|
15 |
|
|
in_samp = round(in_samp * (2^15-1));
|
16 |
|
|
end
|
17 |
|
|
|
18 |
|
|
// step quantizer adaptation lookup table
|
19 |
|
|
STEP_LUT = [ ...
|
20 |
|
|
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, ...
|
21 |
|
|
37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, ...
|
22 |
|
|
173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, ...
|
23 |
|
|
658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, ...
|
24 |
|
|
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, ...
|
25 |
|
|
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, ...
|
26 |
|
|
20350, 22385, 24623, 27086, 29794, 32767];
|
27 |
|
|
// quantizer index adaptation lookup table
|
28 |
|
|
INDEX_LUT = [-1, -1, -1, -1, 2, 4, 6, 8];
|
29 |
|
|
|
30 |
|
|
// prepare output vector
|
31 |
|
|
out_pcm = zeros(length(in_samp), 4); // in binary format
|
32 |
|
|
|
33 |
|
|
// prepare loop variables
|
34 |
|
|
predictor_samp = zeros(1, length(in_samp)+1);
|
35 |
|
|
qstep_index = ones(1, length(in_samp)+1);
|
36 |
|
|
|
37 |
|
|
// compression loop
|
38 |
|
|
for idx = [1:length(in_samp)],
|
39 |
|
|
// subtract the previous sample form the current input sample
|
40 |
|
|
samp_diff = in_samp(idx)*8 - predictor_samp(idx);
|
41 |
|
|
|
42 |
|
|
// extract the current quantizer step size
|
43 |
|
|
qstep_size = STEP_LUT(qstep_index(idx));
|
44 |
|
|
|
45 |
|
|
// start difference quantization from the sign bit
|
46 |
|
|
out_pcm(idx, 1) = 1 * (samp_diff < 0);
|
47 |
|
|
samp_diff = abs(samp_diff);
|
48 |
|
|
|
49 |
|
|
// quantize the absolute value bit by bit
|
50 |
|
|
// the same process is used to calculate the de-quantizer output sample. note that the
|
51 |
|
|
// de-quantizer sample is started from the middle of the current step size (qstep_size/8).
|
52 |
|
|
dequant_samp = qstep_size;
|
53 |
|
|
// bit 2
|
54 |
|
|
out_pcm(idx, 2) = 1 * (samp_diff >= (qstep_size * 8));
|
55 |
|
|
samp_diff = samp_diff - out_pcm(idx, 2) * qstep_size * 8;
|
56 |
|
|
dequant_samp = dequant_samp + out_pcm(idx, 2) * qstep_size * 8;
|
57 |
|
|
// bit 1
|
58 |
|
|
out_pcm(idx, 3) = 1 * (samp_diff >= (qstep_size * 4));
|
59 |
|
|
samp_diff = samp_diff - out_pcm(idx, 3) * qstep_size * 4;
|
60 |
|
|
dequant_samp = dequant_samp + out_pcm(idx, 3) * qstep_size * 4;
|
61 |
|
|
// bit 0
|
62 |
|
|
out_pcm(idx, 4) = 1 * (samp_diff >= (qstep_size * 2));
|
63 |
|
|
dequant_samp = dequant_samp + out_pcm(idx, 4) * qstep_size * 2;
|
64 |
|
|
|
65 |
|
|
// update the predictor sample for the next iteration according to the sign bit
|
66 |
|
|
if (out_pcm(idx, 1)),
|
67 |
|
|
predictor_samp(idx+1) = predictor_samp(idx) - dequant_samp;
|
68 |
|
|
else
|
69 |
|
|
predictor_samp(idx+1) = predictor_samp(idx) + dequant_samp;
|
70 |
|
|
end
|
71 |
|
|
// check for predictor sample saturation condition
|
72 |
|
|
if (predictor_samp(idx+1) > (2^18-1)),
|
73 |
|
|
predictor_samp(idx+1) = 2^18 - 1;
|
74 |
|
|
elseif (predictor_samp(idx+1) < -2^18),
|
75 |
|
|
predictor_samp(idx + 1) = -2^18;
|
76 |
|
|
end
|
77 |
|
|
|
78 |
|
|
// update the step size index
|
79 |
|
|
pcm_val = out_pcm(idx, [2:4]) * [4, 2, 1]';
|
80 |
|
|
qstep_index(idx+1) = qstep_index(idx) + INDEX_LUT(pcm_val+1);
|
81 |
|
|
// check index saturation conditions
|
82 |
|
|
if (qstep_index(idx+1) < 1)
|
83 |
|
|
qstep_index(idx+1) = 1;
|
84 |
|
|
elseif (qstep_index(idx+1) > 89)
|
85 |
|
|
qstep_index(idx+1) = 89;
|
86 |
|
|
end
|
87 |
|
|
end
|
88 |
|
|
|
89 |
|
|
// convert the resulting compressed binary values to decimal
|
90 |
|
|
out_pcm = bi2de(out_pcm);
|
91 |
|
|
|
92 |
|
|
endfunction
|