Skip to content

Commit 92e9f4c

Browse files
committed
Audio: STFT Process: Add script to export configuration blob
This patch adds script to create configuration blobs for STFT process module. A few blobs are created to be used with topology to test STFT. This is WIP. The blob format is not yet final. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 2f92066 commit 92e9f4c

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
% setup_stft_process()
2+
%
3+
% Create binary configuration blob for STFT_PROCESS component. The hex data
4+
% is written to tools/topology/topology1/m4/stft_process/stft_process_config.m4
5+
6+
% SPDX-License-Identifier: BSD-3-Clause
7+
%
8+
% Copyright (c) 2025, Intel Corporation.
9+
10+
function setup_stft_process(cfg)
11+
12+
cfg.tools_path = '../../../../tools/';
13+
cfg.tplg_path = [cfg.tools_path 'topology/topology2/include/components/stft_process/'];
14+
cfg.common_path = [cfg.tools_path 'tune/common'];
15+
cfg.tplg_ver = 2;
16+
cfg.ipc_ver = 4;
17+
cfg.channel = 0;
18+
cfg.sample_frequency = 48000;
19+
20+
cfg.frame_length = 512; % 10.7 ms
21+
cfg.frame_shift = 128; % 2.7 ms
22+
cfg.window_type = 'hann';
23+
cfg.tplg_fn = 'hann_512_128.conf';
24+
export_stft_process_setup(cfg);
25+
26+
cfg.frame_length = 768; % 16 ms
27+
cfg.frame_shift = 120; % 2.5 ms
28+
cfg.window_type = 'hann';
29+
cfg.tplg_fn = 'hann_768_120.conf';
30+
export_stft_process_setup(cfg);
31+
32+
cfg.frame_length = 1024; % 21.3 ms
33+
cfg.frame_shift = 256; % 5.3 ms
34+
cfg.window_type = 'hann';
35+
cfg.tplg_fn = 'hann_1024_256.conf';
36+
export_stft_process_setup(cfg);
37+
38+
cfg.frame_length = 1536; % 32 ms
39+
cfg.frame_shift = 240; % 5 ms
40+
cfg.window_type = 'hann';
41+
cfg.tplg_fn = 'hann_1536_240.conf';
42+
export_stft_process_setup(cfg);
43+
44+
end
45+
46+
function export_stft_process_setup(cfg)
47+
48+
% Use blob tool from EQ
49+
addpath(cfg.common_path);
50+
51+
% Blob size, size plus reserved(8) + current parameters
52+
nbytes_data = 64;
53+
54+
% Get ABI information
55+
[abi_bytes, nbytes_abi] = sof_get_abi(nbytes_data, cfg.ipc_ver);
56+
57+
% Initialize correct size uint8 array
58+
nbytes = nbytes_abi + nbytes_data;
59+
b8 = uint8(zeros(1,nbytes));
60+
61+
% Insert ABI header
62+
fprintf(1, 'STFT_PROCESS blob size is %d, ABI header is %d, data is %d\n',nbytes, nbytes_abi, nbytes_data);
63+
b8(1:nbytes_abi) = abi_bytes;
64+
j = nbytes_abi + 1;
65+
66+
% Apply default STFT_PROCESS configuration, first struct header and reserved, then data
67+
[b8, j] = add_w32b(nbytes_data, b8, j);
68+
for i = 1:8
69+
[b8, j] = add_w32b(0, b8, j);
70+
end
71+
72+
fft_length = cfg.frame_length;
73+
fft_hop = cfg.frame_shift;
74+
[window_idx, window_gain_comp] = get_window(cfg, fft_length, fft_hop);
75+
76+
v = q_convert(cfg.sample_frequency, 0); [b8, j] = add_w32b(v, b8, j);
77+
v = q_convert(window_gain_comp, 31); [b8, j] = add_w32b(v, b8, j);
78+
v = 0; [b8, j] = add_w32b(v, b8, j); % reserved
79+
v = cfg.channel; [b8, j] = add_w16b(v, b8, j);
80+
v = fft_length; [b8, j] = add_w16b(v, b8, j);
81+
v = fft_hop; [b8, j] = add_w16b(v, b8, j);
82+
v = 0; [b8, j] = add_w16b(v, b8, j); % reserved
83+
v = 0; [b8, j] = add_w32b(v, b8, j); % enum pad
84+
v = window_idx; [b8, j] = add_w32b(v, b8, j); % enum window
85+
86+
% Export
87+
switch cfg.tplg_ver
88+
case 2
89+
sof_tplg2_write([cfg.tplg_path cfg.tplg_fn], b8, "stft_process_config", ...
90+
"Exported STFT_PROCESS configuration", ...
91+
"cd tools/tune/stft_process; octave setup_stft_process.m");
92+
otherwise
93+
error("Illegal cfg.tplg_ver, use 2 topology v2.");
94+
end
95+
96+
rmpath(cfg.common_path);
97+
98+
end
99+
100+
%% Helper functions
101+
102+
function [idx, iwg] = get_window(cfg, len, hop)
103+
switch lower(cfg.window_type)
104+
case 'rectangular'
105+
win = boxcar(len);
106+
idx = 0;
107+
case 'blackman'
108+
win = blackman(len);
109+
idx = 1;
110+
case 'hamming'
111+
win = hamming(len);
112+
idx = 2;
113+
case 'hann'
114+
win = hann(len);
115+
idx = 3;
116+
case 'povey'
117+
idx = 4;
118+
n = 0:(len-1);
119+
win = ((1 - cos(2 * pi * n / len)) / 2).^0.85;
120+
otherwise
121+
error('Unknown window type');
122+
end
123+
iwg = hop / sum(win.^2);
124+
end
125+
126+
function bytes = w8b(word)
127+
bytes = uint8(zeros(1,1));
128+
bytes(1) = bitand(word, 255);
129+
end
130+
131+
function bytes = w16b(word)
132+
sh = [0 -8];
133+
bytes = uint8(zeros(1,2));
134+
bytes(1) = bitand(bitshift(word, sh(1)), 255);
135+
bytes(2) = bitand(bitshift(word, sh(2)), 255);
136+
end
137+
138+
function bytes = w32b(word)
139+
sh = [0 -8 -16 -24];
140+
bytes = uint8(zeros(1,4));
141+
bytes(1) = bitand(bitshift(word, sh(1)), 255);
142+
bytes(2) = bitand(bitshift(word, sh(2)), 255);
143+
bytes(3) = bitand(bitshift(word, sh(3)), 255);
144+
bytes(4) = bitand(bitshift(word, sh(4)), 255);
145+
end
146+
147+
function n = q_convert(val, q)
148+
n = round(val * 2^q);
149+
end
150+
151+
function [blob8, j] = add_w8b(v, blob8, j)
152+
if j > length(blob8)
153+
error('Blob size is not sufficient');
154+
end
155+
blob8(j) = w8b(v);
156+
j = j + 1;
157+
end
158+
159+
function [blob8, j] = add_w16b(v, blob8, j)
160+
if j + 1 > length(blob8)
161+
error('Blob size is not sufficient');
162+
end
163+
if v < 0
164+
v = 2^16 + v;
165+
end
166+
blob8(j : j + 1) = w16b(v);
167+
j = j + 2;
168+
end
169+
170+
function [blob8, j] = add_w32b(v, blob8, j)
171+
if j + 3 > length(blob8)
172+
error('Blob size is not sufficient');
173+
end
174+
if v < 0
175+
v = 2^32 + v;
176+
end
177+
blob8(j : j + 3) = w32b(v);
178+
j = j + 4;
179+
end

0 commit comments

Comments
 (0)