annotate Example VamPy plugins/PySpectralFeatures.py @ 25:7648f3f2fa14

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