blob: b01b29ddb06246281e7a41ebb8f7d195c69dd850 [file] [log] [blame]
function src_generate(fs_in, fs_out, ctype, fs_inout, profile, qc)
% src_generate - export src conversions for given fs_in and fs_out
%
% src_generate(fs_in, fs_out <, ctype, fs_inout>>)
%
% fs_in - vector of input sample rates (M)
% fs_out - vector of output sample rates (N)
% ctype - coefficient type, use 'int16','int24', 'int32', or 'float'
% fs_inout - matrix of supported conversions (MxN),
% 0 = no support, 1 = supported
% %
% if ctype is omitted then ctype defaults to 'int16'.
%
% If fs_inout matrix is omitted this script will compute coefficients
% for all fs_in <-> fs_out combinations.
%
% Copyright (c) 2016, Intel Corporation
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
% * Redistributions of source code must retain the above copyright
% notice, this list of conditions and the following disclaimer.
% * Redistributions in binary form must reproduce the above copyright
% notice, this list of conditions and the following disclaimer in the
% documentation and/or other materials provided with the distribution.
% * Neither the name of the Intel Corporation nor the
% names of its contributors may be used to endorse or promote products
% derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
%
% Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
%
if (nargin == 1) || (nargin > 6)
error('Incorrect arguments for function!');
end
if nargin == 0
%% Default input and output rates
fs_in = [8e3 11025 12e3 16e3 18900 22050 24e3 32e3 44100 48e3 ...
64e3 88.2e3 96e3 176400 192e3];
fs_out = [8e3 11025 12e3 16e3 18900 22050 24e3 32e3 44100 48e3];
fs_inout = [ 0 0 0 1 0 0 1 1 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
1 0 0 0 0 0 1 1 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
1 0 0 1 0 0 0 1 0 1 ; ...
1 0 0 1 0 0 1 0 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
1 1 1 1 0 1 1 1 1 0 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ; ...
0 0 0 0 0 0 0 0 0 1 ];
ctype = 'int32';
profile = 'std';
qc = 1.0;
else
if nargin < 3
ctype = 'int16';
end
if nargin < 4
fs_inout = ones(length(fs_in), length(fs_out));
end
if nargin < 5
profile = '';
end
if nargin < 6
qc = 1.0;
end
end
sio = size(fs_inout);
if (length(fs_in) ~= sio(1)) || (length(fs_out) ~= sio(2))
error('Sample rates in/out matrix size mismatch!');
end
%% Exported coefficients type int16, int24, int32, float
switch ctype
case 'int16'
coef_label = 'int16';
coef_ctype = 'int16_t';
coef_bits = 16;
coef_bytes = 2;
case 'int24'
coef_label = 'int24';
coef_ctype = 'int32_t';
coef_bits = 24;
coef_bytes = 4;
case 'int32'
coef_label = 'int32';
coef_ctype = 'int32_t';
coef_bits = 32;
coef_bytes = 4;
case 'float'
coef_label = 'float'; coef_ctype = 'float';
coef_bits = 24;
coef_bytes = 4;
otherwise
error('Request for incorrect coefficient type');
end
data_bytes = 4;
hdir = mkdir_check('include');
rdir = mkdir_check('reports');
%% Find fractional conversion factors
nfsi = length(fs_in);
nfso = length(fs_out);
l_2s = zeros(2, nfsi, nfso);
m_2s = zeros(2, nfsi, nfso);
mops_2s = zeros(2, nfsi, nfso);
pb_2s = zeros(2,nfsi, nfso);
sb_2s = zeros(2,nfsi, nfso);
taps_2s = zeros(2,nfsi, nfso);
defs.fir_delay_size = 0;
defs.out_delay_size = 0;
defs.blk_in = 0;
defs.blk_out = 0;
defs.num_in_fs = nfsi;
defs.num_out_fs = nfso;
defs.stage1_times_max = 0;
defs.stage2_times_max = 0;
defs.stage_buf_size = 0;
h = 1;
for b = 1:nfso
for a = 1:nfsi
fs1 = fs_in(a);
fs2 = fs_out(b);
[l1, m1, l2, m2] = src_factor2_lm(fs1, fs2);
fs3 = fs1*l1/m1;
cnv1 = src_param(fs1, fs3, coef_bits, qc);
cnv2 = src_param(fs3, fs2, coef_bits, qc);
if (fs2 < fs1)
% When decimating 1st stage passband can be limited
% for wider transition band
f_pb = fs2*cnv2.c_pb;
cnv1.c_pb = f_pb/min(fs1,fs3);
end
if (fs2 > fs1)
% When interpolating 2nd stage passband can be limited
% for wider transition band
f_pb = fs1*cnv1.c_pb;
cnv2.c_pb = f_pb/min(fs2,fs3);
end
if fs_inout(a,b) > 0 || (a == b)
if cnv2.fs1-cnv2.fs2 > eps
% Allow half ripple for dual stage SRC parts
cnv1.rp = cnv1.rp/2;
cnv2.rp = cnv2.rp/2;
end
src1 = src_get(cnv1);
src2 = src_get(cnv2);
k = gcd(src1.blk_out, src2.blk_in);
stage1_times = src2.blk_in/k;
stage2_times = stage1_times*src1.blk_out/src2.blk_in;
defs.stage1_times_max = max(defs.stage1_times_max, stage1_times);
defs.stage2_times_max = max(defs.stage2_times_max, stage2_times);
l_2s(:,a,b) = [src1.L src2.L];
m_2s(:,a,b) = [src1.M src2.M];
mops_2s(:,a,b) = [src1.MOPS src2.MOPS];
pb_2s(:,a,b) = [round(1e4*src1.c_pb) round(1e4*src2.c_pb)];
sb_2s(:,a,b) = [round(1e4*src1.c_sb) round(1e4*src2.c_sb)];
taps_2s(:,a,b) = [src1.filter_length src2.filter_length];
defs.fir_delay_size = max(defs.fir_delay_size, src1.fir_delay_size);
defs.out_delay_size = max(defs.out_delay_size, src1.out_delay_size);
defs.blk_in = max(defs.blk_in, src1.blk_in);
defs.blk_out = max(defs.blk_out, src1.blk_out);
defs.fir_delay_size = max(defs.fir_delay_size, src2.fir_delay_size);
defs.out_delay_size = max(defs.out_delay_size, src2.out_delay_size);
defs.blk_in = max(defs.blk_in, src2.blk_in);
defs.blk_out = max(defs.blk_out, src2.blk_out);
defs.stage_buf_size = max(defs.stage_buf_size, src1.blk_out*stage1_times);
src_export_coef(src1, coef_label, coef_ctype, hdir, profile);
src_export_coef(src2, coef_label, coef_ctype, hdir, profile);
end
end
end
%% Export modes table
defs.sum_filter_lengths = src_export_table_2s(fs_in, fs_out, l_2s, m_2s, ...
pb_2s, sb_2s, taps_2s, coef_label, coef_ctype, ...
'sof/audio/coefficients/src/', hdir, profile);
src_export_defines(defs, coef_label, hdir, profile);
%% Print 2 stage conversion factors
fn = sprintf('%s/src_2stage.txt', rdir);
fh = fopen(fn,'w');
fprintf(fh,'\n');
fprintf(fh,'Dual stage fractional SRC: Ratios\n');
fprintf(fh,'%8s, ', 'in \ out');
for b = 1:nfso
fprintf(fh,'%12.1f, ', fs_out(b)/1e3);
end
fprintf(fh,'\n');
for a = 1:nfsi
fprintf(fh,'%8.1f, ', fs_in(a)/1e3);
for b = 1:nfso
cstr = print_ratios(l_2s, m_2s, a, b);
fprintf(fh,'%12s, ', cstr);
end
fprintf(fh,'\n');
end
fprintf(fh,'\n');
%% Print 2 stage MOPS
fprintf(fh,'Dual stage fractional SRC: MOPS\n');
fprintf(fh,'%8s, ', 'in \ out');
for b = 1:nfso
fprintf(fh,'%8.1f, ', fs_out(b)/1e3);
end
fprintf(fh,'\n');
for a = 1:nfsi
fprintf(fh,'%8.1f, ', fs_in(a)/1e3);
for b = 1:nfso
mops = sum(mops_2s(:,a,b));
if sum(l_2s(:,a,b)) < eps
mops_str = 'x';
else
mops_str = sprintf('%.2f', mops);
end
fprintf(fh,'%8s, ', mops_str);
end
fprintf(fh,'\n');
end
fprintf(fh,'\n');
%% Print 2 stage MOPS per stage
fprintf(fh,'Dual stage fractional SRC: MOPS per stage\n');
fprintf(fh,'%10s, ', 'in \ out');
for b = 1:nfso
fprintf(fh,'%10.1f, ', fs_out(b)/1e3);
end
fprintf(fh,'\n');
for a = 1:nfsi
fprintf(fh,'%10.1f, ', fs_in(a)/1e3);
for b = 1:nfso
mops = mops_2s(:,a,b);
if sum(l_2s(:,a,b)) < eps
mops_str = 'x';
else
mops_str = sprintf('%.2f+%.2f', mops(1), mops(2));
end
fprintf(fh,'%10s, ', mops_str);
end
fprintf(fh,'\n');
end
fprintf(fh,'\n');
fprintf(fh,'Coefficient RAM %.1f kB\n', ...
defs.sum_filter_lengths*coef_bytes/1024);
fprintf(fh,'Max. data RAM %.1f kB\n', ...
(defs.fir_delay_size + defs.out_delay_size+defs.stage_buf_size) ...
* data_bytes/1024);
fprintf(fh,'\n');
fclose(fh);
type(fn);
end
function d = mkdir_check(d)
if exist(d) ~= 7
mkdir(d);
end
end
function cstr = print_ratios(l_2s, m_2s, a, b)
l1 = l_2s(1,a,b);
m1 = m_2s(1,a,b);
l2 = l_2s(2,a,b);
m2 = m_2s(2,a,b);
if l1+m2+l2+m2 == 0
cstr = 'x';
else
if m2 == 1
if l2 == 1
cstr2 = '';
else
cstr2 = sprintf('*%d', l2);
end
else
cstr2 = sprintf('*%d/%d', l2, m2);
end
if m1 == 1
cstr1 = sprintf('%d', l1);
else
cstr1 = sprintf('%d/%d', l1, m1);
end
cstr = sprintf('%s%s', cstr1, cstr2);
end
end