Code generation error while using the Audio Toolbox

2 visualizzazioni (ultimi 30 giorni)
Hello,
I was wondering if someone could help me understanding why I get the following error while trying to generate the standalone executable of an audio plugin using the Audio Test Bench.
I am using features from the Audio Toolbox and the DSP Toolbox. In particular, I am using the dsp.FilterCascade function, and I get this error:
"Changing the size on input 1 of Sysremobject dsp.FilterCascade is not allowed without first calling the release() method."
In the considered implementation EQ1 is a property,
properties (Access = private)
width = 2.75;
flag = 1;
sizePre = 0;
EQ1 = [];
EQ2 = [];
DRC = [];
DRL = [];
end
and then is set as a dsp.FilterCascade.
plugin.EQ1 = dsp.FilterCascade(highpass, lowshelf, parametric, ...
highshelf, lowpass);
The line giving the error is the following one:
y_EQ1 = plugin.EQ1(x);
This line is inside the plugin process function:
function out = process(plugin, in)
...
...
y_EQ1 = plugin.EQ1(x);
...
end
As suggested by the error message, I have tried to call the release method just before evaluating y_EQ1 = plugin.EQ1(x),
function out = process(plugin, in)
...
...
release(plugin.EQ1);
y_EQ1 = plugin.EQ1(x);
...
end
but I get another error message and the plugin now produces a crackle. I am supposing this is due to the fact that it cannot work in real time with such modification.
The error message printed on the command window while trying to generate the standalone executable is the following one:
??? Cannot compute constant value for argument #2 for this System object constructor. All
arguments to the constructor of this System object must be constants for code generation.
One way to supply a constant value is to pass it to the main function using Simulink
non-tunable parameters (for MATLAB Function block) or coder.Constant(...) (for MATLAB
Coder).
Error in ==> PiezoSoundEnhancerV3 Line: 172 Column: 24
Code generation failed: View Error Report
This is line 172:
[B, A] = designVarSlopeFilter(slopeHighpass, ...
cutoffHighpass, "hi", "Orientation", "row");
highpass = dsp.SOSFilter('Numerator',B,'Denominator',A);
Thanks a lot for your help.
Best Regards,
  1 Commento
Denis Gurchenkov
Denis Gurchenkov il 7 Ott 2022
Hi Alberto, this behavior does not look correct, though it is hard to say something definitive without seeing the entire example. I wonder if you could contact MathWorks technical support and open a ticket?

Accedi per commentare.

Risposta accettata

jibrahim
jibrahim il 7 Ott 2022
Hi Alberto,
I see two issues here:
1) First, you have hit a limitation of dsp.FilterCascade. It does not support variable-size inputs. You are right that releasing the object is not the right approach here, as it will lead to glitches. You will have to bypass usage of dsp.FilterCascade, and manage multiple objects (one per cascade item, see below for a contrived example)
2) The issue with the SOS filter object can be solved by specifying the coefficient source as input ports rather than a property on the object. Again see code below for the pattern.
classdef (StrictDefaults)myExamplePlugin < matlab.System & audioPlugin
% Contrived example with a cascade of two filters that do the same thing
properties
% Cutoff frequency in Hz
LowCutoff = 20
HighCutoff = 18e3;
end
properties
% Slope in dB/octave
LowSlope = '12'
HighSlope = '30'
end
properties (Constant)
% Define the plugin interface
PluginInterface = audioPluginInterface( ...
'InputChannels',2,...
'OutputChannels',2,...
'PluginName','Variable Slope Bandpass',...
audioPluginParameter('LowCutoff', ...
'DisplayName', 'Low Cutoff', ...
'Label', 'Hz', ...
'Mapping', { 'log', 20, 20000},...
'Style', 'rotaryknob', 'Layout', [1 1]),...
audioPluginParameter('HighCutoff', ...
'DisplayName', 'High Cutoff', ...
'Label', 'Hz', ...
'Mapping', { 'log', 20, 20000},...
'Style', 'rotaryknob', 'Layout', [1 2]),...
audioPluginParameter('LowSlope', ...
'DisplayName', 'Low Slope', ...
'Label', 'dB/octave', ...
'Mapping', { 'enum', '0','6','12','18','24','30','36','42','48'},...
'Layout', [3 1]),...
audioPluginParameter('HighSlope', ...
'DisplayName', 'High Slope', ...
'Label', 'dB/octave', ...
'Mapping', { 'enum', '0','6','12','18','24','30','36','42','48'},...
'Layout', [3 2]), ...
audioPluginGridLayout('RowHeight', [100 20 30 20], ...
'Padding', [10 10 10 30]), ...
'BackgroundImage', audiopluginexample.private.mwatlogo);
end
properties (Access = private)
% Numerator coefficients
Num
% Denominator coefficients
Den
% Biquad filter
SOSObj
% Another filter for illustration
SOSObj2
% Flag to indicate whether filter re-design is needed
AreFiltersDesigned = false;
pHighSlopeNumeric = 30
pLowSlopeNumeric = 12
end
methods
% Constructor
function plugin = myExamplePlugin(Fc1,Fc2,s1,s2)
if nargin > 0
plugin.LowCutoff = Fc1;
end
if nargin > 1
plugin.HighCutoff = Fc2;
end
if nargin > 2
plugin.LowSlope = s1;
end
if nargin > 3
plugin.HighSlope = s2;
end
% Set CoefficientSource to 'Input port'!
plugin.SOSObj = dsp.SOSFilter('CoefficientSource','Input port',...
'HasScaleValues',false);
plugin.SOSObj2 = dsp.SOSFilter('CoefficientSource','Input port',...
'HasScaleValues',false);
calculateCoefficients(plugin);
end
function set.LowCutoff(plugin,val)
% Check that the low cutoff is a finite, real,
% nonnegative scalar
validateattributes(val, {'numeric'}, ...
{'finite','real','scalar','nonnegative'},...
'set.LowCutoff','LowCutoff');
% Set value if it meets required attributes
plugin.LowCutoff = val;
needToDesignFilters(plugin);
end
function set.HighCutoff(plugin,val)
% Check that the high cutoff is a finite, real,
% nonnegative scalar
validateattributes(val, {'numeric'}, ...
{'finite','real','scalar','nonnegative'},...
'set.HighCutoff','HighCutoff');
% Set value if it meets required attributes
plugin.HighCutoff = val;
needToDesignFilters(plugin);
end
function set.LowSlope(plugin,val)
% Check that the low slope is a finite, real,
% nonnegative scalar
validatestring(val,{'0','6','12','18','24','30','36','42','48'},...
'set.LowSlope','LowSlope');
% Round slope to nearest multiple of 6
plugin.pLowSlopeNumeric = real(str2double(val));%#ok<MCSUP>
needToDesignFilters(plugin);
end
function set.HighSlope(plugin,val)
% Check that the high slope is a finite, real,
% nonnegative scalar
validatestring(val,{'0','6','12','18','24','30','36','42','48'},...
'set.HighSlope','HighSlope');
% Set value if it meets required attributes
plugin.pHighSlopeNumeric = real(str2double(val));%#ok<MCSUP>
needToDesignFilters(plugin);
end
function val = get.LowSlope(plugin)
val = convertnum(plugin.pLowSlopeNumeric);
end
function val = get.HighSlope(plugin)
val = convertnum(plugin.pHighSlopeNumeric);
end
end
methods(Access = protected)
function releaseImpl(plugin)
release(plugin.SOSObj);
release(plugin.SOSObj2)
end
function out = stepImpl(plugin, in)
% Main processing algorithm
% Notice that the coefficients are passed to the object right
% here
y = plugin.SOSObj(in, plugin.Num, plugin.Den);
out = plugin.SOSObj2(y, plugin.Num, plugin.Den);
end
function resetImpl(plugin)
% Reset the states
reset(plugin.SOSObj);
reset(plugin.SOSObj2);
calculateCoefficients(plugin);
end
function processTunedPropertiesImpl(plugin)
% Recalculate coefficients when cutoff is changed
if ~plugin.AreFiltersDesigned
% Re-design filters when necessary
calculateCoefficients(plugin);
end
end
function [B, A] = getFilterCoefficients(plugin)
B = plugin.Num;
A = plugin.Den;
end
function flag = isInputSizeMutableImpl(~,~)
flag = true;
end
end
methods (Access = private)
function calculateCoefficients(plugin)
% Function to compute filter coefficients
Fs = getSampleRate(plugin);
[B1,A1] = designVarSlopeFilter(plugin.pLowSlopeNumeric,plugin.LowCutoff/(Fs/2),'hi','Orientation','row');
[B2,A2] = designVarSlopeFilter(plugin.pHighSlopeNumeric,plugin.HighCutoff/(Fs/2),'lo','Orientation','row');
plugin.Num = [B1;B2];
plugin.Den = [A1;A2];
plugin.AreFiltersDesigned = true;
end
function needToDesignFilters(plugin)
plugin.AreFiltersDesigned = false;
end
end
methods(Static, Access = protected)
function group = getPropertyGroupsImpl
% This is needed to define dependent properties for MATLAB
% System block
group = matlab.system.display.Section('Title', getString(message('dsp:system:Shared:Parameters')), ...
'PropertyList', {'LowCutoff', 'HighCutoff', 'LowSlope','HighSlope','PluginInterface'}, ...
'DependOnPrivatePropertyList',{'LowSlope','HighSlope'});
end
end
end
function s = convertnum(n)
if n==0
s = '0';
return;
end
s = [];
while n > 0
d = mod(n,10);
s = [char(48+d), s]; %#ok
n = (n-d)/10;
end
end

Più risposte (0)

Categorie

Scopri di più su Audio Plugin Creation and Hosting in Help Center e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by