This example shows how to create a System
object™ composed
of other System
objects. In this example, build a multi-notch
filter using two dsp.NotchPeakFilter
System
objects. Multi-notch
filters are used in many applications. Examples include audio phasers
and applications that require the removal of multiple interfering
tones.
Create Moving Average System object (MATLAB) explains in
detail how to write a System
object using a template file. In this example, the entire System
object is provided for convenience in dspdemo.CompositeObj_MultiNotch
. To view the MATLAB® code, at the command prompt
enter:
edit dspdemo.CompositeObj_MultiNotch
dspdemo.CompositeObj_MultiNotch
has five public
properties. Public properties are accessible to every user. The first property,
SampleRate
, is a nontunable property. Nontunable properties
cannot change when the filter is locked (after you use step
on the filter). The remaining properties,
CenterFrequency1
, CenterFrequency2
,
QualityFactor1
, and QualityFactor2
control settings in the two notch filters contained in dspdemo.CompositeObj_MultiNotch
. These four properties are tunable.
You can change the values of these properties while streaming data.dspdemo.CompositeObj_MultiNotch
uses dsp.NotchPeakFilter
to design the two notch filters. The notch filters
are set up in the setupImpl
method.
methods (Access=protected) function setupImpl(obj,~) % Construct two notch filters with default values obj.NotchFilter1 = dsp.NotchPeakFilter(... 'Specification', 'Quality factor and center frequency',... 'CenterFrequency',400); obj.NotchFilter2 = dsp.NotchPeakFilter(... 'Specification', 'Quality factor and center frequency',... 'CenterFrequency',800); end end
The ability to create more than one instance of a System
object and having each instance manage its own state is one of the biggest
advantages of using System
objects over functions. The private properties
NotchFilter1
and NotchFilter2
are used
to store the two notch filters.
properties (Access=private) % This example class contains two notch filters (more can be added % in the same way) NotchFilter1 NotchFilter2 end
The SampleRate
property as well as the remaining four public properties
are implemented as dependent properties in this example.
Whenever you assign a value to one of the dependent properties, the value is set in
the corresponding single-notch filter. When you read one of the dependent
properties, the value is read from the corresponding single-notch filter. Find the
following code block in dspdemo.CompositeObj_MultiNotch
.
properties (Dependent) %CenterFrequency1 Center frequency of first notch % Specify the first notch center frequency as a finite positive % numeric scalar in Hertz. The default is 400 Hz. This property % is tunable. CenterFrequency1; %QualityFactor1 Quality factor of first notch % Specify the quality factor (Q factor) for the first notch % filter. The default value is 5. This property is tunable. QualityFactor1; %CenterFrequency2 Center frequency of second notch % Specify the second notch center frequency as a finite positive % numeric scalar in Hertz. The default is 800 Hz. This property % is tunable. CenterFrequency2; %QualityFactor2 Quality factor of second notch % Specify the quality factor (Q factor) for the first notch % filter. The default value is 5. This property is tunable. QualityFactor2; end
To use dspdemo.CompositeObj_MultiNotch
, initialize the
filter and any other required components. In this example, initialize an audio file
reader, a multi-notch filter, a transfer function estimator, an array plotter, and
an audio
player.
FrameSize = 1024; AFR = dsp.AudioFileReader('guitar10min.ogg','SamplesPerFrame',FrameSize); Fs = AFR.SampleRate; MNF = dspdemo.CompositeObj_MultiNotch('SampleRate',Fs); TFE = dsp.TransferFunctionEstimator(... 'FrequencyRange','onesided','SpectralAverages',5); AP = dsp.ArrayPlot('PlotType','Line','YLimits',[-85 15],... 'SampleIncrement',Fs/FrameSize); P = audioDeviceWriter;
To illustrate the tunability of the two notch filter center
frequencies, vary the center frequencies sinusoidally in a loop. The
starting center frequencies are 500 and 2000 Hz. The first center
frequency oscillates over the range [100, 900] Hz with a frequency
of 0.2 Hz. The second center frequency oscillates over the range [1200,
2800] Hz with a frequency of 0.5 Hz. Because CenterFrequency1
and CenterFrequency2
are
dependent properties, modifying their values in the loop changes the
center frequencies in the two notch filters contained in dspdemo.CompositeObj_MultiNotch
.
To visualize the multi-notch filter, estimate and plot the transfer
function continuously. The quality factors remain constant. The simulation
runs for 20 seconds.
MNF.QualityFactor1 = .5; MNF.QualityFactor2 = 1; f0 = 0.2; f1 = 0.5; k = 0; tic, while toc < 20 x = AFR(); t = k*FrameSize/Fs; k = k+1; MNF.CenterFrequency1 = 500 + 400*sin(2*pi*f0*t); MNF.CenterFrequency2 = 2000 + 800*sin(2*pi*f1*t); CF1(k) = MNF.CenterFrequency1; CF2(k) = MNF.CenterFrequency2; y = MNF(x); H = TFE(x(:,1),y(:,1)); magdB = 20*log10(abs(H)); AP(magdB); P(y); end
Execute this code to show how the two notch center frequencies varied over the simulation.
subplot(2,1,1) plot(CF1); title('Center Frequency 1'); ylabel('Notch CF (Hz)'); subplot(2,1,2) plot(CF2); title('Center Frequency 2'); ylabel('Notch CF (Hz)'); xlabel('Iteration')