view Example VamPy plugins/PyZeroCrossing.py @ 24:7d28bed0864e

* Rearrange Python plugin construction. Formerly, the PyPluginAdapter has retained a single plugin instance pointer for each plugin found, and its createPlugin method has simply returned a new PyPlugin object wrapping the same instance pointer. This has a couple of negative consequences: - Because construction of the actual Python instance occurred before the wrapper was constructed, it was not possible to pass arguments (i.e. the sample rate) from the wrapper constructor to the Python plugin instance constructor -- they had to be passed later, to initialise, disadvantaging those plugins that would like to use the sample rate for parameter & step/block size calculations etc - Because there was only a single Python plugin instance, it was not possible to run more than one instance at once with any isolation This rework instead stores the Python class pointer (rather than instance pointer) in the PyPluginAdapter, and each PyPlugin wrapper instance creates its own Python plugin instance. What could possibly go wrong?
author cannam
date Mon, 17 Aug 2009 15:22:06 +0000
parents 535d559300dc
children ba3686eb697c
line wrap: on
line source
'''PyZeroCrossing.py - Example plugin demonstrates''' 
'''how to call a python class using the VamPy Vamp plugin'''

from random import *

class PyZeroCrossing: 
	
	def __init__(self,inputSampleRate): 
		self.m_inputSampleRate = inputSampleRate 
		self.m_stepSize = 0
		self.m_blockSize = 0
		self.m_channels = 0
		self.previousSample = 0.0
		self.threshold = 0.005
		self.identity = random()
		self.counter = 0
		
	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 'Vampy Zero Crossings'
		
	def getIdentifier(self):
		return 'python-zc'
	
	def getMaxChannelCount(self):
		return 1
		
	def getInputDomain(self):
		return 'TimeDomain'
			
	def getOutputDescriptors(self):
		
		#descriptors are python dictionaries
		output0={
		'identifier':'vampy-counts',
		'name':'Number of Zero Crossings',
		'description':'Number of zero crossings per audio frame',
		'unit':' ',
		'hasFixedBinCount':True,
		'binCount':1,
		#'binNames':['1 Hz',1.5,'2 Hz',3,'4 Hz'],
		'hasKnownExtents':False,
		#'minValue':0.0,
		#'maxValue':0.0,
		'isQuantized':True,
		'quantizeStep':1.0,
		'sampleType':'OneSamplePerStep'
		#'sampleRate':48000.0
		}

		output1={
		'identifier':'vampy-crossings',
		'name':'Zero Crossing Locations',
		'description':'The locations of zero crossing points',
		'unit':'discrete',
		'hasFixedBinCount':True,
		'binCount':0,
		'sampleType':'VariableSampleRate'
		#'sampleRate':48000.0
		}

		#return a list of dictionaries
		return [output0,output1]

	def getParameterDescriptors(self):
		paramlist1={
		'identifier':'threshold',
		'name':'Noise threshold',
		'description':'',
		'unit':'v',
		'minValue':0.0,
		'maxValue':0.5,
		'defaultValue':0.005,
		'isQuantized':False
		}
		return [paramlist1]

	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,inbuf,timestamp):
		crossing = False
		prev = self.previousSample
		count = 0.0;
		channel = inbuf[0]

		print "Identity ", self.identity, ", counter ", self.counter
		self.counter = self.counter + 1

		#we have two outputs defined thus we have to declare
		#them as empty dictionaries in our output list
		#in order to be able to return variable rate outputs
		output0=[]
		output1=[]

		if sum([abs(s) for s in channel]) > self.threshold : 

			for x in range(len(channel)-1) :
				crossing = False
				sample = channel[x]
				if sample <= 0.0 : 
					if prev > 0.0 : crossing = True
				else :
					if sample > 0.0 :
						if prev <= 0.0 : crossing = True		
			
				if crossing == True : 
					count = count + 1
					feature1={
					'hasTimestamp':True,	
					#for now return sample position and convert to RealTime in C code
					'timeStamp':long(timestamp + x),				
					'values':[count],			
					'label':str(count),				
					}				
					output1.append(feature1)
			
				prev = sample	
			self.previousSample = prev

		else :
			count = 0.0
			self.previousSample = channel[len(channel)-1]

		feature0={
		'hasTimestamp':False,		
		#'timeStamp':timestamp,				
		'values':[count],		#strictly must be a list
		'label':str(count)				
		}
		output0.append(feature0)
		
		#return a LIST of list of dictionaries
		return [output0,output1]