1010from __future__ import absolute_import , division , print_function
1111
1212import inspect
13- import math
1413from functools import partial
1514
1615import numpy as np
@@ -125,9 +124,9 @@ def process(self, data, **kwargs):
125124MFCC_NORM_FILTERS = True
126125MFCC_MUL = 1.
127126MFCC_ADD = np .spacing (1 )
128- MFCC_DCT_NORM = " ortho"
127+ MFCC_DCT_NORM = ' ortho'
129128MFCC_DELTA_FILTER = np .linspace (4 , - 4 , 9 ) / 60
130- MFCC_DELTADELTA_FILTER = np .linspace (1 , - 1 , 3 ) / 2
129+ MFCC_DELTA_DELTA_FILTER = np .linspace (1 , - 1 , 3 ) / 2
131130
132131
133132class MFCC (Cepstrogram ):
@@ -159,7 +158,7 @@ class MFCC(Cepstrogram):
159158 Add this value before taking the logarithm of the magnitudes.
160159 dct_norm : {'ortho', None}, optional
161160 Normalization mode (see scipy.fftpack.dct). Default is 'ortho'.
162- kwargs : dict
161+ kwargs : dict, optional
163162 If no :class:`.audio.spectrogram.Spectrogram` instance was given, one
164163 is instantiated and these keyword arguments are passed.
165164
@@ -234,7 +233,7 @@ def __new__(cls, spectrogram, filterbank=MelFilterbank,
234233 @staticmethod
235234 def calc_deltas (data , delta_filter ):
236235 """
237- Applies the given filter to the data after automatically padding by
236+ Apply the given filter to the data after automatically padding by
238237 replicating the first and last frame. The length of the padding is
239238 calculated via ceil(len(delta_filter)).
240239
@@ -245,106 +244,111 @@ def calc_deltas(data, delta_filter):
245244 Parameters
246245 ----------
247246 data: numpy array
248- containing the data to process
247+ Data to process, i.e. MFCCs or deltas thereof.
249248 delta_filter: numpy array
250- the filter used for convolution
249+ Filter used for convolution.
251250
252251 Returns
253252 -------
254253 deltas: numpy array
255- containing the deltas, has the same shape as data
254+ Deltas of `data`, same shape as `data`.
255+
256256 """
257- # prepare vectorized convolve function
258- # (requires transposed matrices in our use case)
259- vconv = np .vectorize (partial (np .convolve , mode = "same" ),
260- signature = '(n),(m)->(k)' )
261257 # pad data by replicating the first and the last frame
262- k = int (math .ceil (len (delta_filter ) / 2 ))
263- padded = np .vstack ((np .array ([data [0 ], ] * k ),
264- data ,
258+ k = int (np .ceil (len (delta_filter ) / 2 ))
259+ padded = np .vstack ((np .array ([data [0 ], ] * k ), data ,
265260 np .array ([data [- 1 ], ] * k )))
266261 # calculate the deltas for each coefficient
267- deltas = vconv (padded .transpose (), delta_filter )
268- return deltas .transpose ()[k :- k ]
262+ deltas = []
263+ for band in padded .T :
264+ deltas .append (np .convolve (band , delta_filter , 'same' ))
265+ # return deltas (first/last k frames truncated)
266+ return np .vstack (deltas ).T [k :- k ]
269267
270268 @lazyprop
271269 def deltas (self , delta_filter = MFCC_DELTA_FILTER ):
272270 """
273- Return the derivative of this MFCC's coefficients by convolving with
274- a filter. Accessing this property corresponds to the function call
275- ``MFCC.calc_deltas(self, delta_filter)``. However, using this property,
276- the result is calculated only once and cached for later access.
277- See ``@lazyprop``for further details.
271+ First order derivative of the MFCCs.
278272
279273 Parameters
280274 ----------
281275 delta_filter: numpy array, optional
282- the filter used for convolution, defaults to MFCC_DELTA_FILTER
276+ Filter to calculate the derivative of the MFCCs.
283277
284278 Returns
285279 -------
286280 deltas: numpy array
287- containing the deltas, has the same shape as self
281+ Deltas of the MFCCs, same shape as MFCCs.
282+
283+ Notes
284+ -----
285+ Accessing this property corresponds to the function call
286+ ``MFCC.calc_deltas(mfccs, delta_filter)``, with results being cached.
287+
288288 """
289289 return MFCC .calc_deltas (self , delta_filter )
290290
291291 @lazyprop
292- def deltadeltas (self , deltadelta_filter = MFCC_DELTADELTA_FILTER ):
292+ def delta_deltas (self , delta_delta_filter = MFCC_DELTA_DELTA_FILTER ):
293293 """
294- Return the second order derivative of this MFCC's coefficients by
295- convolving with a filter. Accessing this property corresponds to the
296- function call ``MFCC.calc_deltas(self, deltadelta_filter)``. However,
297- using this property, the result is calculated only once and cached
298- for later access. See ``@lazyprop``for further details.
294+ Second order derivatives of the MFCCs.
299295
300296 Parameters
301297 ----------
302- delta_filter : numpy array, optional
303- the filter used for convolution, defaults to MFCC_DELTA_FILTER
298+ delta_delta_filter : numpy array, optional
299+ Filter to calculate the derivative of the derivative.
304300
305301 Returns
306302 -------
307303 deltas: numpy array
308- containing the deltas, has the same shape as self
304+ Delta deltas of the MFCCs, same shape as MFCCs.
305+
306+ Notes
307+ -----
308+ Accessing this property corresponds to the function call
309+ ``MFCC.calc_deltas(deltas, delta_delta_filter)``, with results being
310+ cached.
311+
309312 """
310- return MFCC .calc_deltas (self .deltas , deltadelta_filter )
313+ return MFCC .calc_deltas (self .deltas , delta_delta_filter )
311314
312315 def calc_voicebox_deltas (self , delta_filter = MFCC_DELTA_FILTER ,
313- ddelta_filter = MFCC_DELTADELTA_FILTER ):
316+ delta_delta_filter = MFCC_DELTA_DELTA_FILTER ):
314317 """
315- Method to calculate deltas and deltadeltas the way it is done in the
316- voicebox MatLab toolbox.
317-
318- see http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
318+ Calculates deltas and delta deltas the way it is done in the voicebox
319+ MatLab toolbox [1]_.
319320
320321 Parameters
321322 ----------
322323 delta_filter : numpy array
323- filter to calculate the derivative of this MFCC's data
324- ddelta_filter : numpy array
325- filter to calculate the derivative of the derivative
324+ Filter to calculate the derivative of the MFCCs.
325+ delta_delta_filter : numpy array
326+ Filter to calculate the derivative of the derivative.
326327
327328 Returns
328329 -------
329- [self, deltas, deltadeltas] : numpy array, shape (|frames|, |bands|*3)
330- a horizontally stacked np array consisting of the MFCC coefficients
331- its derivative and the derivative of second order
330+ [mfcc, delta, delta_delta] : numpy array, shape (num_frames, bands * 3)
331+ Horizontally stacked array consisting of the MFCC coefficients,
332+ their first and second order derivatives.
333+
334+ References
335+ ----------
336+ .. [1] http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
337+
332338 """
333339 padded_input = np .vstack (
334340 (np .array ([self [0 ], ] * 5 ), self , np .array ([self [- 1 ], ] * 5 )))
335341 deltashape = tuple (reversed (padded_input .shape ))
336342 flat_input = padded_input .transpose ().flatten ()
337-
338- deltas = np .convolve (flat_input , delta_filter , mode = "same" ) \
339- .reshape (deltashape ).T [4 :- 4 , ]
343+ deltas = np .convolve (flat_input , delta_filter , mode = 'same' )
344+ deltas = deltas .reshape (deltashape ).T [4 :- 4 , ]
340345 deltadeltashape = tuple (reversed (deltas .shape ))
341346 flat_deltas = deltas .transpose ().flatten ()
342347 deltas = deltas [1 :- 1 , ]
343-
344- deltadeltas = np .convolve (flat_deltas , ddelta_filter , mode = "same" ) \
345- .reshape (deltadeltashape ).T [1 :- 1 , ]
346-
347- return np .hstack ((self , deltas , deltadeltas ))
348+ delta_deltas = np .convolve (flat_deltas , delta_delta_filter ,
349+ mode = 'same' )
350+ delta_deltas = delta_deltas .reshape (deltadeltashape ).T [1 :- 1 , ]
351+ return np .hstack ((self , deltas , delta_deltas ))
348352
349353 def __array_finalize__ (self , obj ):
350354 if obj is None :
@@ -358,9 +362,8 @@ def __array_finalize__(self, obj):
358362
359363class MFCCProcessor (Processor ):
360364 """
361- MFCCProcessor is CepstrogramProcessor which filters the magnitude
362- spectrogram of the spectrogram with a Mel filterbank, takes the logarithm
363- and performs a discrete cosine transform afterwards.
365+ MFCCProcessor filters the magnitude spectrogram with a Mel filterbank,
366+ takes the logarithm and performs a discrete cosine transform afterwards.
364367
365368 Parameters
366369 ----------
@@ -377,8 +380,6 @@ class MFCCProcessor(Processor):
377380 logarithm.
378381 add : float, optional
379382 Add this value before taking the logarithm of the magnitudes.
380- transform : numpy ufunc
381- Transformation applied to the Mel filtered spectrogram.
382383
383384 """
384385
@@ -403,7 +404,7 @@ def process(self, data, **kwargs):
403404 ----------
404405 data : numpy array
405406 Data to be processed (a spectrogram).
406- kwargs : dict
407+ kwargs : dict, optional
407408 Keyword arguments passed to :class:`MFCC`.
408409
409410 Returns
0 commit comments