I am writing a Matlab script that implements a noisegate algorithm. It iterates over the length of an input signal (which I created in the same script) and processes sample by sample. The algorithm itself doesn't require much memory (it carries over two values to the next iteration, namely x_peak_old
and g_old
). However, to monitor the internal process of the algorithm, I created some additional debug vectors that are the same length of the input signal and get updated with each loop. I comment them in and out as needed.
However, my problem is that one of these vectors behaves strangely. If I disable this vector and hit 'Run', the script executes and finishes in an instant. However, when I assign values to this specific vector each loop and run the script, it takes several seconds to compute and one core of my CPU is at 100% load during this time.
Here's the code:
clear all; close all;
% ***** Parameter *****
Fs = 44100; % Samplerate
ta = 5; % Attack time in ms
tr = 300; % Release time in ms
th = -8; % Threshold in dB
R = 0.05; % Ratio in dB/dB
% ***** Test signal *****
f0 = 20000; % Frequency in Hz
a = (0:Fs) ./ Fs;
aflip = fliplr(a);
sine = sin((2 * pi * f0 / Fs) .* (0:Fs));
sinedecay = zeros(1, Fs);
for k = 1:(Fs+1)
sinedecay(k) = sine(k)*aflip(k);
end
zeropad = zeros(1, Fs);
% Sine only
% x = [zeropad sine sinedecay zeropad];
% Triangle Rectangle Sine
x = [zeropad a (1-a) -a a-1 zeropad ones(1, Fs) (-1).*ones(1,Fs) zeropad sine sine sinedecay zeropad];
% Dirac
%x = [zeropad 1 zeropad];
siglen = length(x);
x_axis = (1:siglen) ./ Fs;
% ***** Output signal *****
y = zeros(1, siglen);
% ***** Debug signals *****
%threshold = 10^(th/20) .* ones(1, siglen);
%xpeakt = zeros(1, siglen);
%peaklogt = zeros(1, siglen);
%ctrl_logt = zeros(1, siglen);
f_t = zeros(1, siglen);
gt = zeros(1, siglen);
% ***** Derived parameters *****
AT = 1/(1+ta*Fs/1000);
RT = 1-1/(1+tr*Fs/1000);
TH_log = log2( 10^(th/20));
S = 1 - 1/R;
% ***** Initial parameters *****
x_peak_old = 0;
g_old = 0;
% ***** Lets go! *****
for i = 1:siglen
% Peak measurement
p0 = abs(x(i));
x_peak = x_peak_old * RT;
if (p0 > x_peak)
x_peak = p0 * AT + x_peak_old *(1-AT);
end
x_peak_old = x_peak;
% xpeakt(i) = x_peak; % DEBUG
x_peak_log = log2(x_peak);
% peaklogt(i) = x_peak_log; % DEBUG
% Compare with threshold
ctrl_log = TH_log - x_peak_log;
if (ctrl_log < 0)
ctrl_log = 0;
end
% ctrl_logt(i) = ctrl_log; %DEBUG
% Calculation of weight factor
f = S * ctrl_log;
f_t(i) = f; %DEBUG
g = 2^f;
% Smoothing filter for weight factor
if (g > g_old)
coeff = 1-AT;
else
coeff = 1-RT;
end
temp = g;
g = coeff * g + (1-coeff) * g_old;
g_old = temp;
% THE FOLLOWING LINE CAUSES PROBLEMS
gt(i) = g; % DEBUG
% Calculation output signal
y(i) = x(i) * g;
end
% ***** Plot input, output and debug signals *****
figure;
subplot(211);
plot(x_axis, x);
hold on; grid on;
%plot(x_axis, threshold);
%plot(x_axis, xpeakt); %DEBUG
%plot(x_axis, peaklogt); %DEBUG
%plot(x_axis, ctrl_logt); %DEBUG
plot(x_axis, f_t); %DEBUG
%plot(x_axis, gt); %DEBUG
subplot(212);
plot(x_axis, y);
The line that is causing the issues is the one near the end:
gt(i) = g; % DEBUG
However, just a few lines before, in the same loop, I assing a value to a vector the same way:
f_t(i) = f; %DEBUG
Both vectors are initialized the same way. There are more vectors in this loop that are treated the exact same way, but it is only the gt(i)
vector that behaves odd.
I tested this script on two different machines running Matlab R2014b. What is causing this issue?
Just change the name of your variable gt
to something else (other than the name of a built-in function).
I think this is exactly the case The Mathworks warn you about when they tell you that it is not recommended to overload built-in function.
The gt
function is the full form of the shorthand operator >
.
Before running the script:
>> which gt
built-in (C:\TLAB13a\toolbox\matlab\ops\@double\gt) % double method
And after running your script:
>> which gt
gt is a variable.
I can reproduce the described behaviour in Matlab R2013a (~7.5s with the debug variable, 0.1s without).
Note that on R2016a this behaviour is inexistant (~0.12s for both versions). The newer Matlab engine are not so easily confused by overloaded built in functions.
In your case, and for people using older Matlab version, just changing the variable name from gt
to anything else (other than the name of another built-in function), gtx
for example, make the script run fine and fast even with the debug variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With