fazekasgy@37
|
1 '''PySpectralCentroid.py - Example plugin demonstrates
|
fazekasgy@37
|
2 how to write a C style plugin using VamPy.
|
fazekasgy@37
|
3
|
fazekasgy@37
|
4 Obsolete warning: this plugin will no longer be supported
|
fazekasgy@37
|
5 since the legacy interface should pass a list of complex
|
fazekasgy@37
|
6 numbers for frequency domain plugins and a list of floats
|
fazekasgy@37
|
7 for time domin plugins.
|
fazekasgy@37
|
8
|
fazekasgy@37
|
9 '''
|
fazekasgy@37
|
10
|
fazekasgy@37
|
11 from numpy import *
|
fazekasgy@37
|
12
|
fazekasgy@37
|
13 class PySpectralCentroid:
|
fazekasgy@37
|
14
|
fazekasgy@37
|
15 def __init__(self,inputSampleRate):
|
fazekasgy@37
|
16 self.m_imputSampleRate = 0.0
|
fazekasgy@37
|
17 self.m_stepSize = 0
|
fazekasgy@37
|
18 self.m_blockSize = 0
|
fazekasgy@37
|
19 self.m_channels = 0
|
fazekasgy@37
|
20 self.previousSample = 0.0
|
fazekasgy@37
|
21 self.m_inputSampleRate = inputSampleRate
|
fazekasgy@37
|
22 self.threshold = 0.00
|
fazekasgy@37
|
23
|
fazekasgy@37
|
24 def initialise(self,channels,stepSize,blockSize):
|
fazekasgy@37
|
25 self.m_channels = channels
|
fazekasgy@37
|
26 self.m_stepSize = stepSize
|
fazekasgy@37
|
27 self.m_blockSize = blockSize
|
fazekasgy@37
|
28 return True
|
fazekasgy@37
|
29
|
fazekasgy@37
|
30 def getMaker(self):
|
fazekasgy@37
|
31 return 'Vampy Example Plugins'
|
fazekasgy@37
|
32
|
fazekasgy@37
|
33 def getName(self):
|
fazekasgy@37
|
34 return 'Spectral Centroid (legacy process interface)'
|
fazekasgy@37
|
35
|
fazekasgy@37
|
36 def getIdentifier(self):
|
fazekasgy@37
|
37 return 'vampy-sc2'
|
fazekasgy@37
|
38
|
fazekasgy@37
|
39 def getMaxChannelCount(self):
|
fazekasgy@37
|
40 return 1
|
fazekasgy@37
|
41
|
fazekasgy@37
|
42 def getInputDomain(self):
|
fazekasgy@37
|
43 return 'FrequencyDomain'
|
fazekasgy@37
|
44
|
fazekasgy@37
|
45 def getOutputDescriptors(self):
|
fazekasgy@37
|
46
|
fazekasgy@37
|
47 output0={
|
fazekasgy@37
|
48 'identifier':'vampy-sf1',
|
fazekasgy@37
|
49 'name':'Spectral Centroid',
|
fazekasgy@37
|
50 'description':'Spectral Centroid (Brightness)',
|
fazekasgy@37
|
51 'unit':' ',
|
fazekasgy@37
|
52 'hasFixedBinCount':True,
|
fazekasgy@37
|
53 'binCount':1,
|
fazekasgy@37
|
54 'hasKnownExtents':False,
|
fazekasgy@37
|
55 'isQuantized':True,
|
fazekasgy@37
|
56 'quantizeStep':1.0,
|
fazekasgy@37
|
57 'sampleType':'OneSamplePerStep'
|
fazekasgy@37
|
58 }
|
fazekasgy@37
|
59
|
fazekasgy@37
|
60 return [output0]
|
fazekasgy@37
|
61
|
fazekasgy@37
|
62 def getParameterDescriptors(self):
|
fazekasgy@37
|
63 paramlist1={
|
fazekasgy@37
|
64 'identifier':'threshold',
|
fazekasgy@37
|
65 'name':'Noise threshold: ',
|
fazekasgy@37
|
66 'description':'Return null or delete this function if not needed.',
|
fazekasgy@37
|
67 'unit':'v',
|
fazekasgy@37
|
68 'minValue':0.0,
|
fazekasgy@37
|
69 'maxValue':0.5,
|
fazekasgy@37
|
70 'defaultValue':0.05,
|
fazekasgy@37
|
71 'isQuantized':False
|
fazekasgy@37
|
72 }
|
fazekasgy@37
|
73 return [paramlist1]
|
fazekasgy@37
|
74
|
fazekasgy@37
|
75 def setParameter(self,paramid,newval):
|
fazekasgy@37
|
76 if paramid == 'threshold' :
|
fazekasgy@37
|
77 self.threshold = newval
|
fazekasgy@37
|
78 return
|
fazekasgy@37
|
79
|
fazekasgy@37
|
80 def getParameter(self,paramid):
|
fazekasgy@37
|
81 if paramid == 'threshold' :
|
fazekasgy@37
|
82 return self.threshold
|
fazekasgy@37
|
83 else:
|
fazekasgy@37
|
84 return 0.0
|
fazekasgy@37
|
85
|
fazekasgy@37
|
86 def process(self,inbuf,timestamp):
|
fazekasgy@37
|
87
|
fazekasgy@37
|
88 inArray = array(inbuf[0])
|
fazekasgy@37
|
89 crossing = False
|
fazekasgy@37
|
90 prev = self.previousSample
|
fazekasgy@37
|
91 count = 0.0
|
fazekasgy@37
|
92 numLin = 0.0
|
fazekasgy@37
|
93 denom = 0.0
|
fazekasgy@37
|
94 centroid = 0.0
|
fazekasgy@37
|
95
|
fazekasgy@37
|
96 # re = array(inbuf[2:len(inArray):2])
|
fazekasgy@37
|
97 # im = array(inbuf[3:len(inArray):2])
|
fazekasgy@37
|
98
|
fazekasgy@37
|
99 output0=[]
|
fazekasgy@37
|
100 output1=[]
|
fazekasgy@37
|
101
|
fazekasgy@37
|
102 # pw = 0
|
fazekasgy@37
|
103 # for i in xrange(1,len(inbuf[0])) :
|
fazekasgy@37
|
104 # pw = pw + abs(inbuf[0][i])
|
fazekasgy@37
|
105
|
fazekasgy@37
|
106 if sum(abs(inArray)) > self.threshold :
|
fazekasgy@37
|
107 for i in range(1,(len(inArray)/2)) :
|
fazekasgy@37
|
108 # for i in range(1,len(inbuf[0])) :
|
fazekasgy@37
|
109
|
fazekasgy@37
|
110 re = inArray[i*2]
|
fazekasgy@37
|
111 im = inArray[i*2+1]
|
fazekasgy@37
|
112 # re = inbuf[0][i].real
|
fazekasgy@37
|
113 # im = inbuf[0][i].imag
|
fazekasgy@37
|
114 freq = i * self.m_inputSampleRate / self.m_blockSize
|
fazekasgy@37
|
115 power = sqrt (re*re + im*im) / (self.m_blockSize/2)
|
fazekasgy@37
|
116 denom = denom + power
|
fazekasgy@37
|
117 numLin = numLin + freq * power
|
fazekasgy@37
|
118
|
fazekasgy@37
|
119 if denom != 0 :
|
fazekasgy@37
|
120 centroid = numLin / denom
|
fazekasgy@37
|
121
|
fazekasgy@37
|
122 else :
|
fazekasgy@37
|
123 centroid = 0.0
|
fazekasgy@37
|
124
|
fazekasgy@37
|
125 feature0={
|
fazekasgy@37
|
126 'hasTimestamp':False,
|
fazekasgy@37
|
127 'values':[centroid], #strictly must be a list
|
fazekasgy@37
|
128 'label':str(centroid)
|
fazekasgy@37
|
129 }
|
fazekasgy@37
|
130 output0.append(feature0)
|
fazekasgy@37
|
131
|
fazekasgy@37
|
132 return [output0]
|