ivan@81
|
1 function y=synth(freq,dur,amp,Fs,type)
|
ivan@81
|
2 % y=synth(freq,dur,amp,Fs,type)
|
ivan@81
|
3 %
|
ivan@81
|
4 % Synthesize a single note
|
ivan@81
|
5 %
|
ivan@81
|
6 % Inputs:
|
ivan@81
|
7 % freq - frequency in Hz
|
ivan@81
|
8 % dur - duration in seconds
|
ivan@81
|
9 % amp - Amplitude in range [0,1]
|
ivan@81
|
10 % Fs - sampling frequency in Hz
|
ivan@81
|
11 % type - string to select synthesis type
|
ivan@81
|
12 % current options: 'fm', 'sine', or 'saw'
|
ivan@81
|
13
|
ivan@81
|
14 % Copyright (c) 2009 Ken Schutte
|
ivan@81
|
15 % more info at: http://www.kenschutte.com/midi
|
ivan@81
|
16
|
ivan@81
|
17 if nargin<5
|
ivan@81
|
18 error('Five arguments required for synth()');
|
ivan@81
|
19 end
|
ivan@81
|
20
|
ivan@81
|
21 N = floor(dur*Fs);
|
ivan@81
|
22
|
ivan@81
|
23 if N == 0
|
ivan@81
|
24 warning('Note with zero duration.');
|
ivan@81
|
25 y = [];
|
ivan@81
|
26 return;
|
ivan@81
|
27
|
ivan@81
|
28 elseif N < 0
|
ivan@81
|
29 warning('Note with negative duration. Skipping.');
|
ivan@81
|
30 y = [];
|
ivan@81
|
31 return;
|
ivan@81
|
32 end
|
ivan@81
|
33
|
ivan@81
|
34 n=0:N-1;
|
ivan@81
|
35 if (strcmp(type,'sine'))
|
ivan@81
|
36 y = amp.*sin(2*pi*n*freq/Fs);
|
ivan@81
|
37
|
ivan@81
|
38 elseif (strcmp(type,'saw'))
|
ivan@81
|
39
|
ivan@81
|
40 T = (1/freq)*Fs; % period in fractional samples
|
ivan@81
|
41 ramp = (0:(N-1))/T;
|
ivan@81
|
42 y = ramp-fix(ramp);
|
ivan@81
|
43 y = amp.*y;
|
ivan@81
|
44 y = y - mean(y);
|
ivan@81
|
45
|
ivan@81
|
46 elseif (strcmp(type,'fm'))
|
ivan@81
|
47
|
ivan@81
|
48 t = 0:(1/Fs):dur;
|
ivan@81
|
49 envel = interp1([0 dur/6 dur/3 dur/5 dur], [0 1 .75 .6 0], 0:(1/Fs):dur);
|
ivan@81
|
50 I_env = 5.*envel;
|
ivan@81
|
51 y = envel.*sin(2.*pi.*freq.*t + I_env.*sin(2.*pi.*freq.*t));
|
ivan@81
|
52
|
ivan@81
|
53 else
|
ivan@81
|
54 error('Unknown synthesis type');
|
ivan@81
|
55 end
|
ivan@81
|
56
|
ivan@81
|
57 % smooth edges w/ 10ms ramp
|
ivan@81
|
58 if (dur > .02)
|
ivan@81
|
59 L = 2*fix(.01*Fs)+1; % L odd
|
ivan@81
|
60 ramp = bartlett(L)'; % odd length
|
ivan@81
|
61 L = ceil(L/2);
|
ivan@81
|
62 y(1:L) = y(1:L) .* ramp(1:L);
|
ivan@81
|
63 y(end-L+1:end) = y(end-L+1:end) .* ramp(end-L+1:end);
|
ivan@81
|
64 end
|