Source code for motif.feature_extractors.bitteli

"""Bitteli feature extractor.
"""
import numpy as np

from motif.core import FeatureExtractor
from motif.feature_extractors import utils


[docs]class BitteliFeatures(FeatureExtractor): '''Bitteli feature extractor Attributes ---------- ref_hz : float Reference frequency (Hz) for converting to cents. poly_degree : int Polynomial fit degree. min_freq : float Minimum possible vibrato frequency (Hz). max_freq : float Maximum possible vibrato frequency (Hz). freq_step : float Step in Hz between frequencies to search. vibrato_threshold : float Threshold on the average vibrato residual to be considered vibrato. ''' def __init__(self, ref_hz=55.0, poly_degree=5, min_freq=3, max_freq=30, freq_step=0.1, vibrato_threshold=0.25): '''Init method Parameters ---------- ref_hz : float Reference frequency (Hz) for converting to cents. poly_degree : int Polynomial fit degree. min_freq : float Minimum possible vibrato frequency (Hz). max_freq : float Maximum possible vibrato frequency (Hz). freq_step : float Step in Hz between frequencies to search. vibrato_threshold : float Threshold on the average vibrato residual to be considered vibrato. ''' self.ref_hz = ref_hz self.poly_degree = poly_degree self.min_freq = min_freq self.max_freq = max_freq self.freq_step = freq_step self.vibrato_threshold = vibrato_threshold FeatureExtractor.__init__(self)
[docs] def get_feature_vector(self, times, freqs_hz, salience, sample_rate): """Get feature vector for a contour. Parameters ---------- times : np.array Contour times freqs_hz : np.array Contour frequencies (Hz) salience : np.array Contour salience sample_rate : float Contour sample rate. Returns ------- feature_vector : np.array Feature vector. """ freqs_cents = utils.hz_to_cents(freqs_hz, ref_hz=self.ref_hz) features = [ utils.get_contour_shape_features( times, freqs_cents, sample_rate, poly_degree=self.poly_degree, min_freq=self.min_freq, max_freq=self.max_freq, freq_step=self.freq_step, vibrato_threshold=self.vibrato_threshold), utils.get_polynomial_fit_features( times - np.mean(times), salience, n_deg=self.poly_degree, norm=False ), utils.get_contour_duration(times), utils.get_std(freqs_cents), utils.get_range(freqs_cents), utils.get_total_variation(freqs_cents)/len(freqs_cents), utils.get_std(salience), utils.get_range(salience), utils.get_total_variation(salience)/len(freqs_cents) ] return np.concatenate(features)
@property def feature_names(self): """Get feature names. Returns ------- feature_names : list List of feature names. """ feature_names = [ 'vibrato rate', 'vibrato extent', 'vibrato coverage', 'vibrato coverage - beginning', 'vibrato coverage - middle', 'vibrato coverage - end', '0th polynomial coeff - freq', '1st polynomial coeff - freq', '2nd polynomial coeff - freq', '3rd polynomial coeff - freq', '4th polynomial coeff - freq', '5th polynomial coeff - freq', 'polynomial fit residual - freq', 'overall model fit residual - freq', '0th polynomial coeff - salience', '1st polynomial coeff - salience', '2nd polynomial coeff - salience', '3rd polynomial coeff - salience', '4th polynomial coeff - salience', '5th polynomial coeff - salience', 'polynomial fit residual - salience', 'duration', 'pitch stddev (cents)', 'pitch range (cents)', 'pitch average variation', 'salience stdev', 'salience range', 'salience average variation' ] return feature_names @classmethod
[docs] def get_id(cls): """ The FeatureExtractor identifier Returns ------- id : string class identifier """ return 'bitteli'