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