Sunteți pe pagina 1din 41

CM0340 Tutorial 5: MATLAB BASIC DSP

and Synthesis
1

In this tutorial we explain some of the DSP and MATLAB concepts


discussed in the lectures leading up to Digital Audio Synthesis.

We start by looking at basic signal waveforms.

JJ
The code that is used over the next few slides is waveforms.m II
J
I
Back
Close
Simple Waveforms

• Frequency is the number of cycles per second and is measured in


Hertz (Hz)
• Wavelength is inversely proportional to frequency JJ
1 II
i.e. Wavelength varies as f requency J
I
Back
Close
The Sine Wave and Sound

The general form of the sine wave we shall use (quite a lot of) is as
follows:
y = A.sin(2π.n.Fw /Fs)
where:

A is the amplitude of the wave, JJ


Fw is the frequency of the wave, II
Fs is the sample frequency, J
n is the sample index. I
MATLAB function: sin() used — works in radians Back
Close
MATLAB Sine Wave Radian Frequency
Period
Basic 1 period Simple Sine wave — 1 period is 2π radians
4

% Basic 1 period Simple Sine wave

i=0:0.2:2*pi;
y = sin(i);
figure(1)
plot(y);

% use stem(y) as alternative plot as in lecture notes to


% see sample values

title(’Simple 1 Period Sine Wave’); JJ


II
J
I
Back
Close
MATLAB Sine Wave Amplitude

Sine Wave Amplitude is -1 to +1.


5

To change amplitude multiply by some gain (amp):

% Now Change amplitude

amp = 2.0;

y = amp*sin(i);

figure(2)
plot(y); JJ
title(’Simple 1 Period Sine Wave Modified Amplitude’);
II
J
I
Back
Close
MATLAB Sine Wave Frequency
% Natural frequency is 2*pi radians
% If sample rate is F_s HZ then 1 HZ is 2*pi/F_s
% If wave frequency is F_w then freequency is F_w* (2*pi/F_s)
% set n samples steps up to sum duration nsec*F_s where nsec is the 6
% duration in seconds
% So we get y = amp*sin(2*pi*n*F_w/F_s);

F_s = 11025;
F_w = 440;
nsec = 2;
dur= nsec*F_s;

n = 0:dur;

y = amp*sin(2*pi*n*F_w/F_s);

figure(3)
plot(y(1:500));
JJ
title(’N second Duration Sine Wave’); II
J
I
Back
Close
MATLAB Sine Wave Plot of n cycles

7
% To plot n cycles of a waveform

ncyc = 2;

n=0:floor(ncyc*F_s/F_w);

y = amp*sin(2*pi*n*F_w/F_s);

figure(4)
plot(y);
title(’N Cycle Duration Sine Wave’);

JJ
II
J
I
Back
Close
Cosine, Square and Sawtooth Waveforms
MATLAB functions cos() (cosine), square() and sawtooth()
similar.
8

JJ
II
J
I
Back
Close
MATLAB Cos v Sin Wave
% Cosine is same as Sine (except 90 degrees out of phase)

yc = amp*cos(2*pi*n*F_w/F_s);
9
figure(5);
hold on
plot(yc,’b’);
plot(y,’r’);
title(’Cos (Blue)/Sin (Red) Plot (Note Phase Difference)’);
hold off;

JJ
II
J
I
Back
Close
Relationship Between Amplitude,
Frequency and Phase
10

JJ
II
J
I
Back
Close
Amplitudes of a Sine Wave
% Simple Sin Amplitude Demo

samp_freq = 400;
dur = 800; % 2 seconds 11
amp = 1; phase = 0; freq = 1;
s1 = mysin(amp,freq,phase,dur,samp_freq);

axisx = (1:dur)*360/samp_freq; % x axis in degrees


plot(axisx,s1);
set(gca,’XTick’,[0:90:axisx(end)]);

fprintf(’Initial Wave: \t Amplitude = ...\n’, amp, freq, phase,...);

% change amplitude
amp = input(’\nEnter Ampltude:\n\n’);

s2 = mysin(amp,freq,phase,dur,samp_freq);
hold on;
JJ
plot(axisx, s2,’r’); II
set(gca,’XTick’,[0:90:axisx(end)]); J
The code is sinampdemo.m
I
Back
Close
mysin MATLAB code
The above call function mysin.m which a simple modified version
of previous MATLAB sin function to account for phase.
function s = mysin(amp,freq,phase,dur, samp_freq) 12
% example function to so show how amplitude,frequency and phase
% are changed in a sin function
% Inputs: amp - amplitude of the wave
% freq - frequency of the wave
% phase - phase of the wave in degree
% dur - duration in number of samples
% samp_freq - sample frequncy

x = 0:dur-1;
phase = phase*pi/180;

s = amp*sin( 2*pi*x*freq/samp_freq + phase); JJ


II
J
I
Back
Close
Amplitudes of a Sine Wave: sinampdemo
output
1

13
0.8

0.6

0.4

0.2

−0.2

−0.4

−0.6

−0.8 JJ
−1
II
0 90 180 270 360 450 540 630 720
J
I
Back
Close
Frequencies of a Sine Wave
% Simple Sin Frequency Demo

samp_freq = 400;
dur = 800; % 2 seconds 14
amp = 1; phase = 0; freq = 1;
s1 = mysin(amp,freq,phase,dur,samp_freq);

axisx = (1:dur)*360/samp_freq; % x axis in degrees


plot(axisx,s1);
set(gca,’XTick’,[0:90:axisx(end)]);

fprintf(’Initial Wave: \t Amplitude = ...\n’, amp, freq, phase,...);

% change amplitude
freq = input(’\nEnter Frequency:\n\n’);

s2 = mysin(amp,freq,phase,dur,samp_freq);
hold on;
JJ
plot(axisx, s2,’r’); II
set(gca,’XTick’,[0:90:axisx(end)]); J
The code is sinfreqdemo.m
I
Back
Close
Amplitudes of a Sine Wave: sinfreqdemo
output
1

15
0.8

0.6

0.4

0.2

−0.2

−0.4

−0.6

−0.8 JJ
−1
0 90 180 270 360 450 540 630 720
II
J
I
Back
Close
Phases of a Sine Wave
% Simple Sin Phase Demo

samp_freq = 400;
dur = 800; % 2 seconds
16
amp = 1; phase = 0; freq = 1;
s1 = mysin(amp,freq,phase,dur,samp_freq);

axisx = (1:dur)*360/samp_freq; % x axis in degrees


plot(axisx,s1);
set(gca,’XTick’,[0:90:axisx(end)]);

fprintf(’Initial Wave: \t Amplitude = ...\n’, amp, freq, phase,...);

% change amplitude
phase = input(’\nEnter Phase:\n\n’);

s2 = mysin(amp,freq,phase,dur,samp_freq);
hold on;
JJ
plot(axisx, s2,’r’); II
set(gca,’XTick’,[0:90:axisx(end)]); J
The code is sinphasedemo.m I
Back
Close
Amplitudes of a Sine Wave: sinphasedemo
output
1

17
0.8

0.6

0.4

0.2

−0.2

−0.4

−0.6

−0.8 JJ
−1
0 90 180 270 360 450 540 630
II
J
I
Back
Close
MATLAB Square and Sawtooth Waveforms
% Square and Sawtooth Waveforms created using Radians

ysq = amp*square(2*pi*n*F_w/F_s);
ysaw = amp*sawtooth(2*pi*n*F_w/F_s); 18

figure(6);
hold on
plot(ysq,’b’);
plot(ysaw,’r’);
title(’Square (Blue)/Sawtooth (Red) Waveform Plots’);
hold off;

JJ
II
J
I
Back
Close
Triangular Waveform
MATLAB function sawtooth(t,width = 0.5) can create a
triangular waveform, but its easy to build one ourselves (later we
make a smoother sounding sawtooth in similar fashion):
% Half Frequency 19
delta = 2*F_w/F_s;
% min and max values of simple waveform
minf=0;maxf=1;
% create triangle wave of centre frequency values
figure(7); hold on
ytri = [];
% plot n cycles
while(length(ytri) < floor(ncyc*F_s/F_w) )
ytri = [ ytri amp*(minf:delta:maxf) ]; %upslope
doplot = input(’\nPlot Figure? y/[n]:\n\n’, ’s’);
if doplot == ’y’,
plot(ytri,’r’);
figure(7);
end
lasti = length(ytri);
ytri = [ ytri amp*(maxf:-delta:minf) ]; %downslope JJ
doplot = input(’\nPlot Figure? y/[n]:\n\n’, ’s’);
if doplot == ’y’, II
plot(ytri,’b’);
figure(7); J
end
end I
title(’Triangular Waveform Plots’); hold off; Back
Close
Triangular Waveform Display
2

1.8

1.6
20

1.4

1.2

0.8

0.6

0.4 JJ
II
0.2 J
I
0
0 5 10 15 20 25 30 35 40 Back
Close
Using these Waveforms
All above waveforms used (as seen in Lecture notes):
• Base waveforms for various forms of synthesis: Subtractive, FM,
21
Additive
• Modulators and Carrier waveforms for various Digital Audio
effects.
– Low Frequency Oscillators (LFO) to vary filter cut-off
frequencies and delay times

JJ
II
J
I
Back
Close
MATLAB filters
Matlab filter() function implements an IIR
(or an FIR no A components).
22
Type help filter:
FILTER One-dimensional digital filter.
Y = FILTER(B,A,X) filters the data in vector X with the
filter described by vectors A and B to create the filtered
data Y. The filter is a "Direct Form II Transposed"
implementation of the standard difference equation:

a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)


- a(2)*y(n-1) - ... - a(na+1)*y(n-na)

If a(1) is not equal to 1, FILTER normalizes the filter


coefficients by a(1). JJ
FILTER always operates along the first non-singleton dimension,
II
namely dimension 1 for column vectors and non-trivial matrices, J
and dimension 2 for row vectors. I
Back
Close
A Complete IIR System
x(n) x(n − 1) x(n − 2) x(n − N + 1)
T T T

23
× b0 × b1 × b2 × bN −2 × bN −1

y(n)
+ + + + +

× −aM × −aM −1 × −aM −2 × −a1

T T T
y(n − M ) y(n − 1)

JJ
Here we extend:
II
The input delay line up to N − 1 elements and
J
The output delay line by M elements.
I
Back
Close
Complete IIR System Algorithm
x(n) x(n − 1) x(n − 2) x(n − N + 1)
T T T

× b0 × b1 × b2 × bN −2 × bN −1
24
y(n)
+ + + + +

× −aM × −aM −1 × −aM −2 × −a1

T T T
y(n − M ) y(n − 1)

We can represent the IIR system algorithm by the difference


equation:
M
X N −1
X JJ
y(n) = − ak y(n − k) + bk x(n − k) II
k=1 k=0 J
I
Back
Close
Using filter() in Practice
We have two filter banks defined by vectors: A = {ak }, B = {bk }.
We have to specify some values for them.
25
• We can do this by hand — we could design our own filters
• MATLAB provides standard functions to set up A and B for
many common filters.

JJ
II
J
I
Back
Close
Using filter() in Practice:Hand Coding
Recall from lecture notes:
The MATLAB file IIRdemo.m sets up the filter banks as follows:
26
fg=4000;
fa=48000;
k=tan(pi*fg/fa);

b(1)=1/(1+sqrt(2)*k+kˆ2);
b(2)=-2/(1+sqrt(2)*k+kˆ2);
b(3)=1/(1+sqrt(2)*k+kˆ2);
a(1)=1;
a(2)=2*(kˆ2-1)/(1+sqrt(2)*k+kˆ2);
a(3)=(1-sqrt(2)*k+kˆ2)/(1+sqrt(2)*k+kˆ2);

and then applies the difference equation:


JJ
for n=1:N
y(n)=b(1)*x(n) + b(2)*xh1 + b(3)*xh2 - a(2)*yh1 - a(3)*yh2; II
xh2=xh1;xh1=x(n); J
yh2=yh1;yh1=y(n); I
end;
Back
Close
Filtering with IIR: Simple Example Output
This produces the following output:

0.5
27
x(n) →

−0.5

−1

0 2 4 6 8 10 12 14 16 18
n→

0.5
y(n) →

0
JJ
−0.5 II
−1 J
0 2 4 6 8 10 12 14 16 18 I
n→
Back
Close
Using MATLAB to make filters
MATLAB provides a few built-in functions to create ready made
filter parameter A and B :
E.g: butter, buttord, besself, cheby1, cheby2, 28
ellip, freqz, filter.
For our purposes the Butterworth filter will create suitable filters,
help butter:
BUTTER Butterworth digital and analog filter design.
[B,A] = BUTTER(N,Wn) designs an Nth order lowpass digital
Butterworth filter and returns the filter coefficients in length
N+1 vectors B (numerator) and A (denominator). The coefficients
are listed in descending powers of z. The cutoff frequency
Wn must be 0.0 < Wn < 1.0, with 1.0 corresponding to
half the sample rate.

If Wn is a two-element vector, Wn = [W1 W2], BUTTER returns an


JJ
order 2N bandpass filter with passband W1 < W < W2. II
[B,A] = BUTTER(N,Wn,’high’) designs a highpass filter. J
[B,A] = BUTTER(N,Wn,’low’) designs a lowpass filter.
[B,A] = BUTTER(N,Wn,’stop’) is a bandstop filter if Wn = [W1 W2].
I
Back
Close
Using MATLAB to make filters
help buttord:
BUTTORD Butterworth filter order selection.
[N, Wn] = BUTTORD(Wp, Ws, Rp, Rs) returns the order N of the lowest
order digital Butterworth filter that loses no more than Rp dB in
the passband and has at least Rs dB of attenuation in the stopband.
Wp and Ws are the passband and stopband edge frequencies, normalized 29
from 0 to 1 (where 1 corresponds to pi radians/sample). For example,
Lowpass: Wp = .1, Ws = .2
Highpass: Wp = .2, Ws = .1
Bandpass: Wp = [.2 .7], Ws = [.1 .8]
Bandstop: Wp = [.1 .8], Ws = [.2 .7]
BUTTORD also returns Wn, the Butterworth natural frequency (or,
the "3 dB frequency") to use with BUTTER to achieve the
specifications.

JJ
II
J
I
Back
Close
Using MATLAB Filter Example: Subtractive Synthesis Lecture
Example
The example for studying subtractive synthesis, subtract synth.m,
uses the butter and filter MATLAB functions:
% simple low pas filter example of subtractive synthesis 30
Fs = 22050;
y = synth(440,2,0.9,22050,’saw’);

% play sawtooth e.g. waveform


doit = input(’\nPlay Raw Sawtooth? Y/[N]:\n\n’, ’s’);
if doit == ’y’,
figure(1)
plot(y(1:440));
playsound(y,Fs);
end

%make lowpass filter and filter y


[B, A] = butter(1,0.04, ’low’); JJ
yf = filter(B,A,y);
II
[B, A] = butter(4,0.04, ’low’); J
yf2 = filter(B,A,y);
I
Back
Close
% play filtererd sawtooths
doit = ...
input(’\nPlay Low Pass Filtered (Low order) ? Y/[N]:\n\n’, ’s’);
if doit == ’y’,
figure(2)
plot(yf(1:440));
playsound(yf,Fs);
end 31

doit = ...
input(’\nPlay Low Pass Filtered (Higher order)? Y/[N]:\n\n’, ’s’);
if doit == ’y’,
figure(3)
plot(yf2(1:440));
playsound(yf2,Fs);
end

%plot figures
doit = input(’\Plot All Figures? Y/[N]:\n\n’, ’s’);
if doit == ’y’,
figure(4)
plot(y(1:440));
JJ
hold on II
plot(yf(1:440),’r+’); J
plot(yf2(1:440),’g-’);
end I
Back
Close
synth.m
The supporting function, synth.m, generates waveforms as we have
seen earlier in this tutorial:
function y=synth(freq,dur,amp,Fs,type)
% y=synth(freq,dur,amp,Fs,type)
% 32
% Synthesize a single note
%
% Inputs:
% freq - frequency in Hz
% dur - duration in seconds
% amp - Amplitude in range [0,1]
% Fs - sampling frequency in Hz
% type - string to select synthesis type
% current options: ’fm’, ’sine’, or ’saw’

if nargin<5
error(’Five arguments required for synth()’);
end JJ
N = floor(dur*Fs); II
n=0:N-1; J
if (strcmp(type,’sine’))
y = amp.*sin(2*pi*n*freq/Fs);
I
Back
Close
elseif (strcmp(type,’saw’))

T = (1/freq)*Fs; % period in fractional samples


ramp = (0:(N-1))/T;
y = ramp-fix(ramp);
y = amp.*y;
y = y - mean(y);
33
elseif (strcmp(type,’fm’))

t = 0:(1/Fs):dur;
envel = interp1([0 dur/6 dur/3 dur/5 dur], [0 1 .75 .6 0], 0:(1/Fs):dur);
I_env = 5.*envel;
y = envel.*sin(2.*pi.*freq.*t + I_env.*sin(2.*pi.*freq.*t));

else
error(’Unknown synthesis type’);
end

% smooth edges w/ 10ms ramp


if (dur > .02)
L = 2*fix(.01*Fs)+1; % L odd
JJ
ramp = bartlett(L)’; % odd length II
L = ceil(L/2); J
y(1:L) = y(1:L) .* ramp(1:L);
y(end-L+1:end) = y(end-L+1:end) .* ramp(end-L+1:end); I
end Back
Close
synth.m (Cont.)

Note the sawtooth waveform generated here has a non-linear up slope:


0.2

0.15

0.1
34
0.05

−0.05

−0.1

−0.15
0 10 20 30 40 50 60 70 80 90 100

This is created with:


ramp = (0:(N-1))/T;
y = ramp-fix(ramp);
JJ
fix rounds the elements of X to the nearest integers towards zero. II
J
This form of sawtooth sounds slightly less harsh and is more suitable I
for audio synthesis purposes. Back
Close
Wavetable Synthesis Examples
Simple form as discussed in Lectures is a simple creation one sine
wave and one saw and then some simple cross-fading between the
waves. The simple example , : 35
% simple example of Wavetable synthesis

f1 = 440; f2 = 500; f3 = 620;


Fs = 22050;

%Create a single sine waves of frequencie f1


y1 = synth(f1,1/f1,0.9,Fs,’sine’);

doit = input(’\nPlay/Plot Raw Sine y1 looped for 10 ...


seconds? Y/[N]:\n\n’, ’s’);
if doit == ’y’,
figure(1)
plot(y1); JJ
loopsound(y1,Fs,10*Fs/f1); II
end J
%Create a single Saw waves of frequencie f2 I
y2 = synth(f2,1/f2,0.9,Fs,’saw’); Back
Close
doit = input(’\nPlay/Plot Raw saw y2 looped for 10 ...
seconds? Y/[N]:\n\n’, ’s’);
if doit == ’y’,
figure(2)
plot(y2);
loopsound(y2,Fs,10*Fs/f2);
end 36

%concatenate wave
ywave = [y1 , y2];

% Create Cross fade half width of wave y1 for xfade window


xfadewidth = floor(Fs/(f1*2));
ramp1 = (0:xfadewidth)/xfadewidth;
ramp2 = 1 - ramp1;

doit = input(’\nShow Crossfade Y/[N]:\n\n’, ’s’);


if doit == ’y’,
figure(4)
plot(ramp1);
hold on;
JJ
plot(ramp2,’r’); II
end; J
%apply crossfade centered over the join of y1 and y2 I
pad = (Fs/f1) + (Fs/f2) - 2.5*xfadewidth; Back
Close
xramp1 = [ones(1,1.5*xfadewidth) , ramp2, zeros(1,pad)];
xramp2 = [zeros(1,1.5*xfadewidth) , ramp1, ones(1,pad)];

% Create two period waveforms to fade between


ywave2 = [y1 , zeros(1,Fs/f2)];
ytemp = [zeros(1,Fs/f1), y2];

ywave = ywave2; 37
% do xfade

% add two waves together over the period modulated by xfade ramps
% (recall .* to multiply matrices element by element
% NOT MATRIX mutliplication

ywave2 = xramp1.*ywave2 + xramp2.*ytemp;

doit = input(’\nPlay/Plot Additive Sines together? Y/[N]:\n\n’, ’s’);


if doit == ’y’,
figure(5)

subplot(4,1,1);
plot(ywave);
JJ
II
hold off J
set(gca,’fontsize’,18); I
ylabel(’Amplitude’); Back
Close
title(’Wave 1’);
set(gca,’fontsize’,18);
subplot(4,1,2);
plot(ytemp);
set(gca,’fontsize’,18);
ylabel(’Amplitude’);
title(’Wave 2’);
set(gca,’fontsize’,18); 38
subplot(4,1,3);
plot(xramp1);
hold on
plot(xramp2,’r’)
hold off
set(gca,’fontsize’,18);
ylabel(’Amplitude’);
title(’Crossfade Masks’);
set(gca,’fontsize’,18);
subplot(4,1,4);
plot(ywave2);
set(gca,’fontsize’,18);
ylabel(’Amplitude’);
title(’WaveTable Synthesis’);
JJ
set(gca,’fontsize’,18); II
loopsound(ywave2,Fs,10*Fs/(f1 + f2)); J
end
I
Back
Close
RECAP: Wavetable synthesis:Dynamic Waveshaping (1)

Simplest idea: Linear crossfading


• Crossfade from one wavetable to the next sequentially. 39

• Crossfade = apply some envelope to smoothly merge waveforms.

JJ
II
J
I
Back
Close
Simple MATLAB Example: Linear Crossfading

% Create Cross fade half width of wave y1 for xfade window


xfadewidth = floor(Fs/(f1*2)); 40
ramp1 = (0:xfadewidth)/xfadewidth;
ramp2 = 1 - ramp1;

%apply crossfade centered over the join of y1 and y2


pad = (Fs/f1) + (Fs/f2) - 2.5*xfadewidth;
xramp1 = [ones(1,1.5*xfadewidth) , ramp2, zeros(1,pad)];
xramp2 = [zeros(1,1.5*xfadewidth) , ramp1, ones(1,pad)];
% Create two period waveforms to fade between
ywave2 = [y1 , zeros(1,Fs/f2)];
ytemp = [zeros(1,Fs/f1), y2];

% do xfade
% add two waves together over the period modulated by xfade ramps JJ
ywave2 = xramp1.*ywave2 + xramp2.*ytemp;
II
J
I
Back
Close
Simple MATLAB Example: Linear Crossfading (Cont.)
Wave 1
1

Amplitude
0

−1
0 20 40 60 80 100
Wave 2
Amplitude 0.5 41

−0.5
0 20 40 60 80 100
Crossfade Masks
1
Amplitude

0.5

0
0 20 40 60 80 100
WaveTable Synthesis
1
Amplitude

−1
0 20 40 60 80 100
JJ
II
J
Note: This sort of technique is useful to create an ADSR envelope I
in MATLAB Back
Close

S-ar putea să vă placă și