

10.3 Audio processing
Audio signals, much like images, can undergo filtering. It is somewhat easier to understand the impact of signal processing on audio, since audio needs not be translated from a spatial to a frequency domain.
To load a wave (PCM) audio file, Matlab provides the function
wavread
:
funky = wavread('funky.wav');

It's important to capture the sampling frequency at which the sound was recorded, otherwise the speed of playback and results of further processing is not guaranteed to be correct:
[funky, f] = wavread('funky.wav');

To play a wave file at sampling frequency
f:
To view the waveform, plot the wave. Since audio is represented with many thousand samples per second, it may be required to plot small portions of the waveform at a time.
subplot(2,1,1), plot(funky), title('Entire waveform'); smallRange = 100000:100000+floor(f/100); subplot(2,1,2), plot(smallRange, funky(smallRange)), title('100 milliseconds');



Figure 10.26 Click image to enlarge, or click here to open


10.3.1 Spectrogram
2dimensional plots of audio waves can be used to easily identify magnitude; however, combined frequency distributions and magnitudes are more easily viewed in a spectrogram:
where 512 is the number of samples that are used for the discrete Fourier Transform, and thus a grouping factor of samples per column in the spectrogram image.


Figure 10.27 Click image to enlarge, or click here to open


Plotting both the original waveform and the spectrogram, it is possible to find correspondences between the two graphical representations:
subplot(2,1,1), plot(funky), axis('tight'); subplot(2,1,2), specgram(funky,128,f);



Figure 10.28 Click image to enlarge, or click here to open


However, it is easier to find such similarities in smaller portions of audio. We can also find repeating patters:
subplot(2,1,1), plot(funky(100000:150000)), axis('tight'); subplot(2,1,2), specgram(funky(100000:150000),128,f);



Figure 10.29 Click image to enlarge, or click here to open


10.3.2 Filtering
We will examine audio filtering in the sense of specific frequency suppression and extraction. There are many different types of filters available for the construction of filters. We will specifically use the Butterworth filter.
Matlab includes function
butter
for building Butterworth filters of three sorts:

'low'
: Lowpass filters, which remove frequencies greater than some specified value.

'high'
: Highpass filters, which remove frequencies lower than some specified value.

'stop'
: Stopband filters, which remove frequencies in a given range of values.
Frequencies values are specified in normalized terms between 0.0 and 1.0, where 1.0 corresponds to half the sampling frequency:
f/2. A given frequency is thus expressed in terms of this value, for example, 1000Hz = 1000/(f/2).
Filters are described in terms of 2 vectors ([b, a] = [numerator, denominator]).
To apply a filter to a 1D audio waveform, Matlab provides function
filtfilt
, which takes as arguments the result [b, a] from butter, the waveform, and a value denoting the order (number of coefficients) of the filter.
A filter's frequency response can be plotted using function
freqz
. Magnitude values at zero dB are unaffected by the filter. Magnitude values below 0 dB are suppressed.
We design a 10th order lowpass filter to supress frequencies higher than 200Hz.
fNorm = 200 / (f/2); [b,a] = butter(10, fNorm, 'low'); funkyLow = filtfilt(b, a, funky);

The frequency response for this filter:


Figure 10.30 Click image to enlarge, or click here to open


Playing the new audio waveform clearly reveals that low (bass) frequencies are preserved, while all higher frequencies have been suppressed.
We design a 10th order highpass filter to supress frequencies below 5kHz.
fNorm = 5000 / (f/2); [b, a] = butter(10, fNorm, 'high'); funkyHigh = filtfilt(b, a, funky);

The frequency response for this filter:


Figure 10.31 Click image to enlarge, or click here to open


Playing the new audio waveform reveals only highpitched tones.
fNorm = [500/(f/2), 2500/(f/2)]; [b, a] = butter(10, fNorm, 'stop'); funkyBand = filtfilt(b, a, funky);

The frequency response for this filter:


Figure 10.32 Click image to enlarge, or click here to open



