]> git.parisson.com Git - timeside.git/commitdiff
New Plugin for multiple F0 estimation (wrapped from C++ code, see fmultipitch.so)
authorDominique Fourer <dfourer@dfourer-ThinkPad-T430.(none)>
Sat, 13 Dec 2014 18:36:26 +0000 (19:36 +0100)
committerDominique Fourer <dfourer@dfourer-ThinkPad-T430.(none)>
Sat, 13 Dec 2014 18:36:26 +0000 (19:36 +0100)
timeside/analyzer/labri/fmultipitch.so [new file with mode: 0755]
timeside/analyzer/labri_instru.py
timeside/analyzer/labri_multipitch.py [new file with mode: 0644]

diff --git a/timeside/analyzer/labri/fmultipitch.so b/timeside/analyzer/labri/fmultipitch.so
new file mode 100755 (executable)
index 0000000..f9765b1
Binary files /dev/null and b/timeside/analyzer/labri/fmultipitch.so differ
index 2a943d521f17a19ae0dadc4f16cc5ecd6d658599..9e768fa15f01627ecf855b569b4b4a2ccfcdb98b 100644 (file)
@@ -31,7 +31,7 @@ from timeside.analyzer.preprocessors import frames_adapter
 ## plugin specific
 import sys, os
 REL_PATH='labri';
-PLUGIN_PATH=os.path.join(timeside.__path__[0], 'REL_PATH');
+PLUGIN_PATH=os.path.join(timeside.__path__[0], REL_PATH);
 sys.path.append(PLUGIN_PATH);
 sys.path.append(REL_PATH);             ## can be commented
 import timbre_descriptor
diff --git a/timeside/analyzer/labri_multipitch.py b/timeside/analyzer/labri_multipitch.py
new file mode 100644 (file)
index 0000000..e1e52ae
--- /dev/null
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+#
+# labri_multipitch.py
+#
+# Copyright (c) 2014 Dominique Fourer <dominique@fourer.fr>
+
+# This file is part of TimeSide.
+
+# TimeSide is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+
+# TimeSide is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
+
+# Author: D Fourer <dominique@fourer.fr> http://www.fourer.fr
+from __future__ import absolute_import
+from timeside.analyzer.utils import segmentFromValues
+from timeside.core import Processor, implements, interfacedoc, FixedSizeInputAdapter
+from timeside.analyzer.core import *
+from timeside.api import IAnalyzer
+import timeside
+
+
+## plugin specific
+import sys, os
+REL_PATH='labri';
+PLUGIN_PATH=os.path.join(timeside.__path__[0], REL_PATH);
+sys.path.append(PLUGIN_PATH);
+sys.path.append(REL_PATH);             ## can be commented
+import fmultipitch
+import numpy, scipy
+from timeside.analyzer.preprocessors import frames_adapter
+
+class LABRIMultipitch(Analyzer):
+       """
+       Labri Multipitch Estimation
+       this module performs multiple F0 estimation using sinusoidal
+       models based on spectral reassignment and adapted harmonic source
+       model.
+       Details are in:
+       [D. Fourer. (in french) PhD thesis. Informed approach applied 
+       sound and music analysis (in french), Dec 2013]
+       [D. Fourer and S. Marchand. Informed Multiple-F0 Estimation 
+       Applied to Monaural Audio Source Separation. Proc. EUSIPCO'12,
+        Bucharest, Romania, August 2012]
+       """
+       implements(IAnalyzer)
+       
+       @interfacedoc
+       def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None):
+               super(LABRIMultipitch, self).setup(channels, samplerate, blocksize, totalframes)
+               self.Fs                 = self.samplerate();
+               self.t_index    = 0.;
+               self.result             = AnalyzerResultContainer();
+               self.values             = list();
+       @staticmethod
+       @interfacedoc
+       def id():
+               return "labri_multipitch"
+
+       @staticmethod
+       @interfacedoc
+       def name():
+               return "Labri Multiple F0 estimation"
+
+       @staticmethod
+       @interfacedoc
+       def unit():
+               # return the unit of the data dB, St, ...
+               return "F0 vector in Hz"
+        
+       def __str__(self):
+               return "Labeled Instrument segments"
+       
+       def process(self, frames, eod=False):
+               
+               s,N = prepare_signal(frames);
+               self.t_index = self.t_index + float(N) / float(self.Fs);     ##time index
+               f0_candidates, t = fmultipitch.analysis(s, N, self.Fs);
+               self.values.append([numpy.unique(numpy.array(numpy.squeeze(f0_candidates))), self.t_index ]);   ## (F0_vector, time_t)
+               
+               return frames, eod;
+
+       def post_process(self):
+               result                                  = self.new_result(data_mode='value', time_mode='framewise')
+               result.data_object.value= np.vstack(self.values)
+               
+               #self.add_result(result);    ## doesn't work !
+               self.result.add(result);
+
+## prepare data before analysis
+def prepare_signal(s):
+       s = numpy.array(numpy.squeeze(s), float);
+
+       ## Stereo to mono
+       if s.ndim > 1:
+               sz = numpy.shape(s);
+               if sz[0] < sz[1]:
+                       s = s.T;
+               s = numpy.sum(s, axis=0);
+       
+       sz = numpy.shape(s);
+       ## normalize
+       N = len(s);     
+       #signal = s/max(abs(s)) * 1.;
+       return s, N;
+       
+