image thumbnail

Vuvuzela filtering with parametric equalizers using System objects

by

 

29 Jun 2010 (Updated )

This example filters out vuvuzela sounds from an audio stream using parametric equalizer filters.

vuvuzela_denoising_parameq.m
%% Vuvuzela Denoising using Parametric Equalizers
%
% Author: Charulatha Kalluri
%
% Copyright 2010 The MathWorks, Inc.
%

%% Introduction
%
% This example demonstrates how you can design parametric equalizer filters
% in MATLAB and use them to filter out vuvuzela sounds from an audio
% stream. This demo uses Signal Processing Toolbox, Filter Design Toolbox
% and Signal Processing Blockset.

%% Set up input data streams
% First, let us look at how we can create streaming inputs in MATLAB

% Create a System object to read from the audio file

% We need an input audio stream that can read data from a WAV file. To do
% this, we can use the MultimediaFileReader System object

hSound = signalblks.MultimediaFileReader('Vuvuzela.wav',...
                                         'SamplesPerAudioFrame', 1024, ...
                                         'AudioOutputDataType', 'double');

                                     
%Get the input sampling frequency
hInfo = info(hSound);
Fs = hInfo.AudioSampleRate;

%% Create a System object to play back audio to the sound card
hPlayer = signalblks.AudioPlayer('SampleRate', Fs);

%% Create a System object to write to an audio file
hOutputFile = signalblks.MultimediaFileWriter('with_then_without_vuvuzela.wav',...
                                              'SampleRate', Fs);

%% Create System objects for logging pure noise and filtered output signals

hLogNoise = signalblks.SignalLogger;
hLogOutput = signalblks.SignalLogger;

%% Advance input audio by 5 seconds
% The first 5 seconds of the input do not contain any significant data,i.e,
% not even noise, so lets advance the input by 5 seconds, i.e., about 100
% frames. (@Fs =22050Hz, 1024 samples per frame)

for frame_index=1:100
    step(hSound);
end

%% Extract the noise spectrum
%To obtain our pure noise signal, we use a 1-second portion of the
%signal, from 00:05 to 00:06 seconds, that has only the vuvuzela sound, but
%no speech.  1 second -> ~20 frames (@Fs=22050Hz, 1024 samples per frame)

for noise_frames = 1:20
    noise = step(hSound);
    step(hLogNoise, noise);
end

%% Plot noise spectrum and identify vuvuzela frequencies

pwelch(hLogNoise.Buffer, [], [], 8192, Fs);
set(gcf,'Color','white');

%% Identify noise peaks

% Zoom into the plot above to identify the vuvuzela frequencies
openfig('noise_peaks.fig');

% Noise peaks are observed at the following frequencies:
% 235Hz, 476Hz, 735Hz, 940Hz, 1180Hz

%% Designing the parametric equalizers
% Our next task is to design notch parametric equalizers that will
% selectively filter out these frequencies.  Since the notch filters will
% also remove components of the speech signal at the above frequencies, we
% will apply a peak filter to boost the speech signal at the output of the
% notch filters.
%
% To design parametric equalizers, we need to specify filter order, center
% frequency, and the bandwidth or Q-factor of the filter.  To determine the
% bandwidth or Q-factor of the filter, lets take a closer look at the
% noise spectrum. At the lower frequeuncies (235Hz, 465Hz), we see that the
% peaks are sharp. At the higher frequencies, the noise peaks are spread
% across a wider band.  So, for the notch filters at the lower frequencies,
% we specify a narrow stopband, i.e., a high Q, and for higher frequencies,
% we specify a wider stopband, i.e., a low Q.

%% Specifications for notch parametric equalizers

F01 = 235; F02 = 476; F03 = 735; F04 = 940; F05 = 1180;

N = 2; %Filter order
Gref = 0; %Reference gain
G0 = -20; %Attenuate by 20dB
Qa = 10;  %Higher Q-factor for fundamental and 1st harmonic
Qb = 5;   %Lower Q-factor for higher harmonics

f1 = fdesign.parameq('N,F0,Qa,Gref,G0',N,F01,Qa,Gref,G0,Fs);
f2 = fdesign.parameq('N,F0,Qa,Gref,G0',N,F02,Qa,Gref,G0,Fs);
f3 = fdesign.parameq('N,F0,Qa,Gref,G0',N,F03,Qb,Gref,G0,Fs);
f4 = fdesign.parameq('N,F0,Qa,Gref,G0',N,F04,Qb,Gref,G0,Fs);
f5 = fdesign.parameq('N,F0,Qa,Gref,G0',N,F05,Qb,Gref,G0,Fs);

%% Specifications for peak parametric equalizer

N_peak = 8; %Use higher filter order for peak filter
F06 = 480;  %Center frequency to boost
Qc = 0.5;   %Use very low Q-factor for boost equalizer filter
G1 = 9;     %Boost gain by 9dB

f6 = fdesign.parameq('N,F0,Qa,Gref,G0',N_peak,F06,Qc,Gref,G1,Fs);

%% Design filters and visualize responses

Hp1 = design(f1, 'butter');
Hp2 = design(f2, 'butter');
Hp3 = design(f3, 'butter');
Hp4 = design(f4, 'butter');
Hp5 = design(f5, 'butter');
Hp6 = design(f6, 'butter');

hFV = fvtool([Hp1 Hp2 Hp3 Hp4 Hp5 Hp6], 'Color', 'white');
legend(hFV,'NotchEQ #1', 'NotchEQ #2', 'NotchEQ #3', 'NotchEQ #4','NotchEQ #5','Peak EQ');

%% Implement filters using second-order sections

hEQ1 = signalblks.BiquadFilter('SOSMatrix',Hp1.sosMatrix,'ScaleValues',Hp1.ScaleValues);
hEQ2 = signalblks.BiquadFilter('SOSMatrix',Hp2.sosMatrix,'ScaleValues',Hp2.ScaleValues);
hEQ3 = signalblks.BiquadFilter('SOSMatrix',Hp3.sosMatrix,'ScaleValues',Hp3.ScaleValues);
hEQ4 = signalblks.BiquadFilter('SOSMatrix',Hp4.sosMatrix,'ScaleValues',Hp4.ScaleValues);
hEQ5 = signalblks.BiquadFilter('SOSMatrix',Hp5.sosMatrix,'ScaleValues',Hp5.ScaleValues);
hEQ6 = signalblks.BiquadFilter('SOSMatrix',Hp6.sosMatrix,'ScaleValues',Hp6.ScaleValues);

%% Stream processing loop to filter out vuvuzela noise

%Note: To process the entire data,use a while loop instead of a for loop
%while (~isDone(hSound))

%Filter 400 frames of input data
for frames = 1:400
    %Step through input WAV file one frame at a time
    input = step(hSound);
    
    %Apply notch EQ filters first, then peak EQ filter
    out1 = step(hEQ1, input);
    out2 = step(hEQ2, out1);
    out3 = step(hEQ3, out2);
    out4 = step(hEQ4, out3);        
    out5 = step(hEQ5, out4);
    denoised_sig = step(hEQ6, out5);
    
    %Play 200 frames of input signal, then 200 frames of filtered output
    %to compare original and filtered signals
    %Log the audio output to a WAV file
    if frames < 200
      step(hPlayer, input);
      step(hOutputFile, input);
    else 
       step(hPlayer, denoised_sig);
       step(hOutputFile, denoised_sig);
    end
   
   %Log filtered output to buffer
   step(hLogOutput, denoised_sig);
end

%% Plot filtered signal spectrum

% Heres the power spectrum of the filtered signal.  If you zoom into the
% plot, you can see that the vuvuzela frequencies have been attenuated by
% our notch equalizer filters:
figure; pwelch(hLogOutput.Buffer, [], [], 8192, Fs);
set(gcf,'Color','white');

%% Cleanup 

%Close input and output stream System objects

close(hSound);
close(hPlayer);
close(hOutputFile);

Contact us