SampleRateConvertion error in plugin

Hi
I´m trying to implement a x4 oversampling process but I´m having difficulties on how let the SampleRateConverter sytem object knows about sample rate used.
When compiling the example attached for plugin generation, the following error shows up: “Failed to compute constant value for nontunable property 'SampleRate'. In code generation, nontunable properties can only be assigned constant values.”
I'd really appreciate if someone can give me a hint on how fix/treat this.
Br
Pablo
classdef (StrictDefaults)DistoLab_Test2 < matlab.System & audioPlugin
properties
GainDisto=0;
Input=0;
Volume=0;
end
properties (Constant, Hidden)
% Define the plugin interface
PluginInterface = audioPluginInterface( ...
'InputChannels',2,...
'OutputChannels',2,...
'PluginName','DistoLab_Test2',...
audioPluginParameter('Volume', ...
'DisplayName', 'Out', ...
'DisplayNameLocation','none',...
'Label','dB', ...
'Mapping', { 'lin', -15, 15}, ...
'Style', 'rotaryknob', 'Layout', [4 6]),...
audioPluginParameter('Input', ...
'DisplayName', 'In', ...
'DisplayNameLocation','none',...
'Label','dB', ...
'Mapping', { 'lin', -5, 5}, ...
'Style', 'rotaryknob', 'Layout', [4 3]),...
audioPluginParameter('GainDisto', ...
'DisplayName', 'Saturation', ...
'DisplayNameLocation','none',...
'Style', 'rotaryknob', 'Layout', [4,5],...
'Mapping', { 'lin', 0, 10}, ...
'Filmstrip','knob_67_black.png', ... %<--
'FilmstripFrameSize',[80,80]), ...
audioPluginGridLayout('RowHeight', [30 90 10 100 37], ...
'ColumnWidth', [30 100 100 20 100 100 20 80 80 80 60], 'Padding', [10 10 10 10]));
end
properties (Access = private)
Up4;
Down4;
end
methods
% Constructor
function plugin = DistoLab_Test2
plugin.Up4=dsp.SampleRateConverter;
plugin.Down4=dsp.SampleRateConverter;
calculateSampleRates(plugin);
end
end
methods(Access = protected)
function out = stepImpl(plugin, in)
inadjusted=in*(10^(plugin.Input/20)); % Incoming signal adjusted by Input Gain
%SampleRateConverter x4 process
v=step(plugin.Up4,inadjusted);
disto=(v*plugin.GainDisto).^5; % input distorted
outdisto=(disto)*(10^(plugin.Volume/20));
out = step(plugin.Down4,outdisto);
end
function resetImpl(plugin)
reset(plugin.Up4);
reset(plugin.Down4);
end
function calculateSampleRates(plugin)
plugin.Up4.InputSampleRate=getSampleRate(plugin);
plugin.Up4.OutputSampleRate=4*getSamplerate(plugin);
plugin.Down4.InputSampleRate=4*getSampleRate(plugin);
plugin.Down4.OutputSampleRate=getSampleRate(plugin);
end
end
end

 Respuesta aceptada

Jimmy Lapierre
Jimmy Lapierre el 23 de Nov. de 2020
Hi Pablo,
There are some limitations with codegen and the resampling objects. If you have a hard-coded ratio of 4, the easiest way around it might be to use a nominal sample rate, such as 48kHz. The added benefit is that avoid calls to getSampleRate will be faster.
function calculateSampleRates(plugin)
sampleRate = 48000; % use a nominal rate
plugin.Up4.InputSampleRate=sampleRate;
plugin.Up4.OutputSampleRate=4*sampleRate;
plugin.Down4.InputSampleRate=4*sampleRate;
plugin.Down4.OutputSampleRate=sampleRate;
end
The following challenge will be that the input of the sample rate converter will be of unknown size. You can get around that by looping over partitions of a maximum size (like 4096). Something like this might work for you:
% Replaces out = step(plugin.Down4,outdisto);
out = zeros(size(in));
for ii = 1:4096:size(in,1)
endIdx = min(ii+4095,size(in,1));
xin = outdisto(4*ii-3:4*endIdx,:);
assert(size(xin,1)<=4*4096); % Tell codegen xin won't be larger than 4x4096
out(ii:endIdx,:) = step(plugin.Down4,xin);
end

7 comentarios

Pablo Panitta
Pablo Panitta el 24 de Nov. de 2020
Editada: Pablo Panitta el 24 de Nov. de 2020
HI Jimmy
Thanks a lot for your promt answer and detail explanation.
I cannot see how the process porposed is solving the issue. My understanding is the following: when plugin is instantiated in a DAW session, works at the sample rate of the session. As this is not knowing in advance by plugin, there´s no way to predefine the ‘InitialSampleRate’ parameter value (until inserted). So the methodology should be: insert the plugin in a session, get the its sample rate value, and then set up the InitialSamplerate accordingly.
But when I try to implement this concept, in the constructor areas (as always do with SystemObject parameter definition), it is not possible to define anything but fixed values (what is exactly I don´t need!). If I try to make it relative to samplerate of the plugin a “non tunable parameter…” error describe above appears.
E.g if your example is inserted in a 88kHz DAW session, the SampleRateConverter will end up working with initialSampleRate of 48kHz instead 88kHz?
If I'm wrong please let me know, otherwise : is there any way to do it?
Thanks
Pablo
Jimmy Lapierre
Jimmy Lapierre el 24 de Nov. de 2020
Hi Pablo, I should have gave some background information. Aa sample rate converter does not need to know the absolute sample rates, only the ratio between the output and the input. If your output/input ratio is contant (4), you can specify 48k input and 4*48k output. It will have the same effect if the sample rate turns out to be 44100 (it will upsample by 4 to 4*44100). Let me know if this helps!
Pablo Panitta
Pablo Panitta el 24 de Nov. de 2020
Hi
So, InputSampleRate & OutputSamplerate are taken only for xfactor, not for the actual values to be sampled. Great this solved my issue!
Just final question, I think this concept also applies to others system Object for oversampling (eg IIRHalfbandDecimator or IIRHalfbandDecimator) with the only difference that oversampling factor is fixed to 2 on those ones,right?
Thanks Jimmy
Pablo
Jimmy Lapierre
Jimmy Lapierre el 24 de Nov. de 2020
For your use-case, same concept. The SampleRate property is used either for display purposes or because these objects are also supported in Simulink, where they must propagate the sample rate.
For example, when resampling a digital signal x2, the same code that does 48k=>96k could do 96k=>192k (except that the latter could have a more lax filter design if you prefer, because of the limits of hearing).
Pablo Panitta
Pablo Panitta el 24 de Nov. de 2020
thanks Jimmy
Adrian Alexander
Adrian Alexander el 2 de Feb. de 2021
Hi i realy like the oversampling code.
I want to change the code to some other oversamplingfactor like x8 or x16
what would change in the second part ? i dont realy know how it works.
ut = zeros(size(in));
for ii = 1:4096:size(in,1)
endIdx = min(ii+4095,size(in,1));
xin = outdisto(4*ii-3:4*endIdx,:);
assert(size(xin,1)<=4*4096); % Tell codegen xin won't be larger than 4x4096
out(ii:endIdx,:) = step(plugin.Down4,xin);
end
thanks
Jimmy Lapierre
Jimmy Lapierre el 2 de Feb. de 2021
Replace all the "4*" by a constant named "OSF" (oversampling factor) and set it to 4, 8 or 16.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Audio Plugin Creation and Hosting en Centro de ayuda y File Exchange.

Productos

Versión

R2020b

Preguntada:

el 23 de Nov. de 2020

Comentada:

el 2 de Feb. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by