Source code for pumpp.feature.cqt

#!/usr/bin/env python
'''CQT features'''

import numpy as np
from librosa import cqt, magphase, note_to_hz, amplitude_to_db

from .base import FeatureExtractor

__all__ = ['CQT', 'CQTMag', 'CQTPhaseDiff']


[docs]class CQT(FeatureExtractor): '''Constant-Q transform Attributes ---------- name : str The name for this feature extractor sr : number > 0 The sampling rate of audio hop_length : int > 0 The number of samples between CQT frames n_octaves : int > 0 The number of octaves in the CQT over_sample : int > 0 The amount of frequency oversampling (bins per semitone) fmin : float > 0 The minimum frequency of the CQT log : boolean If `True`, scale the magnitude to decibels Otherwise, use linear magnitude '''
[docs] def __init__(self, name, sr, hop_length, n_octaves=8, over_sample=3, fmin=None, log=False, conv=None): super(CQT, self).__init__(name, sr, hop_length, conv=conv) if fmin is None: fmin = note_to_hz('C1') self.n_octaves = n_octaves self.over_sample = over_sample self.fmin = fmin self.log = log n_bins = n_octaves * 12 * over_sample self.register('mag', n_bins, np.float32) self.register('phase', n_bins, np.float32)
def transform_audio(self, y): '''Compute the CQT Parameters ---------- y : np.ndarray The audio buffer Returns ------- data : dict data['mag'] : np.ndarray, shape = (n_frames, n_bins) The CQT magnitude data['phase']: np.ndarray, shape = mag.shape The CQT phase ''' cqtm, phase = magphase(cqt(y=y, sr=self.sr, hop_length=self.hop_length, fmin=self.fmin, n_bins=(self.n_octaves * self.over_sample * 12), bins_per_octave=(self.over_sample * 12))) if self.log: cqtm = amplitude_to_db(cqtm, ref=np.max) return {'mag': cqtm.T.astype(np.float32)[self.idx], 'phase': np.angle(phase).T.astype(np.float32)[self.idx]}
[docs]class CQTMag(CQT): '''Magnitude CQT See Also -------- CQT '''
[docs] def __init__(self, *args, **kwargs): super(CQTMag, self).__init__(*args, **kwargs) self.pop('phase')
def transform_audio(self, y): '''Compute CQT magnitude. Parameters ---------- y : np.ndarray the audio buffer Returns ------- data : dict data['mag'] : np.ndarray, shape=(n_frames, n_bins) The CQT magnitude ''' data = super(CQTMag, self).transform_audio(y) data.pop('phase') return data
[docs]class CQTPhaseDiff(CQT): '''CQT with unwrapped phase differentials See Also -------- CQT '''
[docs] def __init__(self, *args, **kwargs): super(CQTPhaseDiff, self).__init__(*args, **kwargs) phase_field = self.pop('phase') self.register('dphase', self.n_octaves * 12 * self.over_sample, phase_field.dtype)
def transform_audio(self, y): '''Compute the CQT with unwrapped phase Parameters ---------- y : np.ndarray The audio buffer Returns ------- data : dict data['mag'] : np.ndarray, shape=(n_frames, n_bins) CQT magnitude data['dphase'] : np.ndarray, shape=(n_frames, n_bins) Unwrapped phase differential ''' data = super(CQTPhaseDiff, self).transform_audio(y) data['dphase'] = self.phase_diff(data.pop('phase')) return data