comparison Example VamPy plugins/PySpectralFeatures.py @ 37:27bab3a16c9a vampy2final

new branch Vampy2final
author fazekasgy
date Mon, 05 Oct 2009 11:28:00 +0000
parents
children 8b2eddf686da
comparison
equal deleted inserted replaced
-1:000000000000 37:27bab3a16c9a
1 '''PySpectralFeatures.py - Example plugin demonstrates
2 how to calculate and return simple low-level spectral
3 descriptors (curves) using Numpy and the buffer interface.
4
5 Outputs:
6 1) Spectral Centroid
7 2) Spectral Creast Factor
8 3) Spectral Band-width
9 4) Spectral Difference (first order)
10
11 Centre for Digital Music, Queen Mary University of London.
12 Copyright (C) 2009 Gyorgy Fazekas, QMUL. (See Vamp sources
13 for licence information.)
14
15 '''
16
17 from numpy import *
18 from vampy import *
19
20 class PySpectralFeatures:
21
22 def __init__(self,inputSampleRate):
23
24 # flags:
25 self.vampy_flags = vf_DEBUG | vf_BUFFER | vf_REALTIME
26
27 self.m_inputSampleRate = inputSampleRate
28 self.m_stepSize = 0
29 self.m_blockSize = 0
30 self.m_channels = 0
31 self.threshold = 0.05
32 return None
33
34 def initialise(self,channels,stepSize,blockSize):
35 self.m_channels = channels
36 self.m_stepSize = stepSize
37 self.m_blockSize = blockSize
38 self.prevMag = zeros((blockSize/2)-1)
39 return True
40
41 def reset(self):
42 # reset any initial conditions
43 self.prevMag = zeros((blockSize/2)-1)
44 return None
45
46 def getMaker(self):
47 return 'Vampy Example Plugins'
48
49 def getName(self):
50 return 'Vampy Spectral Features'
51
52 def getIdentifier(self):
53 return 'vampy-sf3'
54
55 def getDescription(self):
56 return 'A collection of low-level spectral descriptors.'
57
58 def getMaxChannelCount(self):
59 return 1
60
61 def getInputDomain(self):
62 return FrequencyDomain
63
64 def getOutputDescriptors(self):
65
66 #Generic values are the same for all
67 Generic = OutputDescriptor()
68 Generic.hasFixedBinCount=True
69 Generic.binCount=1
70 Generic.hasKnownExtents=False
71 Generic.isQuantized=False
72 Generic.sampleType = OneSamplePerStep
73 Generic.unit = 'Hz'
74
75 #Spectral centroid etc...
76 SC = OutputDescriptor(Generic)
77 SC.identifier = 'vampy-sc'
78 SC.name = 'Spectral Centroid'
79 SC.description ='Spectral Centroid (Brightness)'
80
81 SCF = OutputDescriptor(Generic)
82 SCF.identifier = 'vampy-scf'
83 SCF.name = 'Spectral Crest Factor'
84 SCF.description = 'Spectral Crest (Tonality)'
85 SCF.unit = 'v'
86
87 BW = OutputDescriptor(Generic)
88 BW.identifier = 'vampy-bw'
89 BW.name = 'Band Width'
90 BW.description = 'Spectral Band Width'
91
92 SD = OutputDescriptor(Generic)
93 SD.identifier = 'vampy-sd'
94 SD.name = 'Spectral Difference'
95 SD.description = 'Eucledian distance of successive magnitude spectra.'
96
97 #return a tuple, list or OutputList(SC,SCF,BW)
98 return OutputList(SC,SCF,BW,SD)
99
100 def getParameterDescriptors(self):
101
102 threshold = ParameterDescriptor()
103 threshold.identifier='threshold'
104 threshold.name='Noise threshold'
105 threshold.description='Noise threshold'
106 threshold.unit='v'
107 threshold.minValue=0
108 threshold.maxValue=1
109 threshold.defaultValue=0.05
110 threshold.isQuantized=False
111
112 return ParameterList(threshold)
113
114 def setParameter(self,paramid,newval):
115 if paramid == 'threshold' :
116 self.threshold = newval
117 return
118
119 def getParameter(self,paramid):
120 if paramid == 'threshold' :
121 return self.threshold
122 else:
123 return 0.0
124
125
126 # using the numpy memory buffer interface:
127 # flag : vf_BUFFER (or implement processN)
128 # NOTE: Vampy can now pass numpy arrays directly using
129 # the flag vf_ARRAY (see MFCC plugin for example)
130 def process(self,membuffer,timestamp):
131
132 fftsize = self.m_blockSize
133 sampleRate = self.m_inputSampleRate
134
135 #for time domain plugins use the following line:
136 #audioSamples = frombuffer(membuffer[0],float32)
137
138 #for frequency domain plugins use:
139 complexSpectrum = frombuffer(membuffer[0],complex64,-1,8)
140
141 # meaning of the parameters above:
142 # complex64 : data type of the created numpy array
143 # -1 : convert the whole buffer
144 # 8 : skip the DC component (2*32bit / 8bit = 8byte)
145
146 magnitudeSpectrum = abs(complexSpectrum) / (fftsize*0.5)
147 #phaseSpectrum = angle(complexSpectrum)
148
149 freq = array(range(1,len(complexSpectrum)+1)) \
150 * sampleRate / fftsize
151
152 # return features in a FeatureSet()
153 output_featureSet = FeatureSet()
154
155 tpower = sum(magnitudeSpectrum)
156
157 if tpower > self.threshold :
158 centroid = sum(freq * magnitudeSpectrum) / tpower
159 crest = max(magnitudeSpectrum) / tpower
160 bw = sum( abs(freq - centroid) * magnitudeSpectrum ) / tpower
161 normMag = magnitudeSpectrum / tpower
162 sd = sqrt(sum(power((normMag - self.prevMag),2)))
163 self.prevMag = normMag
164 else :
165 centroid = 0.0
166 crest = 0.0
167 bw = 0.0
168 sd = 0.0
169
170 # Any value resulting from the process can be returned.
171 # It is no longer necessary to wrap single values into lists
172 # and convert numpy.floats to python floats,
173 # however a FeatureList() (or python list) can be returned
174 # if more than one feature is calculated per frame.
175 # The feature values can be e.g. int, float, list or array.
176
177 output_featureSet[0] = Feature(centroid)
178 output_featureSet[1] = Feature(crest)
179 output_featureSet[2] = Feature(bw)
180 output_featureSet[3] = Feature(sd)
181
182 return output_featureSet