%% Remove High-Frequency Noise Using Biquad SOS Filter
% Lowpass filter a noisy sinusoidal signal using the dsp.SOSFilter System object. Visualize the original and filtered signals using a spectrum analyzer.
%% Input Signal
% The input signal is a sinusoidal signal with two tones, one at 1 kHz and the other at 3 kHz. The sampling frequency is 8 kHz.

f1 = 1000;
f2 = 3000;
Fs = 8000;
sine = dsp.SineWave('Frequency',[f1,f2],'SampleRate',Fs,...
'SamplesPerFrame',1024);

%
%% Create Biquad SOS Filter
% Design a 10th-order lowpass Butterworth IIR filter with a cutoff frequency of 2 kHz. The numerator and denominator coefficients are extracted from the designed SOS matrix.

Fcutoff = 2000;
[z,p,k] = butter(10,Fcutoff/(Fs/2));
[s, g]  = zp2sos(z,p,k);
num = s(:,1:3);
den = s(:,4:6);
    
sosFilter = dsp.SOSFilter(num, den,'HasScaleValues',true,'ScaleValues',g)

% Visualize the frequency response of the designed SOS filter.

fvtool(sosFilter,'Fs',8000)

%
%% Streaming
% Add zero-mean white Gaussian noise with a standard deviation of 0.1 to the sum of sine waves. Filter the noisy sinusoidal signal with the designed SOS filter.
% While running the simulation, the spectrum analyzer shows that the high-frequency tone above 2 kHz in the source signal is attenuated. The resulting signal maintains the peak at 1 kHz because it falls in the passband of the lowpass filter.

SA = dsp.SpectrumAnalyzer('PlotAsTwoSidedSpectrum',false, ...
    'SampleRate',Fs, ...
    'NumInputPorts',2,...
    'ShowLegend',true,...
    'YLimits',[-200 100],...
    'ChannelNames',{'Input signal', 'Filtered signal'});

    % Stream processing loop
for k = 1:100
    input = sum(sine(),2) + 0.1.*randn(sine.SamplesPerFrame,1);
    filteredOutput = sosFilter(input);
    SA(input,filteredOutput);
end

% Copyright 2019 The MathWorks, Inc.