tomwalters@0
|
1 % support file for 'aim-mat'
|
tomwalters@0
|
2 %
|
tomwalters@0
|
3 % This external file is included as part of the 'aim-mat' distribution package
|
bleeck@3
|
4 % (c) 2011, University of Southampton
|
bleeck@3
|
5 % Maintained by Stefan Bleeck (bleeck@gmail.com)
|
bleeck@3
|
6 % download of current version is on the soundsoftware site:
|
bleeck@3
|
7 % http://code.soundsoftware.ac.uk/projects/aimmat
|
bleeck@3
|
8 % documentation and everything is on http://www.acousticscale.org
|
bleeck@3
|
9
|
tomwalters@0
|
10
|
tomwalters@0
|
11 function f=spectrogram(sig,nr_f,maxfre)
|
tomwalters@0
|
12
|
tomwalters@0
|
13 nsig=changesr(sig,maxfre*2);
|
tomwalters@0
|
14 sr=getsr(nsig);
|
tomwalters@0
|
15 vals=getvalues(nsig);
|
tomwalters@0
|
16
|
tomwalters@0
|
17 % sig_len=getlength(sig);
|
tomwalters@0
|
18 % time_step=sig_len/nr_t;
|
tomwalters@0
|
19 % window=[0:time_step:sig_len];
|
tomwalters@0
|
20 % win_len=getnrpoints(nsig)/nr_t;
|
tomwalters@0
|
21 % window = hann(round(win_len));
|
tomwalters@0
|
22 % noverlap=round(win_len/2);
|
tomwalters@0
|
23 noverlap=nr_f*2-2;
|
tomwalters@0
|
24 [Bb,freqs,ts]=specgram(vals,nr_f*2,sr*2,[],noverlap);
|
tomwalters@0
|
25
|
tomwalters@0
|
26 B=Bb(2:nr_f+1,:);
|
tomwalters@0
|
27
|
tomwalters@0
|
28 nr_t=size(B,2);
|
tomwalters@0
|
29 nr_f=size(B,1);
|
tomwalters@0
|
30
|
tomwalters@0
|
31 srf=nr_t/getlength(sig);
|
tomwalters@0
|
32 f=field(nr_t,nr_f,srf);
|
tomwalters@0
|
33 f=setvalues(f,abs(B));
|
tomwalters@0
|
34 f=setmaxfre(f,maxfre);
|
tomwalters@0
|
35
|
tomwalters@0
|
36 return
|
tomwalters@0
|
37
|
tomwalters@0
|
38
|
tomwalters@0
|
39
|
tomwalters@0
|
40
|
tomwalters@0
|
41 % function f=spectrogram(sig,tstart,tstop,nr_t,nr_f,maxfre)
|
tomwalters@0
|
42 % alle Zeiten in Sekunden
|
tomwalters@0
|
43 % macht ein Sektrogramm aus dem Signal sig, das zu nr_t Zeiten gesampelt
|
tomwalters@0
|
44 % wird und nr_f Frequenzen hat
|
tomwalters@0
|
45 % das Signal wird aus sig in der Zeit von start bis stop genommen
|
tomwalters@0
|
46 % das Signal sig wird erst so auf eine Samplerate gebracht, dass
|
tomwalters@0
|
47 % das Resultat der FFT eine Auflösung bis maxfre hat.
|
tomwalters@0
|
48
|
tomwalters@0
|
49 if nargin<6
|
tomwalters@0
|
50 maxfre=GetSR(sig)/2;
|
tomwalters@0
|
51 end
|
tomwalters@0
|
52
|
tomwalters@0
|
53 % die alte (orginale) Samplerate
|
tomwalters@0
|
54 sr_old=GetSR(sig);
|
tomwalters@0
|
55
|
tomwalters@0
|
56 %wenn die maxfre anders ist als die, die das Signal mitbringt, dann muss das Signal heruntergesamplet werden:
|
tomwalters@0
|
57 if sr_old~=maxfre*2
|
tomwalters@0
|
58 sr_neu=maxfre*2;
|
tomwalters@0
|
59 sig=changesr(sig,sr_neu); % änder das ganze Signal zu der neuen SR
|
tomwalters@0
|
60 else
|
tomwalters@0
|
61 sr_neu=sr_old;
|
tomwalters@0
|
62 end
|
tomwalters@0
|
63
|
tomwalters@0
|
64 % Punkte, die die FFT benötigt, damit nr_f punkte hinten raus kommen
|
tomwalters@0
|
65 nr_fft=nr_f*2;
|
tomwalters@0
|
66 % und das ist ein Signal von dieser Länge: (auch mit neuer Samplerate)
|
tomwalters@0
|
67 stime=bin2time(nr_fft,sr_neu);
|
tomwalters@0
|
68 % Dauer des zu untersuchenden Signals
|
tomwalters@0
|
69 duration=tstop-tstart;
|
tomwalters@0
|
70 % wenn die gewünschte Samplingrate nicht hoch genug ist, weil zuviel Punkte erforderlich sind
|
tomwalters@0
|
71 if duration < stime
|
tomwalters@0
|
72 error('spectrogram: desired Samplingrate too low: take less points or higher freqeuncy!');
|
tomwalters@0
|
73 return;
|
tomwalters@0
|
74 end
|
tomwalters@0
|
75
|
tomwalters@0
|
76
|
tomwalters@0
|
77 % meine Notation ist anders als Matlab: Bei mir ist x die Zeit
|
tomwalters@0
|
78 % und y die Frequenz
|
tomwalters@0
|
79 sr_field=nr_t/duration; % die "SampleRate" des Feldes (sehr klein, da nur wenig Punkte)
|
tomwalters@0
|
80 f=field(nr_t,nr_f,sr_field);
|
tomwalters@0
|
81 f=setmaxfre(f,maxfre); % Für die Grafik: Wie hoch die Frequenzen geben
|
tomwalters@0
|
82
|
tomwalters@0
|
83 % damit die fft immer von einem richtigen vollen Signal gemacht werden kann, werden die
|
tomwalters@0
|
84 % FFTs an Stellen berechenet, die immer ein volles signal haben
|
tomwalters@0
|
85 time_step=(tstop-tstart-stime)/nr_t;
|
tomwalters@0
|
86
|
tomwalters@0
|
87 count=0;
|
tomwalters@0
|
88 w = hann(nr_fft); % for later: the window
|
tomwalters@0
|
89 % for t=56*time_step:time_step:tstop-stime-time_step
|
tomwalters@0
|
90
|
tomwalters@0
|
91 sig=setstarttime(sig,0);
|
tomwalters@0
|
92 for t=tstart:time_step:tstop-stime-time_step
|
tomwalters@0
|
93 count=count+1;
|
tomwalters@0
|
94 s1=t;
|
tomwalters@0
|
95 s2=t+stime;
|
tomwalters@0
|
96 if s2<tstop
|
tomwalters@0
|
97 s=getpart(sig,t,t+stime); % von diesem Teil soll die FFT gemacht werden
|
tomwalters@0
|
98 else % hier sollte er nicht hinkommen
|
tomwalters@0
|
99 s=getpart(sig,t,tstop);
|
tomwalters@0
|
100 s=expand(s,stime,0); % fülle den Rest mit Nullen auf, damit das Signal auf jeden Fall lang genug ist
|
tomwalters@0
|
101 end
|
tomwalters@0
|
102 s=setstarttime(s,0);
|
tomwalters@0
|
103 % damit die FFT nr_f Punkte hat, muss das Signal, womit sie gemacht wird, so lang sein:
|
tomwalters@0
|
104 % s2=changesr(s,sr_neu);
|
tomwalters@0
|
105 % ein HanningFenster drüberlegen:
|
tomwalters@0
|
106 s=s*w;
|
tomwalters@0
|
107 ps=powerspectrum(s,nr_f*2);
|
tomwalters@0
|
108 % the resultig powesprect is one point too large, because of the zerovalue->strip it
|
tomwalters@0
|
109 ps=strippowerspectrum(ps); % cut the leading zero
|
tomwalters@0
|
110 % figure(1)
|
tomwalters@0
|
111 % plot(s,'.-');
|
tomwalters@0
|
112 % figure(2)
|
tomwalters@0
|
113 % plot(ps,'.-');
|
tomwalters@0
|
114 % normiere das Spektrum auf die maximale Amplitude des Signals
|
tomwalters@0
|
115 ms=max(s);
|
tomwalters@0
|
116 ps=ps*ms;
|
tomwalters@0
|
117 f=setcolumn(f,count,ps);
|
tomwalters@0
|
118 end
|