fazekasgy@37: '''PySpectralCentroid.py - Example plugin demonstrates 
fazekasgy@37: how to write a C style plugin using VamPy.
fazekasgy@37: 
fazekasgy@37: Obsolete warning: this plugin will no longer be supported 
fazekasgy@37: since the legacy interface should pass a list of complex
fazekasgy@37: numbers for frequency domain plugins and a list of floats
fazekasgy@37: for time domin plugins.
fazekasgy@37: 
fazekasgy@37: '''
fazekasgy@37: 
fazekasgy@37: from numpy import *
fazekasgy@37: 
fazekasgy@37: class PySpectralCentroid: 
fazekasgy@37: 	
fazekasgy@37: 	def __init__(self,inputSampleRate): 
fazekasgy@37: 		self.m_imputSampleRate = 0.0 
fazekasgy@37: 		self.m_stepSize = 0
fazekasgy@37: 		self.m_blockSize = 0
fazekasgy@37: 		self.m_channels = 0
fazekasgy@37: 		self.previousSample = 0.0
fazekasgy@37: 		self.m_inputSampleRate = inputSampleRate
fazekasgy@37: 		self.threshold = 0.00
fazekasgy@37: 		
fazekasgy@37: 	def initialise(self,channels,stepSize,blockSize):
fazekasgy@37: 		self.m_channels = channels
fazekasgy@37: 		self.m_stepSize = stepSize		
fazekasgy@37: 		self.m_blockSize = blockSize
fazekasgy@37: 		return True
fazekasgy@37: 	
fazekasgy@37: 	def getMaker(self):
fazekasgy@37: 		return 'Vampy Example Plugins'
fazekasgy@37: 	
fazekasgy@37: 	def getName(self):
fazekasgy@37: 		return 'Spectral Centroid (legacy process interface)'
fazekasgy@37: 		
fazekasgy@37: 	def getIdentifier(self):
fazekasgy@37: 		return 'vampy-sc2'
fazekasgy@37: 	
fazekasgy@37: 	def getMaxChannelCount(self):
fazekasgy@37: 		return 1
fazekasgy@37: 		
fazekasgy@37: 	def getInputDomain(self):
fazekasgy@37: 		return 'FrequencyDomain'
fazekasgy@37: 			
fazekasgy@37: 	def getOutputDescriptors(self):
fazekasgy@37: 		
fazekasgy@37: 		output0={
fazekasgy@37: 		'identifier':'vampy-sf1',
fazekasgy@37: 		'name':'Spectral Centroid',
fazekasgy@37: 		'description':'Spectral Centroid (Brightness)',
fazekasgy@37: 		'unit':' ',
fazekasgy@37: 		'hasFixedBinCount':True,
fazekasgy@37: 		'binCount':1,
fazekasgy@37: 		'hasKnownExtents':False,
fazekasgy@37: 		'isQuantized':True,
fazekasgy@37: 		'quantizeStep':1.0,
fazekasgy@37: 		'sampleType':'OneSamplePerStep'
fazekasgy@37: 		}
fazekasgy@37: 
fazekasgy@37: 		return [output0]
fazekasgy@37: 
fazekasgy@37: 	def getParameterDescriptors(self):
fazekasgy@37: 		paramlist1={
fazekasgy@37: 		'identifier':'threshold',
fazekasgy@37: 		'name':'Noise threshold: ',
fazekasgy@37: 		'description':'Return null or delete this function if not needed.',
fazekasgy@37: 		'unit':'v',
fazekasgy@37: 		'minValue':0.0,
fazekasgy@37: 		'maxValue':0.5,
fazekasgy@37: 		'defaultValue':0.05,
fazekasgy@37: 		'isQuantized':False
fazekasgy@37: 		}
fazekasgy@37: 		return [paramlist1]
fazekasgy@37: 
fazekasgy@37: 	def setParameter(self,paramid,newval):
fazekasgy@37: 		if paramid == 'threshold' :
fazekasgy@37: 			self.threshold = newval
fazekasgy@37: 		return
fazekasgy@37: 		
fazekasgy@37: 	def getParameter(self,paramid):
fazekasgy@37: 		if paramid == 'threshold' :
fazekasgy@37: 			return self.threshold
fazekasgy@37: 		else:
fazekasgy@37: 			return 0.0
fazekasgy@37: 			
fazekasgy@37: 	def process(self,inbuf,timestamp):
fazekasgy@37: 		
fazekasgy@37: 		inArray = array(inbuf[0])
fazekasgy@37: 		crossing = False
fazekasgy@37: 		prev = self.previousSample
fazekasgy@37: 		count = 0.0
fazekasgy@37: 		numLin = 0.0
fazekasgy@37: 		denom = 0.0
fazekasgy@37: 		centroid = 0.0
fazekasgy@37: 		
fazekasgy@37: 		# re = array(inbuf[2:len(inArray):2])
fazekasgy@37: 		# im = array(inbuf[3:len(inArray):2])
fazekasgy@37: 
fazekasgy@37: 		output0=[]
fazekasgy@37: 		output1=[]
fazekasgy@37: 
fazekasgy@37: 		# pw = 0
fazekasgy@37: 		# for i in xrange(1,len(inbuf[0])) : 
fazekasgy@37: 		# 	pw = pw + abs(inbuf[0][i])
fazekasgy@37: 		
fazekasgy@37: 		if sum(abs(inArray)) > self.threshold : 
fazekasgy@37: 			for i in range(1,(len(inArray)/2)) :
fazekasgy@37: 			# for i in range(1,len(inbuf[0])) :
fazekasgy@37: 				
fazekasgy@37: 				re = inArray[i*2]
fazekasgy@37: 				im = inArray[i*2+1]
fazekasgy@37: 				# re = inbuf[0][i].real
fazekasgy@37: 				# im = inbuf[0][i].imag
fazekasgy@37: 				freq = i * self.m_inputSampleRate / self.m_blockSize
fazekasgy@37: 				power = sqrt (re*re + im*im) / (self.m_blockSize/2)
fazekasgy@37: 				denom = denom + power
fazekasgy@37: 				numLin = numLin + freq * power
fazekasgy@37: 				
fazekasgy@37: 			if denom != 0 :
fazekasgy@37: 				centroid = numLin / denom 
fazekasgy@37: 				
fazekasgy@37: 		else :
fazekasgy@37: 			centroid = 0.0
fazekasgy@37: 
fazekasgy@37: 		feature0={
fazekasgy@37: 		'hasTimestamp':False,		
fazekasgy@37: 		'values':[centroid],		#strictly must be a list
fazekasgy@37: 		'label':str(centroid)				
fazekasgy@37: 		}
fazekasgy@37: 		output0.append(feature0)
fazekasgy@37: 		
fazekasgy@37: 		return [output0]