Source code for shennong.features.window

"""Implementation of different types of window functions

This is usefull when computing frames for features extraction. Uses
the kaldi implementation.

The implemented window functions :math:`w(n)` are, with `length` noted
:math:`N`:

* **rectangular**:

  .. math::

     w(n) = 1

* **hanning**:

  .. math::

     w(n) = \\frac{1}{2} - \\frac{1}{2} cos(\\frac{2\\pi n}{N-1})

* **hamming**:

  .. math::

     w(n) = 0.54 - 0.46 cos(\\frac{2\\pi n}{N-1})

* **povey** (like `hamming` but goes to zero at edges):

  .. math::

     w(n) = (\\frac{1}{2} - \\frac{1}{2} cos(\\frac{2\\pi n}{N-1}))^{0.85}

* **blackman**, with `blackman_coeff` noted as :math:`\\alpha`:

  .. math::

     w(n) = \\alpha - \\frac{1}{2} cos(\\frac{2\\pi n}{N-1}) + \
            (\\frac{1}{2} - \\alpha) cos(\\frac{4\\pi n}{N-1})

Examples
--------

>>> from shennong.features.window import window
>>> window(5, type='hamming')
array([0.08, 0.54, 1.  , 0.54, 0.08], dtype=float32)
>>> window(5, type='rectangular')
array([1., 1., 1., 1., 1.], dtype=float32)
>>> window(5, type='povey').tolist()
[0.0, 0.5547847151756287, 1.0, 0.5547847151756287, 0.0]

"""

import numpy as np

import kaldi.matrix
import kaldi.feat.window


[docs]def types(): """Returns the supported window functions as a list""" return sorted(['povey', 'hanning', 'hamming', 'rectangular', 'blackman'])
[docs]def window(length, type='povey', blackman_coeff=0.42): """Returns a window of the given `type` and `length` Parameters ---------- length : int The size of the window, in number of samples type : {'povey', 'hanning', 'hamming', 'rectangular', 'blackman'} The type of the window, default is 'povey' (like hamming but goes to zero at edges) blackman_coeff : float, optional The constant coefficient for generalized Blackman window, used only when `type` is 'blackman' Returns ------- window : array, shape = [length, 1] The window with the given `type` and `length` Raises ------ ValueError If the `type` is not valid or `length <= 1` """ if int(length) <= 0: raise ValueError( 'length must be strictly positive but is {}'.format(length)) if type not in types(): raise ValueError( 'type must be in {} but is {}'.format(types, type)) # special case where the window has only one sample (in kaldi this # returns nan) if length == 1: return np.ones((1,)) # special case where the window has only two samples, for povey, # hanning and blackman this leads to a zeros only window. if length == 2 and type in ('povey', 'blackman', 'hanning'): return np.ones((2,)) opt = kaldi.feat.window.FrameExtractionOptions() opt.samp_freq = 1000 opt.frame_length_ms = length # samp_freq * 0.001 * length opt.window_type = type opt.blackman_coeff = blackman_coeff window = kaldi.feat.window.FeatureWindowFunction().from_options(opt).window return kaldi.matrix.SubVector(window).numpy()