Mercurial > hg > vampy
diff Example VamPy plugins/PySpectralCentroid.py @ 52:d56f48aafb99
Updated some example plugins.
author | fazekasgy |
---|---|
date | Thu, 08 Oct 2009 08:59:08 +0000 |
parents | |
children | 44d56a3d16b7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Example VamPy plugins/PySpectralCentroid.py Thu Oct 08 08:59:08 2009 +0000 @@ -0,0 +1,144 @@ +'''PySpectralCentroid.py - Example plugin demonstrates +how to write a C style plugin using VamPy in pure Python. +This plugin also introduces the use of the builtin vampy +extension module. + +The plugin has frequency domain input and is using the +legacy interface: the FFT outpout is passed as a list +of complex numbers. + +Outputs: +1) Spectral centroid + +Note: This is not the adviced way of writing Vampy plugins now, +since the interfaces provided for Numpy are at least 5 times +faster. However, this is still a nice and easy to understand +example, which also shows how can one write a reasonable +plugin without having Numpy installed. + +Warning: Earlier versions of this plugin are now obsolete. +(They were using the legacy interface of Vampy 1 which +did not distinquish between time and frequency domain inputs.) + +Centre for Digital Music, Queen Mary University of London. +Copyright (C) 2009 Gyorgy Fazekas, QMUL. (See Vamp sources +for licence information.) + +''' + +# import the names we use from vampy +from vampy import Feature,FeatureSet,ParameterDescriptor +from vampy import OutputDescriptor,FrequencyDomain,OneSamplePerStep + +from math import sqrt + +class PySpectralCentroid: + + def __init__(self,inputSampleRate): + self.m_imputSampleRate = 0.0 + self.m_stepSize = 0 + self.m_blockSize = 0 + self.m_channels = 0 + self.previousSample = 0.0 + self.m_inputSampleRate = inputSampleRate + self.threshold = 0.00 + + def initialise(self,channels,stepSize,blockSize): + self.m_channels = channels + self.m_stepSize = stepSize + self.m_blockSize = blockSize + return True + + def getMaker(self): + return 'Vampy Example Plugins' + + def getName(self): + return 'Spectral Centroid (using legacy process interface)' + + def getIdentifier(self): + return 'vampy-sc3' + + def getMaxChannelCount(self): + return 1 + + def getInputDomain(self): + return FrequencyDomain + + def getOutputDescriptors(self): + + cod = OutputDescriptor() + cod.identifier='vampy-sc3' + cod.name='Spectral Centroid' + cod.description='Spectral Centroid (Brightness)' + cod.unit='' + cod.hasFixedBinCount=True + cod.binCount=1 + cod.hasKnownExtents=False + cod.isQuantized=True + cod.quantizeStep=1.0 + cod.sampleType=OneSamplePerStep + return cod + + def getParameterDescriptors(self): + thd = ParameterDescriptor() + thd.identifier='threshold' + thd.name='Noise threshold' + thd.description='Return null or delete this function if not needed.' + thd.unit='v' + thd.minValue=0.0 + thd.maxValue=0.5 + thd.defaultValue=0.05 + thd.isQuantized=False + return thd + + def setParameter(self,paramid,newval): + if paramid == 'threshold' : + self.threshold = newval + return + + def getParameter(self,paramid): + if paramid == 'threshold' : + return self.threshold + else: + return 0.0 + + def process(self,inputbuffers,timestamp): + + # this is a 1 channel frequency domain plugin, therefore + # inputbuffers contain (block size / 2) + 1 complex numbers + # corresponding to the FFT output from DC to Nyquist inclusive + + cplxArray = inputbuffers[0][:-1] + + prev = self.previousSample + numLin = 0.0 + denom = 0.0 + centroid = 0.0 + + output = FeatureSet() + + pw = 0 + for i in xrange(1,len(cplxArray)) : + pw = pw + abs(cplxArray[i]) + + if pw > self.threshold : + for i in range(1,(len(cplxArray))) : + + re = cplxArray[i].real + im = cplxArray[i].imag + freq = i * self.m_inputSampleRate / self.m_blockSize + power = sqrt (re*re + im*im) / (self.m_blockSize/2) + denom = denom + power + numLin = numLin + freq * power + + if denom != 0 : + centroid = numLin / denom + + else : + centroid = 0.0 + + output[0] = Feature() + output[0].values = centroid + output[0].label = str(centroid) + + return output