Skip to content
This repository was archived by the owner on Jan 17, 2019. It is now read-only.

Commit b322168

Browse files
singalsulrgirdwo
authored andcommitted
SOFT: Add SRC coefficients generate tool
This patch adds the scripts src_std_int32.m and src_tiny_int16.m those were used to create the conversions matrices for the default and tiny profiles. The scripts call the included src_generate function that does the task with help from the filter design and coefficients export utilities. The quality and resources consumption of SRC can be customized with this tool. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 5a59eca commit b322168

12 files changed

Lines changed: 1497 additions & 0 deletions

tune/src/README

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Sample rate converter (SRC) Setup Tools
2+
=======================================
3+
4+
This is a tool to set up SRC conversions sample rates list, define
5+
quality related parameters, and test the C implementation for a number
6+
of objective audio quality parameters.
7+
8+
The tools need GNU Octave version 4.0.0 or later with octave-signal
9+
package.
10+
11+
src_std_int32.m
12+
---------------
13+
14+
This script creates the default coefficient set and contains nothing
15+
else but call for src_generate.
16+
17+
src_tiny_int16.m
18+
----------------
19+
20+
This script creates the tiny coefficient set. The script contains an
21+
example how to customize the input/output rates matrix and in a simple
22+
way the scale conversions quality. More controlled quality adjust can
23+
be done by editing file src_param.m directly. Note that int16
24+
presentation for SRC coefficients will degrade even the default
25+
quality.
26+
27+
src_generate.m
28+
--------------
29+
30+
Creates the header files to include to C into directory "include". A
31+
report of create modes is written to directory "reports". The
32+
coefficients need to be copied to directory
33+
sof.git/src/include/sof/audio/coefficients/src.
34+
35+
The default quality of SRC is defined in module src_param.m. The
36+
quality impacts the complexity and coefficents tables size of SRC.

tune/src/src_export_coef.m

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
function success=src_export_coef(src, ctype, vtype, hdir, profile)
2+
3+
% src_export_coef - Export FIR coefficients
4+
%
5+
% success=src_export_coef(src, ctype, hdir, profile)
6+
%
7+
% src - src definition struct
8+
% ctype - 'float','int32', or 'int24'
9+
% vtype - 'float','int32_t'
10+
% hdir - directory for header files
11+
% profile - string to append to filename
12+
%
13+
14+
% Copyright (c) 2016, Intel Corporation
15+
% All rights reserved.
16+
%
17+
% Redistribution and use in source and binary forms, with or without
18+
% modification, are permitted provided that the following conditions are met:
19+
% * Redistributions of source code must retain the above copyright
20+
% notice, this list of conditions and the following disclaimer.
21+
% * Redistributions in binary form must reproduce the above copyright
22+
% notice, this list of conditions and the following disclaimer in the
23+
% documentation and/or other materials provided with the distribution.
24+
% * Neither the name of the Intel Corporation nor the
25+
% names of its contributors may be used to endorse or promote products
26+
% derived from this software without specific prior written permission.
27+
%
28+
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29+
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30+
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31+
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32+
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33+
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34+
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35+
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36+
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37+
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38+
% POSSIBILITY OF SUCH DAMAGE.
39+
%
40+
% Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
41+
%
42+
43+
if nargin < 5
44+
profile = '';
45+
end
46+
47+
if src.L == src.M
48+
success = 0;
49+
else
50+
pbi = round(src.c_pb*1e4);
51+
sbi = round(src.c_sb*1e4);
52+
if isempty(profile)
53+
hfn = sprintf('%s/src_%s_%d_%d_%d_%d.h', ...
54+
hdir, ctype, src.L, src.M, pbi, sbi);
55+
else
56+
hfn = sprintf('%s/src_%s_%s_%d_%d_%d_%d.h', ...
57+
hdir, profile, ctype, src.L, src.M, pbi, sbi);
58+
end
59+
vfn = sprintf('src_%s_%d_%d_%d_%d_fir', ctype, src.L, src.M, pbi, sbi);
60+
sfn = sprintf('src_%s_%d_%d_%d_%d', ctype, src.L, src.M, pbi, sbi);
61+
62+
fprintf('Exporting %s ...\n', hfn);
63+
fh = fopen(hfn, 'w');
64+
65+
switch ctype
66+
case 'float'
67+
fprintf(fh, 'const %s %s[%d] = {\n', ...
68+
vtype, vfn, src.filter_length);
69+
fprintf(fh,'\t%16.9e', src.coefs(1));
70+
for n=2:src.filter_length
71+
fprintf(fh, ',\n');
72+
fprintf(fh,'\t%16.9e', src.coefs(n));
73+
end
74+
fprintf(fh,'\n\n};');
75+
case 'int32'
76+
print_int_coef(src, fh, vtype, vfn, 32);
77+
case 'int24'
78+
print_int_coef(src, fh, vtype, vfn, 24);
79+
case 'int16'
80+
print_int_coef(src, fh, vtype, vfn, 16);
81+
otherwise
82+
error('Unknown type %s !!!', ctype);
83+
end
84+
85+
fprintf(fh, '\n');
86+
switch ctype
87+
case 'float'
88+
fprintf(fh, 'struct src_stage %s = {\n', sfn);
89+
fprintf(fh, '\t%d, %d, %d, %d, %d, %d, %d, %d, %f,\n\t%s};\n', ...
90+
src.idm, src.odm, src.num_of_subfilters, ...
91+
src.subfilter_length, src.filter_length, ...
92+
src.blk_in, src.blk_out, src.halfband, ...
93+
src.gain, vfn);
94+
case { 'int16' 'int24' 'int32' }
95+
fprintf(fh, 'struct src_stage %s = {\n', sfn);
96+
fprintf(fh, '\t%d, %d, %d, %d, %d, %d, %d, %d, %d,\n\t%s};\n', ...
97+
src.idm, src.odm, src.num_of_subfilters, ...
98+
src.subfilter_length, src.filter_length, ...
99+
src.blk_in, src.blk_out, src.halfband, ...
100+
src.shift, vfn);
101+
otherwise
102+
error('Unknown type %s !!!', ctype);
103+
end
104+
%fprintf(fh, '\n');
105+
fclose(fh);
106+
success = 1;
107+
end
108+
109+
end
110+
111+
function print_int_coef(src, fh, vtype, vfn, nbits)
112+
fprintf(fh, 'const %s %s[%d] = {\n', ...
113+
vtype, vfn, src.filter_length);
114+
115+
cint = coef_quant(src, nbits);
116+
fprintf(fh,'\t%d', cint(1));
117+
for n=2:src.filter_length
118+
fprintf(fh, ',\n');
119+
fprintf(fh,'\t%d', cint(n));
120+
end
121+
fprintf(fh,'\n\n};');
122+
end
123+
124+
function cint = coef_quant(src, nbits)
125+
126+
sref = 2^(nbits-1);
127+
pmax = sref-1;
128+
nmin = -sref;
129+
130+
if nbits > 16
131+
%% Round() is OK
132+
cint0 = round(sref*src.coefs);
133+
else
134+
%% Prepare to optimize coefficient quantization
135+
fs = max(src.fs1, src.fs2);
136+
f = linspace(0, fs/2, 1000);
137+
138+
%% Test sensitivity for stopband and find the most sensitive
139+
% coefficients
140+
sbf = linspace(src.f_sb,fs/2, 500);
141+
n = src.filter_length;
142+
psens = zeros(1,n);
143+
bq0 = round(sref*src.coefs);
144+
h = freqz(bq0/sref/src.L, 1, sbf, fs);
145+
sb1 = 20*log10(sqrt(sum(h.*conj(h))));
146+
for i=1:n
147+
bq = src.coefs;
148+
bq(i) = round(sref*bq(i))/sref;
149+
%tbq = bq; %tbq(i) = bq(i)+1;
150+
h = freqz(bq, 1, sbf, fs);
151+
psens(i) = sum(h.*conj(h));
152+
end
153+
[spsens, pidx] = sort(psens, 'descend');
154+
155+
%% Test quantization in the found order
156+
% The impact to passband is minimal so it's not tested
157+
bi = round(sref*src.coefs);
158+
bi0 = bi;
159+
dl = -1:1;
160+
nd = length(dl);
161+
msb = zeros(1,nd);
162+
for i=pidx
163+
bit = bi;
164+
for j=1:nd
165+
bit(i) = bi(i) + dl(j);
166+
h = freqz(bit, 1, sbf, fs);
167+
msb(j) = sum(h.*conj(h));
168+
end
169+
idx = find(msb == min(msb), 1, 'first');
170+
bi(i) = bi(i) + dl(idx);
171+
end
172+
h = freqz(bi/sref/src.L, 1, sbf, fs);
173+
sb2 = 20*log10(sqrt(sum(h.*conj(h))));
174+
175+
%% Plot to compare
176+
if 0
177+
f = linspace(0, fs/2, 1000);
178+
h1 = freqz(src.coefs/src.L, 1, f, fs);
179+
h2 = freqz(bq0/sref/src.L, 1, f, fs);
180+
h3 = freqz(bi/sref/src.L, 1, f, fs);
181+
figure;
182+
plot(f, 20*log10(abs(h1)), f, 20*log10(abs(h2)), f, 20*log10(abs(h3)));
183+
grid on;
184+
fprintf('Original = %4.1f dB, optimized = %4.1f dB, delta = %4.1f dB\n', ...
185+
sb1, sb2, sb1-sb2);
186+
end
187+
cint0 = bi;
188+
end
189+
190+
191+
%% Re-order coefficients for filter implementation
192+
cint = zeros(src.filter_length,1);
193+
for n = 1:src.num_of_subfilters
194+
i11 = (n-1)*src.subfilter_length+1;
195+
i12 = i11+src.subfilter_length-1;
196+
cint(i11:i12) = cint0(n:src.num_of_subfilters:end);
197+
end
198+
199+
%% Done check for no overflow
200+
max_fix = max(cint);
201+
min_fix = min(cint);
202+
if (max_fix > pmax)
203+
printf('Fixed point coefficient %d exceeded %d\n.', max_fix, pmax);
204+
error('Something went wrong!');
205+
end
206+
if (min_fix < nmin)
207+
printf('Fixed point coefficient %d exceeded %d\n.', min_fix, nmax);
208+
error('Something went wrong!');
209+
end
210+
211+
212+
end

tune/src/src_export_defines.m

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
function src_export_defines(defs, ctype, hdir, profile)
2+
3+
% src_export_defines - Exports the constants to header files
4+
%
5+
% src_export_defines(defs, ctype, hdir)
6+
%
7+
% defs - defs struct
8+
% ctype - e.g. 'int24' appended to file name
9+
% hdir - directory for header file
10+
% profile - string to append to file name
11+
%
12+
13+
14+
% Copyright (c) 2016, Intel Corporation
15+
% All rights reserved.
16+
%
17+
% Redistribution and use in source and binary forms, with or without
18+
% modification, are permitted provided that the following conditions are met:
19+
% * Redistributions of source code must retain the above copyright
20+
% notice, this list of conditions and the following disclaimer.
21+
% * Redistributions in binary form must reproduce the above copyright
22+
% notice, this list of conditions and the following disclaimer in the
23+
% documentation and/or other materials provided with the distribution.
24+
% * Neither the name of the Intel Corporation nor the
25+
% names of its contributors may be used to endorse or promote products
26+
% derived from this software without specific prior written permission.
27+
%
28+
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29+
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30+
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31+
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32+
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33+
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34+
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35+
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36+
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37+
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38+
% POSSIBILITY OF SUCH DAMAGE.
39+
%
40+
% Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
41+
%
42+
43+
if nargin < 4
44+
profile = '';
45+
end
46+
47+
if isempty(profile)
48+
hfn = sprintf('src_%s_define.h', ctype);
49+
else
50+
hfn = sprintf('src_%s_%s_define.h', profile, ctype);
51+
end
52+
fh = fopen(fullfile(hdir,hfn), 'w');
53+
fprintf(fh, '/* SRC constants */\n');
54+
fprintf(fh, '#define MAX_FIR_DELAY_SIZE %d\n', defs.fir_delay_size);
55+
fprintf(fh, '#define MAX_OUT_DELAY_SIZE %d\n', defs.out_delay_size);
56+
fprintf(fh, '#define MAX_BLK_IN %d\n', defs.blk_in);
57+
fprintf(fh, '#define MAX_BLK_OUT %d\n', defs.blk_out);
58+
fprintf(fh, '#define NUM_IN_FS %d\n', defs.num_in_fs);
59+
fprintf(fh, '#define NUM_OUT_FS %d\n', defs.num_out_fs);
60+
fprintf(fh, '#define STAGE1_TIMES_MAX %d\n', defs.stage1_times_max);
61+
fprintf(fh, '#define STAGE2_TIMES_MAX %d\n', defs.stage2_times_max);
62+
fprintf(fh, '#define STAGE_BUF_SIZE %d\n', defs.stage_buf_size);
63+
fprintf(fh, '#define NUM_ALL_COEFFICIENTS %d\n', defs.sum_filter_lengths);
64+
fclose(fh);
65+
66+
end

0 commit comments

Comments
 (0)