Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tools: Tune: TDFB: Add generate of few needed blobs #9147

Merged
merged 3 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/audio/tdfb/tune/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Settings blobs generators for TDFB

This directory contains the scripts to generate settings blobs for
the time-domain fixed beamformer (TDFB) for various microphone array
geometries and beamformer features.

The requirement is Octave or Matlab with signal processing package.

The most straightforward way to generate all blobs for topologies,
sof-ctl and UCM is to run command

```
./sof_example_all.sh
```

It creates the blobs for passthrough mode, single beam blobs for
line and circular arrays, and dual beam blobs for stereo audio
capture. Running it can take about 30 minutes.

All the topology ASCII text format blobs contain instructions
how to generate them from command line shell. E.g. these
commands do a more fine grained build.

```
cd $SOF_WORKSPACE/sof

# Generate pass-through blobs
cd tools/tune/tdfb; octave --no-window-system example_pass_config.m

# Generate blobs for line array and single beam
cd tools/tune/tdfb; octave --no-window-system example_line_array.m

# Generate blobs for stereo capture for arrays with known mm-spacing
cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams

# Generate bobs for stereo capture for generic arrays with known microphones count
cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams_default
```

Further information about TDFB component is available in SOF Docs, see
https://thesofproject.github.io/latest/algos/tdfb/time_domain_fixed_beamformer.html
2 changes: 2 additions & 0 deletions src/audio/tdfb/tune/sof_bf_defaults.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
bf.array_angle = [0 0 0]; % Array rotation angles for xyz
bf.tplg_fn = '';
bf.sofctl_fn = '';
bf.ucmbin3_fn = '';
bf.ucmbin4_fn = '';
sof_tools = '../../../../tools';
bf.tplg1_path = fullfile(sof_tools, 'topology/topology1/m4/tdfb');
bf.tplg2_path = fullfile(sof_tools, 'topology/topology2/include/components/tdfb');
Expand Down
14 changes: 14 additions & 0 deletions src/audio/tdfb/tune/sof_bf_export.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
% Inputs
% bf.sofctl3_fn .... filename of ascii text format blob
% bf.sofctl4_fn .... filename of ascii text format blob
% bf.ucmbin3_fn .... filename of binary format blob for UCM (IPC3)
% bf.ucmbin4_fn .... filename of binary format blob for UCM (IPC4)
% bf.tplg1_fn ...... filename of topology m4 format blob
% bf.tplg2_fn ...... filename of topology m4 format blob
% bf ............... the design procedure output
Expand Down Expand Up @@ -116,6 +118,18 @@
tplg2_write(bf.tplg2_fn, bp4, "tdfb_config", export_note, bf.export_howto);
end

if ~isempty(bf.ucmbin3_fn)
fprintf(1, 'Exporting to %s\n', bf.ucmbin3_fn);
mkdir_check(bf.sofctl3_path);
sof_ucm_blob_write(bf.ucmbin3_fn, bp3);
end

if ~isempty(bf.ucmbin4_fn)
fprintf(1, 'Exporting to %s\n', bf.ucmbin4_fn);
mkdir_check(bf.sofctl4_path);
sof_ucm_blob_write(bf.ucmbin4_fn, bp4);
end

sof_bf_paths(false);

end
2 changes: 2 additions & 0 deletions src/audio/tdfb/tune/sof_bf_filenames_helper.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
bf.sofctl3_fn = fullfile(bf.sofctl3_path, sprintf('coef_%s.txt', idstr));
bf.tplg1_fn = fullfile(bf.tplg1_path, sprintf('coef_%s.m4', idstr));
bf.sofctl4_fn = fullfile(bf.sofctl4_path, sprintf('%s.txt', idstr));
bf.ucmbin3_fn = fullfile(bf.sofctl3_path, sprintf('%s.bin', idstr));
bf.ucmbin4_fn = fullfile(bf.sofctl4_path, sprintf('%s.bin', idstr));
bf.tplg2_fn = fullfile(bf.tplg2_path, sprintf('%s.conf', idstr));


Expand Down
75 changes: 75 additions & 0 deletions src/audio/tdfb/tune/sof_bf_line2_two_beams.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
function sof_bf_line2_two_beams(fs, d, a1, a2, fn, prm)

% sof_bf_line2_two_beams(fs, d, a1, a2, fn, prm)
% Input
% fs - sample rate
% d - microphones distance in meters
% a1 - steer angle beam 1
% a2 - steer angle beam 2
% fn - struct with exported blob files names
% prm
% .add_beam_beam_off - controls addition of beam off definition to blob
% .type - Use 'SDB' or 'DSB'
% .export_note - comment about build generally
% .export_howto - detailed build instruction
%

% SPDX-License-Identifier: BSD-3-Clause
%
% Copyright (c) 2020-2024, Intel Corporation.
%
% Author: Seppo Ingalsuo <[email protected]>

% Get defaults
bf1 = sof_bf_defaults();
bf1.fs = fs;

% Setup array
bf1.array='line'; % Calculate xyz coordinates for line
bf1.mic_n = 2;
bf1.mic_d = d;
bf1.beam_off_defined = prm.add_beam_off;
bf1.type = prm.type;

% Copy settings for bf2
bf2 = bf1;

% Design beamformer 1 (left)
bf1.steer_az = a1;
bf1.steer_el = 0 * a1;
bf1.input_channel_select = [0 1]; % Input two channels
bf1.output_channel_mix = [1 1]; % Mix both filters to channel 2^0
bf1.output_channel_mix_beam_off = [1 2]; % Filter 1 to channel 2^0, etc.
bf1.output_stream_mix = [0 0]; % Mix both filters to stream 0
bf1.num_output_channels = 2;
bf1.fn = 10; % Figs 10....
bf1 = sof_bf_filenames_helper(bf1);
bf1 = sof_bf_design(bf1);

% Design beamformer 2 (right)
bf2.steer_az = a2;
bf2.steer_el = 0 * a2;
bf2.input_channel_select = [0 1]; % Input two channels
bf2.output_channel_mix = [2 2]; % Mix both filters to channel 2^1
bf2.output_channel_mix_beam_off = [0 0]; % Filters omitted
bf2.output_stream_mix = [0 0]; % Mix both filters to stream 0
bf2.num_output_channels = 2;
bf2.fn = 20; % Figs 20....
bf2 = sof_bf_filenames_helper(bf2);
bf2 = sof_bf_design(bf2);

% Merge two beamformers into single description, set file names
bfm = sof_bf_merge(bf1, bf2);
bfm.sofctl3_fn = fullfile(bfm.sofctl3_path, fn.sofctl3_fn);
bfm.tplg1_fn = fullfile(bfm.tplg1_path, fn.tplg1_fn);
bfm.sofctl4_fn = fullfile(bfm.sofctl4_path, fn.sofctl4_fn);
bfm.ucmbin3_fn = fullfile(bfm.sofctl3_path, fn.ucmbin3_fn);
bfm.ucmbin4_fn = fullfile(bfm.sofctl4_path, fn.ucmbin4_fn);
bfm.tplg2_fn = fullfile(bfm.tplg2_path, fn.tplg2_fn);

% Export files for topology and sof-ctl
bfm.export_note = prm.export_note;
bfm.export_howto = prm.export_howto;
sof_bf_export(bfm);

end
75 changes: 75 additions & 0 deletions src/audio/tdfb/tune/sof_bf_line4_two_beams.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
function sof_bf_line4_two_beams(fs, d, a1, a2, fn, prm)

% sof_bf_line4_two_beams(fs, d, a1, a2, fn, prm)
% Input
% fs - sample rate
% d - microphones distance in meters
% a1 - steer angle beam 1
% a2 - steer angle beam 2
% fn - struct with exported blob files names
% prm
% .add_beam_beam_off - controls addition of beam off definition to blob
% .type - Use 'SDB' or 'DSB'
% .export_note - comment about build generally
% .export_howto - detailed build instruction
%

% SPDX-License-Identifier: BSD-3-Clause
%
% Copyright (c) 2020-2024, Intel Corporation. All rights reserved.
%
% Author: Seppo Ingalsuo <[email protected]>

% Get defaults
bf1 = sof_bf_defaults();
bf1.fs = fs;

% Setup array
bf1.array='line'; % Calculate xyz coordinates for line
bf1.mic_n = 4;
bf1.mic_d = d;
bf1.beam_off_defined = prm.add_beam_off;
bf1.type = prm.type;

% Copy settings for bf2
bf2 = bf1;

% Design beamformer 1 (left)
bf1.steer_az = a1;
bf1.steer_el = 0 * a1;
bf1.input_channel_select = [0 1 2 3]; % Input four channels
bf1.output_channel_mix = [1 1 1 1]; % Mix filters to channel 2^0
bf1.output_channel_mix_beam_off = [1 0 0 2]; % Filter 1 to channel 2^0, filter 4 to channel 2^1
bf1.output_stream_mix = [0 0 0 0]; % Mix filters to stream 0
bf1.num_output_channels = 2;
bf1.fn = 10; % Figs 10....
bf1 = sof_bf_filenames_helper(bf1);
bf1 = sof_bf_design(bf1);

% Design beamformer 2 (right)
bf2.steer_az = a2;
bf2.steer_el = 0 * a2;
bf2.input_channel_select = [0 1 2 3]; % Input two channels
bf2.output_channel_mix = [2 2 2 2]; % Mix filters to channel 2^1
bf2.output_channel_mix_beam_off = [0 0 0 0]; % Filters omitted
bf2.output_stream_mix = [0 0 0 0]; % Mix filters to stream 0
bf2.num_output_channels = 2;
bf2.fn = 20; % Figs 20....
bf2 = sof_bf_filenames_helper(bf2);
bf2 = sof_bf_design(bf2);

% Merge two beamformers into single description, set file names
bfm = sof_bf_merge(bf1, bf2);
bfm.sofctl3_fn = fullfile(bfm.sofctl3_path, fn.sofctl3_fn);
bfm.tplg1_fn = fullfile(bfm.tplg1_path, fn.tplg1_fn);
bfm.sofctl4_fn = fullfile(bfm.sofctl4_path, fn.sofctl4_fn);
bfm.ucmbin3_fn = fullfile(bfm.sofctl3_path, fn.ucmbin3_fn);
bfm.ucmbin4_fn = fullfile(bfm.sofctl4_path, fn.ucmbin4_fn);
bfm.tplg2_fn = fullfile(bfm.tplg2_path, fn.tplg2_fn);

% Export files for topology and sof-ctl
bfm.export_note = prm.export_note;
bfm.export_howto = prm.export_howto;
sof_bf_export(bfm);

end
5 changes: 3 additions & 2 deletions src/audio/tdfb/tune/sof_example_all.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#!/bin/bash

# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2022 Intel Corporation. All rights reserved.
# Copyright(c) 2022-2024 Intel Corporation.

set -e

CONFIG_LIST=( sof_example_pass_config sof_example_line_array
sof_example_line_0mm36mm146mm182mm sof_example_circular_array sof_example_two_beams )
sof_example_line_0mm36mm146mm182mm sof_example_circular_array
sof_example_two_beams sof_example_two_beams_default )
OCTAVE_CMD=( octave --no-window-system )
MATLAB_CMD=( matlab -nodisplay -batch )

Expand Down
2 changes: 2 additions & 0 deletions src/audio/tdfb/tune/sof_example_line_array.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ function sof_example_line_array()
az = -90:15:90;
close all; line_one_beam(48e3, 50e-3, az, 2, 64);
close all; line_one_beam(48e3, 68e-3, az, 2, 64);
close all; line_one_beam(48e3, 73.5e-3, az, 2, 64);
close all; line_one_beam(16e3, 50e-3, az, 2, 40);
close all; line_one_beam(16e3, 68e-3, az, 2, 40);
close all; line_one_beam(16e3, 73.5e-3, az, 2, 40);

%% 4 mic arrays
close all; line_one_beam(48e3, 28e-3, az, 4, 80);
Expand Down
34 changes: 31 additions & 3 deletions src/audio/tdfb/tune/sof_example_pass_config.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ function sof_example_pass_config()
bf.num_output_channels = 2; % Two channels
bf.num_output_streams = 1; % One sink stream
bf.beam_off_defined = 0; % No need for separate bypass definition
bf.num_angles = 0; % No beams defined
bf.num_angles = 1; % Need at least one beam defined even
bf.steer_az = 0; % if no processing happens, claim it's
bf.steer_el = 0; % angle (0, 0).
bf.num_filters = 2; % Two filters

% Minimal manual design fields for successful export
Expand All @@ -32,12 +34,14 @@ function sof_example_pass_config()
bf.sofctl3_fn = fullfile(bf.sofctl3_path, 'coef_line2_pass.txt');
bf.tplg1_fn = fullfile(bf.tplg1_path, 'coef_line2_pass.m4');
bf.sofctl4_fn = fullfile(bf.sofctl4_path, 'line2_pass.txt');
bf.ucmbin3_fn = fullfile(bf.sofctl3_path, 'line2_pass.bin');
bf.ucmbin4_fn = fullfile(bf.sofctl4_path, 'line2_pass.bin');
bf.tplg2_fn = fullfile(bf.tplg2_path, 'line2_pass.conf');
sof_bf_export(bf);

% Setup for four channels
bf.input_channel_select = [0 1 2 3]; % Input two channels
bf.output_channel_mix = [1 2 4 8]; % Filter1 -> ch0, filter2 -> ch1
bf.input_channel_select = [0 1 2 3]; % Input four channels
bf.output_channel_mix = [1 2 4 8]; % Filter1 -> ch0, filter2 -> ch1, ...
bf.output_stream_mix = [0 0 0 0]; % Mix both filters to stream 0
bf.num_output_channels = 4; % Four channels
bf.num_output_streams = 1; % One sink stream
Expand All @@ -50,7 +54,31 @@ function sof_example_pass_config()
bf.sofctl3_fn = fullfile(bf.sofctl3_path, 'coef_line4_pass.txt');
bf.tplg1_fn = fullfile(bf.tplg1_path, 'coef_line4_pass.m4');
bf.sofctl4_fn = fullfile(bf.sofctl4_path, 'line4_pass.txt');
bf.ucmbin3_fn = fullfile(bf.sofctl3_path, 'line4_pass.bin');
bf.ucmbin4_fn = fullfile(bf.sofctl4_path, 'line4_pass.bin');
bf.tplg2_fn = fullfile(bf.tplg2_path, 'line4_pass.conf');
sof_bf_export(bf);


% Setup for four channels to two channels passthrough

bf.input_channel_select = [0 3]; % Input two channels, leftmost, rightmost mic of 4
bf.output_channel_mix = [1 2]; % Filter1 -> ch0, filter2 -> ch1
bf.output_stream_mix = [0 0]; % Mix both filters to stream 0
bf.num_output_channels = 2; % Two channels
bf.num_output_streams = 1; % One sink stream

% Minimal manual design fields for successful export
bf.num_filters = 2;
bf.w = [1 0 0 0; 1 0 0 0]'; % Two FIR filters with first tap set to one

% Files
bf.sofctl3_fn = fullfile(bf.sofctl3_path, 'coef_line4to2_pass.txt');
bf.tplg1_fn = fullfile(bf.tplg1_path, 'coef_line4to2_pass.m4');
bf.sofctl4_fn = fullfile(bf.sofctl4_path, 'line4to2_pass.txt');
bf.ucmbin3_fn = fullfile(bf.sofctl3_path, 'line4to2_pass.bin');
bf.ucmbin4_fn = fullfile(bf.sofctl4_path, 'line4to2_pass.bin');
bf.tplg2_fn = fullfile(bf.tplg2_path, 'line4to2_pass.conf');
sof_bf_export(bf);

end
Loading
Loading