Code generation error while using the Audio Toolbox
    5 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
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
    
 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? 
Risposta accettata
  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
0 Commenti
Più risposte (0)
Vedere anche
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!


