Skip to content

Commit 77a2213

Browse files
singalsulgirdwood
authored andcommitted
Test: Cmocka: Add test vector generator for A-law and mu-law
This patch adds Octave script to generate test data for A-law and mu-law coding. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 70a6006 commit 77a2213

File tree

2 files changed

+231
-2
lines changed

2 files changed

+231
-2
lines changed

test/cmocka/m/export_headerfile_open.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
% SPDX-License-Identifier: BSD-3-Clause
1111
%
12-
% Copyright(c) 2022 Intel Corporation. All rights reserved.
12+
% Copyright(c) 2022-2025 Intel Corporation.
1313

1414
function fh = export_headerfile_open(headerfn, corp)
1515

@@ -23,7 +23,7 @@
2323
end
2424
fprintf(fh, '/* SPDX-License-Identifier: BSD-3-Clause\n');
2525
fprintf(fh, ' *\n');
26-
fprintf(fh, ' * Copyright(c) %s %s. All rights reserved.\n', ...
26+
fprintf(fh, ' * Copyright(c) %s %s.\n', ...
2727
datestr(now, 'yyyy'), corp);
2828
fprintf(fh, ' */\n\n');
2929
end
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
% a_law_mu_law_test_vectors() - Create A-law and mu-law test vectors
2+
%
3+
% Running this script creates header files ref_chirp_mono_8k_s16.h,
4+
% a_law_codec.h, and mu_law_codec.h. The chirp waveform for test
5+
% input is created with sox, and then ended and decoded as
6+
% A-law and mu-law.
7+
8+
% SPDX-License-Identifier: BSD-3-Clause
9+
%
10+
% Copyright(c) 2025 Intel Corporation.
11+
12+
function a_law_mu_law_test_vectors()
13+
14+
sox = 0;
15+
alaw = 1;
16+
mulaw = 1;
17+
bits = 16;
18+
ts = 0.5;
19+
fs = 8e3;
20+
t = (0:round(ts*fs - 1))/fs;
21+
x = round(2^(bits - 1) * chirp(t, 100, ts, 3.5e3, 'logarithmic'));
22+
xmax = 2^(bits - 1) - 1;
23+
xmin = -2^(bits - 1);
24+
x = max(min(x, xmax), xmin);
25+
ref_s16_data = int16(x);
26+
27+
ref_s16_header_fn = 'ref_chirp_mono_8k_s16.h';
28+
ref_alaw_header_fn = 'a_law_codec.h';
29+
ref_mulaw_header_fn = 'mu_law_codec.h';
30+
31+
close all;
32+
path(path(), '../../../m');
33+
34+
if sox
35+
ref_s16 = '/tmp/chirp_mono_8k_s16.raw';
36+
ref_alaw_enc = '/tmp/ref_alaw_enc.raw';
37+
ref_alaw_dec = '/tmp/ref_alaw_dec.raw';
38+
ref_mulaw_enc = '/tmp/ref_mulaw_enc.raw';
39+
ref_mulaw_dec = '/tmp/ref_mulaw_dec.raw';
40+
sox_s16_chirp_gen = sprintf('sox -c 1 -r 8000 -b 16 --encoding signed-integer -n %s synth 0.5 sine 100-3500', ref_s16);
41+
sox_alaw_enc = sprintf('sox -c 1 -r 8000 -b 16 --encoding signed-integer %s --encoding a-law %s', ref_s16, ref_alaw_enc);
42+
sox_alaw_dec = sprintf('sox -c 1 -r 8000 --encoding a-law %s -b 16 --encoding signed-integer %s', ref_alaw_enc, ref_alaw_dec);
43+
sox_mulaw_enc = sprintf('sox -c 1 -r 8000 -b 16 --encoding signed-integer %s --encoding a-law %s', ref_s16, ref_mulaw_enc);
44+
sox_mulaw_dec = sprintf('sox -c 1 -r 8000 --encoding a-law %s -b 16 --encoding signed-integer %s', ref_mulaw_enc, ref_mulaw_dec);
45+
system(sox_s16_chirp_gen);
46+
system(sox_alaw_enc);
47+
system(sox_alaw_dec);
48+
system(sox_mulaw_enc);
49+
system(sox_mulaw_dec);
50+
ref_s16_data = readbin(ref_s16, 'int16'); figure;
51+
ref_alaw_enc_data = readbin(ref_alaw_enc, 'uint8');
52+
ref_alaw_dec_data = readbin(ref_alaw_dec, 'int16');
53+
ref_mulaw_enc_data = readbin(ref_mulaw_enc, 'uint8');
54+
ref_mulaw_dec_data = readbin(ref_mulaw_dec, 'int16');
55+
else
56+
if alaw
57+
ref_alaw_enc_data = alaw_enc(ref_s16_data);
58+
ref_alaw_dec_data = alaw_dec(ref_alaw_enc_data);
59+
end
60+
if mulaw
61+
ref_mulaw_enc_data = mulaw_enc(ref_s16_data);
62+
ref_mulaw_dec_data = mulaw_dec(ref_mulaw_enc_data);
63+
end
64+
end
65+
66+
if alaw
67+
plot(ref_s16_data); grid on; title('Input s16');
68+
figure; plot(ref_alaw_enc_data); grid on; title('A-law data');
69+
figure; plot(ref_alaw_dec_data); grid on; title('A-law decode s16');
70+
end
71+
72+
if mulaw
73+
figure; plot(ref_mulaw_enc_data); grid on; title('mu-law data');
74+
figure; plot(ref_mulaw_dec_data); grid on; title('mu-law decode s16');
75+
end
76+
77+
fh = export_headerfile_open(ref_s16_header_fn);
78+
comment = sprintf('Created %s with script a_law_mu_law_test_vectors.m %s', ...
79+
datestr(now, 0), export_get_git_describe());
80+
export_comment(fh, comment);
81+
fprintf(fh, '#include <stdint.h>\n');
82+
export_ndefine(fh, 'REF_DATA_SAMPLE_COUNT', length(ref_s16_data));
83+
export_vector(fh, 16, 'chirp_mono_8k_s16', ref_s16_data);
84+
fclose(fh);
85+
86+
if alaw
87+
fh = export_headerfile_open(ref_alaw_header_fn);
88+
comment = sprintf('Created %s with script a_law_mu_law_test_vectors.m %s', ...
89+
datestr(now, 0), export_get_git_describe());
90+
export_comment(fh, comment);
91+
fprintf(fh, '#include <stdint.h>\n');
92+
export_vector(fh, 8, 'ref_alaw_enc_data', ref_alaw_enc_data);
93+
export_vector(fh, 16, 'ref_alaw_dec_data', ref_alaw_dec_data);
94+
fclose(fh);
95+
end
96+
97+
if mulaw
98+
fh = export_headerfile_open(ref_mulaw_header_fn);
99+
comment = sprintf('Created %s with script a_law_mu_law_test_vectors.m %s', ...
100+
datestr(now, 0), export_get_git_describe());
101+
export_comment(fh, comment);
102+
fprintf(fh, '#include <stdint.h>\n');
103+
export_vector(fh, 8, 'ref_mulaw_enc_data', ref_mulaw_enc_data);
104+
export_vector(fh, 16, 'ref_mulaw_dec_data', ref_mulaw_dec_data);
105+
fclose(fh);
106+
end
107+
108+
end
109+
110+
function x = readbin(fn, itype)
111+
fh = fopen(fn, 'r');
112+
if fh == -1
113+
fprintf(1, 'Could not open file %s.\n', fn);
114+
error("Failed.");
115+
end
116+
x = fread(fh, inf, itype);
117+
fclose(fh);
118+
end
119+
120+
% See G.711 alaw compress from
121+
% https://www.itu.int/rec/T-REC-G.191/
122+
function encoded = alaw_enc(input_samples)
123+
num_samples = length(input_samples);
124+
in16 = int16(input_samples);
125+
encoded_samples = uint8(zeros(num_samples, 1));
126+
for n = 1:num_samples
127+
if in16(n) < 0
128+
ix = bitshift(-in16(n) -1, -4); % 1's complement
129+
else
130+
ix = bitshift(in16(n), -4);
131+
end
132+
133+
if ix > 15
134+
iexp = 1;
135+
while (ix > 16 + 15)
136+
ix = bitshift(ix, -1);
137+
iexp = iexp + 1;
138+
end
139+
140+
ix = ix - 16;
141+
ix = ix + bitshift(iexp, 4);
142+
end
143+
144+
if in16(n) >= 0
145+
ix = bitor(ix, 128);
146+
end
147+
148+
encoded(n) = bitxor(ix, 85);
149+
end
150+
end
151+
152+
% See G.711 alaw expand from
153+
% https://www.itu.int/rec/T-REC-G.191/
154+
function samples_s16 = alaw_dec(input_bytes)
155+
num_samples = length(input_bytes);
156+
samples_s16 = int16(zeros(num_samples, 1));
157+
for n = 1:num_samples
158+
ix = bitxor(int16(input_bytes(n)), 85);
159+
ix = bitand(ix, 127);
160+
iexp = bitshift(ix, -4);
161+
mant = bitand(ix, 15);
162+
if iexp > 0
163+
mant = mant + 16;
164+
end
165+
166+
mant = bitshift(mant, 4) + 8;
167+
if iexp > 1
168+
mant = bitshift(mant, iexp - 1);
169+
end
170+
171+
if input_bytes(n) > 127
172+
samples_s16(n) = mant;
173+
else
174+
samples_s16(n) = -mant;
175+
end
176+
end
177+
end
178+
179+
% See G.711 ulaw compress from
180+
% https://www.itu.int/rec/T-REC-G.191/
181+
function encoded = mulaw_enc(input_samples)
182+
num_samples = length(input_samples);
183+
in16 = int16(input_samples);
184+
encoded_samples = uint8(zeros(num_samples, 1));
185+
for n = 1:num_samples
186+
if in16(n) < 0
187+
absno = bitshift(-in16(n) -1, -2) + 33; % 1's complement
188+
else
189+
absno = bitshift(in16(n), -2) + 33;
190+
end
191+
192+
absno = min(absno, 8191);
193+
i = bitshift(absno, -6);
194+
segno = 1;
195+
while i > 0
196+
segno = segno + 1;
197+
i = bitshift(i, -1);
198+
end
199+
200+
high_nibble = 8 - segno;
201+
low_nibble = bitand(bitshift(absno, -segno), 15);
202+
low_nibble = 15 - low_nibble;
203+
encoded(n) = bitor(bitshift(high_nibble, 4), low_nibble);
204+
if in16(n) >= 0
205+
encoded(n) = bitor(encoded(n), 128);
206+
end
207+
end
208+
end
209+
210+
% See G.711 alaw expand from
211+
% https://www.itu.int/rec/T-REC-G.191/
212+
function samples_s16 = mulaw_dec(input_bytes)
213+
num_samples = length(input_bytes);
214+
samples_s16 = int16(zeros(num_samples, 1));
215+
for n = 1:num_samples
216+
if input_bytes(n) < 128
217+
sign = -1;
218+
else
219+
sign = 1;
220+
end
221+
222+
mantissa = -int16(input_bytes(n)) - 1; % 1's complement
223+
exponent = bitand(bitshift(mantissa, -4), 7);
224+
segment = exponent + 1;
225+
mantissa = bitand(mantissa, 15);
226+
step = bitshift(4, segment);
227+
samples_s16(n) = sign * (bitshift(128, exponent) + step * mantissa + step / 2 - 4 * 33);
228+
end
229+
end

0 commit comments

Comments
 (0)