From 2eee02fe9fbde6d68884ab5f86d60a92dc441a5f Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Mon, 25 Nov 2024 13:46:46 +0200 Subject: [PATCH] Tools: Tune: TDFB: Add generate of few needed blobs This patch adds a few blobs generate for the beamformer. There is no need to update the blobs in tplg2 since the update has been already done with run of an earlier version of this patch. - Support two mic line array with 74 mm spacing with addition to sof_example_line_array.m and sof_example_two_beams.m - Updates beamformer pass-through configuration blob with steer angle to avoid initialize error. - Adds script sof_example_two_beams_default.m to export generic blobs for 2 and 4 mic line arrays. The parameters are such that the array mic spacing is not critical (delay-and-sum type) and narrow user faced stereo beams. The two beams design functions are split to own files for use from two scripts. Signed-off-by: Seppo Ingalsuo --- src/audio/tdfb/tune/sof_bf_line2_two_beams.m | 73 +++++++++ src/audio/tdfb/tune/sof_bf_line4_two_beams.m | 73 +++++++++ src/audio/tdfb/tune/sof_example_all.sh | 5 +- src/audio/tdfb/tune/sof_example_line_array.m | 2 + src/audio/tdfb/tune/sof_example_pass_config.m | 28 +++- src/audio/tdfb/tune/sof_example_two_beams.m | 138 +++--------------- .../tdfb/tune/sof_example_two_beams_default.m | 61 ++++++++ 7 files changed, 261 insertions(+), 119 deletions(-) create mode 100644 src/audio/tdfb/tune/sof_bf_line2_two_beams.m create mode 100644 src/audio/tdfb/tune/sof_bf_line4_two_beams.m create mode 100644 src/audio/tdfb/tune/sof_example_two_beams_default.m diff --git a/src/audio/tdfb/tune/sof_bf_line2_two_beams.m b/src/audio/tdfb/tune/sof_bf_line2_two_beams.m new file mode 100644 index 000000000000..7f7eec8dd826 --- /dev/null +++ b/src/audio/tdfb/tune/sof_bf_line2_two_beams.m @@ -0,0 +1,73 @@ +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 + +% 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.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 diff --git a/src/audio/tdfb/tune/sof_bf_line4_two_beams.m b/src/audio/tdfb/tune/sof_bf_line4_two_beams.m new file mode 100644 index 000000000000..9cefc37fc10a --- /dev/null +++ b/src/audio/tdfb/tune/sof_bf_line4_two_beams.m @@ -0,0 +1,73 @@ +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 + +% 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.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 diff --git a/src/audio/tdfb/tune/sof_example_all.sh b/src/audio/tdfb/tune/sof_example_all.sh index eb9c6f2ab74f..2a7b45b3833c 100755 --- a/src/audio/tdfb/tune/sof_example_all.sh +++ b/src/audio/tdfb/tune/sof_example_all.sh @@ -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 ) diff --git a/src/audio/tdfb/tune/sof_example_line_array.m b/src/audio/tdfb/tune/sof_example_line_array.m index be8b60acf3fc..5ae28003fc79 100644 --- a/src/audio/tdfb/tune/sof_example_line_array.m +++ b/src/audio/tdfb/tune/sof_example_line_array.m @@ -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); diff --git a/src/audio/tdfb/tune/sof_example_pass_config.m b/src/audio/tdfb/tune/sof_example_pass_config.m index d3e1fabc39b9..35bba9eb7186 100644 --- a/src/audio/tdfb/tune/sof_example_pass_config.m +++ b/src/audio/tdfb/tune/sof_example_pass_config.m @@ -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 @@ -36,8 +38,8 @@ function sof_example_pass_config() 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 @@ -53,4 +55,24 @@ function sof_example_pass_config() 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.tplg2_fn = fullfile(bf.tplg2_path, 'line4to2_pass.conf'); +sof_bf_export(bf); + end diff --git a/src/audio/tdfb/tune/sof_example_two_beams.m b/src/audio/tdfb/tune/sof_example_two_beams.m index dc081593fb44..6b7dab549be5 100644 --- a/src/audio/tdfb/tune/sof_example_two_beams.m +++ b/src/audio/tdfb/tune/sof_example_two_beams.m @@ -20,6 +20,12 @@ function sof_example_two_beams() %% Stereo capture blobs with two beams az = [0 30 90]; azstr = az_to_string(az); + +prm.export_note = 'Created with script example_two_beams.m'; +prm.export_howto = 'cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r example_two_beams'; +prm.type = 'SDB'; +prm.add_beam_off = 1; + for fs = [16e3 48e3] %% Close all plots to avoid issues with large number of windows close all; @@ -32,7 +38,7 @@ function sof_example_two_beams() d = 50e-3; % 50 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line2_two_beams(fs, d, a1, a2, fn, 1); + sof_bf_line2_two_beams(fs, d, a1, a2, fn, prm); %% 2 mic 68 mm array fn.tplg1_fn = sprintf('coef_line2_68mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); @@ -42,7 +48,17 @@ function sof_example_two_beams() d = 68e-3; % 68 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line2_two_beams(fs, d, a1, a2, fn, 1); + sof_bf_line2_two_beams(fs, d, a1, a2, fn, prm); + + %% 2 mic 73.5 mm array + fn.tplg1_fn = sprintf('coef_line2_74mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line2_74mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line2_74mm_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line2_74mm_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + d = 73.5e-3; % 73.5 mm spacing + a1 = az; % Azimuth +az deg + a2 = -az; % Azimuth -az deg + sof_bf_line2_two_beams(fs, d, a1, a2, fn, prm); %% 4 mic 28 mm spaced array fn.tplg1_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); @@ -52,7 +68,7 @@ function sof_example_two_beams() d = 28e-3; % 28 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, fn, 1); + sof_bf_line4_two_beams(fs, d, a1, a2, fn, prm); %% 4 mic 68 mm spaced array fn.tplg1_fn = sprintf('coef_line4_68mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); @@ -62,7 +78,7 @@ function sof_example_two_beams() d = 68e-3; % 68 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, fn, 1); + sof_bf_line4_two_beams(fs, d, a1, a2, fn, prm); %% 4 mic 78 mm spaced array fn.tplg1_fn = sprintf('coef_line4_78mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); @@ -72,13 +88,14 @@ function sof_example_two_beams() d = 78e-3; % 78 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, fn, 1); + sof_bf_line4_two_beams(fs, d, a1, a2, fn, prm); end %% Export blob with just +/- 90 deg beams for testbench beampattern check close all; az = [90]; azstr = az_to_string(az); +prm.add_beam_off = 0; for fs = [16e3 48e3] %% 2 mic 50 mm array, disable beam off description in blob to force processing on fn.tplg1_fn = sprintf('coef_line2_50mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); @@ -88,7 +105,7 @@ function sof_example_two_beams() d = 50e-3; % 50 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line2_two_beams(fs, d, a1, a2, fn, 0); + sof_bf_line2_two_beams(fs, d, a1, a2, fn, prm); %% 4 mic 28 mm spaced array, no beam off configuration fn.tplg1_fn = sprintf('coef_line4_28mm_pm%sdeg_%dkhz.m4', azstr, fs/1e3); @@ -98,7 +115,7 @@ function sof_example_two_beams() d = 28e-3; % 28 mm spacing a1 = az; % Azimuth +az deg a2 = -az; % Azimuth -az deg - line4_two_beams(fs, d, a1, a2, fn, 0); + sof_bf_line4_two_beams(fs, d, a1, a2, fn, prm); end %% Circular array with two beams @@ -126,113 +143,6 @@ function sof_example_two_beams() end end -function line2_two_beams(fs, d, a1, a2, fn, add_beam_off); - -% Get defaults -bf1 = sof_bf_defaults(); -bf1.fs = fs; -bf1.beam_off_defined = add_beam_off; - - -% Setup array -bf1.array='line'; % Calculate xyz coordinates for line -bf1.mic_n = 2; -bf1.mic_d = d; - -% 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.tplg2_fn = fullfile(bfm.tplg2_path, fn.tplg2_fn); - -% Export files for topology and sof-ctl -bfm.export_note = 'Created with script sof_example_two_beams.m'; -bfm.export_howto = 'cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r sof_example_two_beams'; -sof_bf_export(bfm); - -end - -function line4_two_beams(fs, d, a1, a2, fn, add_beam_off); - -% Get defaults -bf1 = sof_bf_defaults(); -bf1.fs = fs; -bf1.beam_off_defined = add_beam_off; - -% Setup array -bf1.array='line'; % Calculate xyz coordinates for line -bf1.mic_n = 4; -bf1.mic_d = d; - -% 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.tplg2_fn = fullfile(bfm.tplg2_path, fn.tplg2_fn); - -% Export files for topology and sof-ctl -bfm.export_note = 'Created with script sof_example_two_beams.m'; -bfm.export_howto = 'cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r sof_example_two_beams'; -sof_bf_export(bfm); - -end - function circular_two_beams(fs, r, n, a1, a2, fn, add_beam_off) % Get defaults and common settings diff --git a/src/audio/tdfb/tune/sof_example_two_beams_default.m b/src/audio/tdfb/tune/sof_example_two_beams_default.m new file mode 100644 index 000000000000..65fe1bc41563 --- /dev/null +++ b/src/audio/tdfb/tune/sof_example_two_beams_default.m @@ -0,0 +1,61 @@ +function sof_example_two_beams_default() + +% sof_example_two_beams_default() +% +% Creates configuration files for a two beams design, one +% points to -10 degrees and other to 10 degrees +% direction for default 50 mm spaced two microphones configuration. The +% beams are output to stereo and left right channels. The angle is +% slightly different for different microphones spacing. With larger +% microphones spacing the angle narrows a bit. But since the target +% is user focused audio with slight stereo effect it's acceptable. +% The bespoke blobs for a device can be applied with ALSA UCM. + +% SPDX-License-Identifier: BSD-3-Clause +% +% Copyright (c) 2024, Intel Corporation. +% +% Author: Seppo Ingalsuo + +%% Stereo capture blobs with two beams +az = [10]; +azstr = az_to_string(az); + +prm.export_note = 'Created with script sof_example_two_beams_default.m'; +prm.export_howto = 'cd tools/tune/tdfb; matlab -nodisplay -nosplash -nodesktop -r sof_example_two_beams_default'; +prm.type = 'DSB'; +prm.add_beam_off = 1; + +for fs = [16e3 48e3] + %% Close all plots to avoid issues with large number of windows + close all; + + %% 2 mic array + fn.tplg1_fn = sprintf('coef_line2_generic_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line2_generic_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line2_generic_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line2_generic_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + d = 50e-3; % 50 mm spacing + a1 = az; % Azimuth +az deg + a2 = -az; % Azimuth -az deg + sof_bf_line2_two_beams(fs, d, a1, a2, fn, prm); + + %% 4 mic array + fn.tplg1_fn = sprintf('coef_line4_generic_pm%sdeg_%dkhz.m4', azstr, fs/1e3); + fn.sofctl3_fn = sprintf('coef_line4_generic_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + fn.tplg2_fn = sprintf('line4_generic_pm%sdeg_%dkhz.conf', azstr, fs/1e3); + fn.sofctl4_fn = sprintf('line4_generic_pm%sdeg_%dkhz.txt', azstr, fs/1e3); + d = 40e-3; % 40 mm spacing + a1 = az; % Azimuth +az deg + a2 = -az; % Azimuth -az deg + sof_bf_line4_two_beams(fs, d, a1, a2, fn, prm); +end + +end + +function s = az_to_string(az) + s = sprintf('%d', az(1)); + for n = 2:length(az) + s = sprintf('%s_%d', s, az(n)); + end +end