Package timeside :: Package analyzer :: Module odf
[hide private]
[frames] | no frames]

Source Code for Module timeside.analyzer.odf

  1  # -*- coding: utf-8 -*- 
  2  # 
  3  # Copyright (c) 2013 Paul Brossier <piem@piem.org> 
  4   
  5  # This file is part of TimeSide. 
  6   
  7  # TimeSide is free software: you can redistribute it and/or modify 
  8  # it under the terms of the GNU General Public License as published by 
  9  # the Free Software Foundation, either version 2 of the License, or 
 10  # (at your option) any later version. 
 11   
 12  # TimeSide is distributed in the hope that it will be useful, 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 15  # GNU General Public License for more details. 
 16   
 17  # You should have received a copy of the GNU General Public License 
 18  # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>. 
 19   
 20  # Author: Thomas Fillon <thomas@parisson.com> 
 21   
 22  from timeside.core import implements, interfacedoc 
 23  from timeside.analyzer.core import Analyzer 
 24  from timeside.analyzer import Spectrogram 
 25  from timeside.api import IAnalyzer 
 26  import numpy as np 
 27  from numpy import pi as Pi 
 28  from scipy import signal 
29 30 31 -class OnsetDetectionFunction(Analyzer):
32 implements(IAnalyzer) 33
34 - def __init__(self, blocksize=1024, stepsize=None):
35 super(OnsetDetectionFunction, self).__init__() 36 37 self.input_blocksize = blocksize 38 if stepsize: 39 self.input_stepsize = stepsize 40 else: 41 self.input_stepsize = blocksize / 2 42 43 self.parents.append(Spectrogram(blocksize=self.input_blocksize, 44 stepsize=self.input_stepsize))
45 46 @interfacedoc
47 - def setup(self, channels=None, samplerate=None, 48 blocksize=None, totalframes=None):
51 52 @staticmethod 53 @interfacedoc
54 - def id():
55 return "odf"
56 57 @staticmethod 58 @interfacedoc
59 - def name():
60 return "Onset Detection Function"
61 62 @staticmethod 63 @interfacedoc
64 - def unit():
65 return ""
66
67 - def process(self, frames, eod=False):
68 return frames, eod
69
70 - def post_process(self):
71 72 #spectrogram = self.parents()[0]['spectrogram_analyzer'].data 73 spectrogram = self.process_pipe.results['spectrogram_analyzer'].data 74 #spectrogram = self.pipe._results[self.parents()[0].id] 75 76 # Low-pass filtering of the spectrogram amplitude along the time axis 77 S = signal.lfilter(signal.hann(15)[8:], 1, abs(spectrogram), axis=0) 78 79 80 import matplotlib.pyplot as plt 81 # plt.figure() 82 # plt.imshow(np.log10(abs(spectrogram)), origin='lower', aspect='auto', interpolation='nearest') 83 84 85 # Clip small value to a minimal threshold 86 np.maximum(S, 1e-9, out=S) 87 88 S = np.log10(S) 89 90 # plt.figure() 91 # plt.imshow(S,origin='lower', aspect='auto', interpolation='nearest') 92 # plt.show() 93 94 # S[S<1e-3]=0 95 np.maximum(S, 1e-3, out=S) 96 97 # Differentiator filter 98 df_filter = signal.fir_filter_design.remez(31, [0, 0.5], [Pi], 99 type='differentiator') 100 101 S_diff = signal.lfilter(df_filter, 1, S, axis=0) 102 S_diff[S_diff < 1e-10] = 0 103 104 # Summation along the frequency axis 105 odf_diff = S_diff.sum(axis=1) 106 odf_diff = odf_diff / np.median(odf_diff) # Normalize 107 108 odf = self.new_result(data_mode='value', time_mode='framewise') 109 #odf.parameters = {'FFT_SIZE': self.FFT_SIZE} 110 odf.data_object.value = odf_diff 111 self.process_pipe.results.add(odf)
112