Mercurial > hg > vampy
comparison Example VamPy plugins/PySpectralFeatures.py @ 9:d2d36e7d2276
more examples and some bug fixes
author | fazekasgy |
---|---|
date | Fri, 13 Jun 2008 16:52:59 +0000 |
parents | |
children | 7d28bed0864e |
comparison
equal
deleted
inserted
replaced
8:3af6b5990ad8 | 9:d2d36e7d2276 |
---|---|
1 '''PySpectralFeatures.py - Example plugin demonstrates''' | |
2 '''how to use the NumPy array interface and write Matlab style code.''' | |
3 | |
4 from numpy import * | |
5 | |
6 class PySpectralFeatures: | |
7 | |
8 def __init__(self): | |
9 self.m_imputSampleRate = 0.0 | |
10 self.m_stepSize = 0 | |
11 self.m_blockSize = 0 | |
12 self.m_channels = 0 | |
13 self.threshold = 0.00 | |
14 self.r = 2.0 | |
15 | |
16 def initialise(self,channels,stepSize,blockSize,inputSampleRate): | |
17 self.m_channels = channels | |
18 self.m_stepSize = stepSize | |
19 self.m_blockSize = blockSize | |
20 self.m_inputSampleRate = inputSampleRate | |
21 #self.prevMag = ones((blockSize/2)-1) / ((blockSize/2)-1) | |
22 self.prevMag = zeros((blockSize/2)-1) | |
23 self.prevMag[0] = 1 | |
24 | |
25 return True | |
26 | |
27 def getMaker(self): | |
28 return 'VamPy Example Plugins' | |
29 | |
30 def getName(self): | |
31 return 'VamPy Spectral Features' | |
32 | |
33 def getIdentifier(self): | |
34 return 'vampy-sf2' | |
35 | |
36 def getDescription(self): | |
37 return 'A collection of low-level spectral descriptors.' | |
38 | |
39 def getMaxChannelCount(self): | |
40 return 1 | |
41 | |
42 def getInputDomain(self): | |
43 return 'FrequencyDomain' | |
44 | |
45 def getOutputDescriptors(self): | |
46 | |
47 #descriptors are python dictionaries | |
48 #Generic values are the same for all | |
49 Generic={ | |
50 'hasFixedBinCount':True, | |
51 'binCount':1, | |
52 'hasKnownExtents':False, | |
53 'isQuantized':False, | |
54 'sampleType':'OneSamplePerStep' | |
55 } | |
56 | |
57 #Spectral centroid etc... | |
58 SC=Generic.copy() | |
59 SC.update({ | |
60 'identifier':'vampy-sc', | |
61 'name':'Spectral Centroid', | |
62 'description':'Spectral Centroid (Brightness)', | |
63 'unit':'Hz' | |
64 }) | |
65 | |
66 SCF=Generic.copy() | |
67 SCF.update({ | |
68 'identifier':'vampy-scf', | |
69 'name':'Spectral Crest Factor', | |
70 'description':'Spectral Crest (Tonality)', | |
71 'unit':'v' | |
72 }) | |
73 | |
74 BW=Generic.copy() | |
75 BW.update({ | |
76 'identifier':'vampy-bw', | |
77 'name':'Band Width', | |
78 'description':'Spectral Band Width', | |
79 'unit':'Hz', | |
80 }) | |
81 | |
82 SE=Generic.copy() | |
83 SE.update({ | |
84 'identifier':'vampy-se', | |
85 'name':'Shannon Entropy', | |
86 'description':'Shannon Entropy', | |
87 'unit':'', | |
88 }) | |
89 | |
90 RE=Generic.copy() | |
91 RE.update({ | |
92 'identifier':'vampy-re', | |
93 'name':'Renyi Entropy', | |
94 'description':'Renyi Entropy', | |
95 'unit':'', | |
96 }) | |
97 | |
98 KL=Generic.copy() | |
99 KL.update({ | |
100 'identifier':'vampy-kl', | |
101 'name':'Kullback Leibler divergence', | |
102 'description':'KL divergence between successive spectra', | |
103 'unit':'', | |
104 }) | |
105 | |
106 #return a list of dictionaries | |
107 return [SC,SCF,BW,SE,RE,KL] | |
108 | |
109 def getParameterDescriptors(self): | |
110 threshold={ | |
111 'identifier':'threshold', | |
112 'name':'Noise threshold: ', | |
113 'description':'', | |
114 'unit':'v', | |
115 'minValue':0.0, | |
116 'maxValue':0.5, | |
117 'defaultValue':0.05, | |
118 'isQuantized':False | |
119 } | |
120 | |
121 renyicoeff={ | |
122 'identifier':'r', | |
123 'name':'Renyi entropy coeff: ', | |
124 'description':'', | |
125 'unit':'', | |
126 'minValue':0.0, | |
127 'maxValue':10.0, | |
128 'defaultValue':2, | |
129 'isQuantized':False | |
130 } | |
131 | |
132 return [threshold,renyicoeff] | |
133 | |
134 def setParameter(self,paramid,newval): | |
135 if paramid == 'threshold' : | |
136 self.threshold = newval | |
137 if paramid == 'r' : | |
138 self.r == newval | |
139 return | |
140 | |
141 def getParameter(self,paramid): | |
142 if paramid == 'threshold' : | |
143 return self.threshold | |
144 if paramid == 'r': | |
145 return float(self.r) | |
146 else: | |
147 return 0.0 | |
148 | |
149 def processN(self,membuffer,samplecount): | |
150 fftsize = self.m_blockSize | |
151 sampleRate = self.m_inputSampleRate | |
152 | |
153 #for time domain plugins use the following line: | |
154 #audioSamples = frombuffer(membuffer[0],float32) | |
155 #-1: do till the end, skip DC 2*32bit / 8bit = 8byte | |
156 complexSpectrum = frombuffer(membuffer[0],complex64,-1,8) | |
157 magnitudeSpectrum = abs(complexSpectrum) / (fftsize/2) | |
158 tpower = sum(magnitudeSpectrum) | |
159 #phaseSpectrum = angle(complexSpectrum) | |
160 | |
161 freq = array(range(1,len(complexSpectrum)+1)) \ | |
162 * sampleRate / fftsize | |
163 | |
164 centroid = 0.0 | |
165 crest = 0.0 | |
166 bw = 0.0 | |
167 shannon = 0.0 | |
168 renyi = 0.0 | |
169 r = self.r | |
170 KLdiv = 0.0 | |
171 flatness = 0.0 | |
172 exp=1.0 / (fftsize/2) | |
173 #print exp | |
174 | |
175 #declare outputs | |
176 output0=[] | |
177 output1=[] | |
178 output2=[] | |
179 output3=[] | |
180 output4=[] | |
181 output5=[] | |
182 | |
183 if tpower > self.threshold : | |
184 | |
185 centroid = sum(freq * magnitudeSpectrum) / tpower | |
186 crest = max(magnitudeSpectrum) / tpower | |
187 bw = sum( abs(freq - centroid) * magnitudeSpectrum ) / tpower | |
188 #flatness = prod(abs(complexSpectrum)) | |
189 #print flatness | |
190 normMag = magnitudeSpectrum / tpower #make it sum to 1 | |
191 shannon = - sum( normMag * log2(normMag) ) | |
192 renyi = (1/1-r) * log10( sum( power(normMag,r))) | |
193 KLdiv = sum( normMag * log2(normMag / self.prevMag) ) | |
194 self.prevMag = normMag | |
195 | |
196 output0.append({ | |
197 'hasTimestamp':False, | |
198 'values':[float(centroid)], | |
199 #'label':str(centroid) | |
200 }) | |
201 | |
202 output1.append({ | |
203 'hasTimestamp':False, | |
204 'values':[float(crest)], | |
205 #'label':str(crest) | |
206 }) | |
207 | |
208 output2.append({ | |
209 'hasTimestamp':False, | |
210 'values':[float(bw)], | |
211 #'label':str(bw) | |
212 }) | |
213 | |
214 output3.append({ | |
215 'hasTimestamp':False, | |
216 'values':[float(shannon)], | |
217 #'label':str(shannon) | |
218 }) | |
219 | |
220 output4.append({ | |
221 'hasTimestamp':False, | |
222 'values':[float(renyi)], | |
223 #'label':str(renyi) | |
224 }) | |
225 | |
226 output5.append({ | |
227 'hasTimestamp':False, | |
228 'values':[float(KLdiv)], #strictly must be a list | |
229 #'label':str(renyi) | |
230 }) | |
231 | |
232 #return a LIST of list of dictionaries | |
233 return [output0,output1,output2,output3,output4,output5] |