forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample_crossover.m
More file actions
130 lines (101 loc) · 3.53 KB
/
example_crossover.m
File metadata and controls
130 lines (101 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
function example_crossover()
addpath ./../common
% Sampling Frequency and Frequency cut-offs for crossover
cr.fs = 48e3;
cr.fc_low = 200;
cr.fc_med = 1000;
cr.fc_high = 3000;
% 2 way crossover, pipeline IDs of sinks are 1 and 2 (IPC3)
% and component output pins 0 and 1 (IPC4)
cr.num_sinks = 2;
cr.sinks = [1 2];
export_crossover(cr);
cr.sinks = [0 1];
export_crossover(cr);
% 3 way crossover, pipeline IDs of sinks are 1 - 3
cr.num_sinks = 3;
cr.sinks = [1 2 3];
export_crossover(cr);
cr.sinks = [0 1 2];
export_crossover(cr);
% 4 way crossover, pipeline IDs of sinks are 1 - 4
cr.num_sinks = 4;
cr.sinks = [1 2 3 4];
export_crossover(cr);
cr.sinks = [0 1 2 3];
export_crossover(cr);
rmpath ./../common
end
function export_crossover(cr)
endian = "little";
tpath1 = '../../topology/topology1/m4/crossover';
tpath2 = '../../topology/topology2/include/components/crossover';
ctlpath = '../../ctl/ipc3';
str_way = sprintf('%dway', cr.num_sinks);
str_freq = get_str_freq(cr);
str_pid = get_str_pid(cr);
% Set the parameters here
tplg1_fn = sprintf('%s/coef_%s_%s_%s.m4', tpath1, str_way, str_freq, str_pid); % Control Bytes File
tplg2_fn = sprintf('%s/coef_%s_%s_%s.conf', tpath2, str_way, str_freq, str_pid);
% Use those files with sof-ctl to update the component's configuration
blob_fn = sprintf('%s/crossover_coef_%dway.blob', ctlpath, cr.num_sinks); % Blob binary file
alsa_fn = sprintf('%s/crossover_coef_%dway.txt', ctlpath, cr.num_sinks); % ALSA CSV format file
% This array is an example on how to assign a buffer from pipeline 1 to output 0,
% buffer from pipeline 2 to output 1, etc...
% Refer to sof/src/include/user/crossover.h for more information on assigning
% buffers to outputs.
assign_sinks = zeros(1, 4);
assign_sinks(1:cr.num_sinks) = cr.sinks;
% Generate zeros, poles and gain for crossover with the given frequencies
switch cr.num_sinks
case 2
crossover = crossover_gen_coefs(cr.fs, cr.fc_low); % 2 way crossover
case 3
crossover = crossover_gen_coefs(cr.fs, cr.fc_low, cr.fc_med); % 3 way crossover
case 4
crossover = crossover_gen_coefs(cr.fs, cr.fc_low, cr.fc_med, cr.fc_high); % 4 way crossover
otherwise
error('Illegal number of sinks %d\n', num_sinks);
end
% Convert the [a,b] coefficients to values usable with SOF
crossover_bqs = crossover_coef_quant(crossover.lp, crossover.hp);
% Convert coefficients to sof_crossover_config struct
config = crossover_generate_config(crossover_bqs, cr.num_sinks, assign_sinks);
% Convert struct to binary blob
blob8 = crossover_build_blob(config, endian, 3);
blob8_ipc4 = crossover_build_blob(config, endian, 4);
% Generate output files
mkdir_check(tpath1);
mkdir_check(tpath2);
mkdir_check(ctlpath);
tplg_write(tplg1_fn, blob8, "CROSSOVER");
tplg2_write(tplg2_fn, blob8_ipc4, "crossover_config", 'Exported Control Bytes');
blob_write(blob_fn, blob8);
alsactl_write(alsa_fn, blob8);
% Plot Magnitude and Phase Response of each sink
crossover_plot_freq(crossover.lp, crossover.hp, cr.fs, cr.num_sinks);
end
% Frequencies part for filename
function str = get_str_freq(cr)
switch cr.num_sinks
case 2
str = sprintf('%d_%d', cr.fs, cr.fc_low);
case 3
str = sprintf('%d_%d_%d', cr.fs, cr.fc_low, cr.fc_med);
case 4
str = sprintf('%d_%d_%d_%d', cr.fs, cr.fc_low, cr.fc_med, cr.fc_high);
end
end
% Pipeline IDs part of filename
function str = get_str_pid(cr)
str = sprintf('%d', cr.sinks(1));
for i = 2:cr.num_sinks
str = sprintf('%s_%d', str, cr.sinks(i));
end
end
% Check if directory exists, avoid warning print for existing
function mkdir_check(new_dir)
if ~exist(new_dir, 'dir')
mkdir(new_dir);
end
end