]> git.parisson.com Git - timeside.git/commitdiff
Automatic discovering of processors
authorThomas Fillon <thomas@parisson.com>
Wed, 14 May 2014 10:35:42 +0000 (12:35 +0200)
committerThomas Fillon <thomas@parisson.com>
Wed, 14 May 2014 10:35:42 +0000 (12:35 +0200)
- Automatic discovering of processors by walking through timeside decoder, analyzer, encoder and grapher subpackages.
- Empty corresponding __init__ files i.e. remove explicit import of processors

33 files changed:
tests/test_AnalyzerResult.py
tests/test_analyzers_stress.py
tests/test_aubio_melenergy.py
tests/test_aubio_mfcc.py
tests/test_aubio_pitch.py
tests/test_aubio_specdesc.py
tests/test_aubio_temporal.py
tests/test_decoding_stack.py
tests/test_transcoding.py
tests/test_transcoding_streaming.py
timeside/__init__.py
timeside/analyzer/__init__.py
timeside/analyzer/aubio_melenergy.py [deleted file]
timeside/analyzer/aubio_mfcc.py [deleted file]
timeside/analyzer/aubio_pitch.py [deleted file]
timeside/analyzer/aubio_specdesc.py [deleted file]
timeside/analyzer/aubio_temporal.py [deleted file]
timeside/analyzer/level.py
timeside/analyzer/limsi_sad.py
timeside/analyzer/odf.py
timeside/analyzer/spectrogram.py
timeside/analyzer/waveform.py
timeside/analyzer/yaafe.py
timeside/api.py
timeside/core.py
timeside/decoder/__init__.py
timeside/decoder/array.py
timeside/decoder/core.py
timeside/decoder/file.py
timeside/decoder/live.py
timeside/encoder/__init__.py
timeside/grapher/__init__.py
timeside/grapher/render_analyzers.py

index 214bfaf1a6cf366be6a6a6e8220c93af3b34338e..27c32d6dcf46113b55ddd54976bac31a23d9c251 100755 (executable)
@@ -2,7 +2,7 @@
 
 from unit_timeside import unittest, TestRunner
 from timeside.analyzer.core import AnalyzerResult, AnalyzerResultContainer
-from timeside.__init__ import __version__
+from timeside import __version__
 import numpy as np
 from math import pi
 
index 7b7d91cf9f14df61d92517d8be639d4b86b349c5..1ce7bfbbd92c3e3b7e0a20586a4a0718befe7c1a 100755 (executable)
@@ -16,8 +16,8 @@ class TestAnalyzers_with_zeros(unittest.TestCase):
         samplerate = 16000  # LimsiSad require Fs = 16000 Hz
         duration = 10
         samples = np.zeros((duration * samplerate, 1))
-        self.decoder = timeside.decoder.ArrayDecoder(samples,
-                                                     samplerate=samplerate)
+        decoder_cls = timeside.core.get_processor('array_dec')
+        self.decoder = decoder_cls(samples, samplerate=samplerate)
 
     def _perform_test(self, analyzer_cls):
         """Internal function that test if there is NaN in the results
@@ -43,8 +43,8 @@ class TestAnalyzers_withDC(TestAnalyzers_with_zeros):
         samplerate = 16000  # LimsiSad require Fs = 16000 Hz
         duration = 10
         samples = -1000*np.ones((duration * samplerate, 1))
-        self.decoder = timeside.decoder.ArrayDecoder(samples,
-                                                     samplerate=samplerate)
+        decoder_cls = timeside.core.get_processor('array_dec')
+        self.decoder = decoder_cls(samples, samplerate=samplerate)
 
 
 def _tests_factory(test_class, test_doc, list_analyzers, skip_reasons={}):
index f5ff1d0a510a9732a748d70f2f0c755cfd811121..34163543ecc3cc68e288f17b901c85fb60263866 100755 (executable)
@@ -4,7 +4,7 @@ from unit_timeside import *
 from timeside.decoder.file import FileDecoder
 from timeside.analyzer import WITH_AUBIO
 if WITH_AUBIO:
-    from timeside.analyzer.aubio_melenergy import AubioMelEnergy
+    from timeside.analyzer.aubio.aubio_melenergy import AubioMelEnergy
 import os
 
 @unittest.skipIf(not WITH_AUBIO, 'Aubio library is not available')
index d7d5ce70589a43df52d58e69df32d365500043ba..3626aab881478c3875d37b60577bbd0385eb61ff 100755 (executable)
@@ -4,7 +4,7 @@ from unit_timeside import *
 from timeside.decoder.file import FileDecoder
 from timeside.analyzer import WITH_AUBIO
 if WITH_AUBIO:
-    from timeside.analyzer.aubio_mfcc import AubioMfcc
+    from timeside.analyzer.aubio.aubio_mfcc import AubioMfcc
 import os
 
 
index dc6022dbdf1f6e352b0323fb8f925dd85134d31a..b4904eddaf695b765ad7cc13106ffd0f08008d5e 100755 (executable)
@@ -4,7 +4,7 @@ from unit_timeside import *
 from timeside.decoder.file import FileDecoder
 from timeside.analyzer import WITH_AUBIO
 if WITH_AUBIO:
-    from timeside.analyzer.aubio_pitch import AubioPitch
+    from timeside.analyzer.aubio.aubio_pitch import AubioPitch
 import os
 
 
index 1fe125592b63ab44a448862b273398d557d6d924..de03a3eaa4467b1bbd55f37175441b573c99b76e 100755 (executable)
@@ -4,7 +4,7 @@ from unit_timeside import *
 from timeside.decoder.file import FileDecoder
 from timeside.analyzer import WITH_AUBIO
 if WITH_AUBIO:
-    from timeside.analyzer.aubio_specdesc import AubioSpecdesc
+    from timeside.analyzer.aubio.aubio_specdesc import AubioSpecdesc
 import os
 
 
index 2dd0801eaf1c70ef53c88e825aad70b773c298cf..77be8130c79c8f585ec8a204032be154bd552eb0 100755 (executable)
@@ -4,7 +4,7 @@ from unit_timeside import *
 from timeside.decoder.file import FileDecoder
 from timeside.analyzer import WITH_AUBIO
 if WITH_AUBIO:
-    from timeside.analyzer.aubio_temporal import AubioTemporal
+    from timeside.analyzer.aubio.aubio_temporal import AubioTemporal
 import os
 
 
index 4650a753cb1de0a663bb50c34175dfc1e1a27beb..819535210a58d19cdbbdeca38ccbc634b3322c87 100755 (executable)
@@ -3,9 +3,8 @@
 from __future__ import division
 
 from timeside.decoder.file import FileDecoder
-from timeside.analyzer import Level
+from timeside.analyzer.level import Level
 from timeside.core import ProcessPipe
-import numpy as np
 from unit_timeside import *
 
 import os.path
index a42aedc0ccc1db886135d82c9d8e3de0a26e46fc..7602ba226eb272b6f84a820ea4d3311e32d5f2d3 100755 (executable)
@@ -2,10 +2,8 @@
 
 from __future__ import division
 
-from timeside.core import *
+from timeside.core import get_processor, ProcessPipe
 from timeside.decoder.file import FileDecoder
-from timeside.analyzer import *
-from timeside.encoder import *
 from timeside.component import *
 
 from unit_timeside import *
@@ -24,43 +22,42 @@ class TestTranscodingFromWav(unittest.TestCase):
 
     def testWav(self):
         "Test conversion to wav"
-        self.encoder_function = WavEncoder
+        self.encoder_id = 'gst_wav_enc'
 
     def testMp3(self):
         "Test conversion to mp3"
-        self.encoder_function = Mp3Encoder
+        self.encoder_id = 'gst_mp3_enc'
 
     def testOgg(self):
         "Test conversion to ogg"
-        self.encoder_function = VorbisEncoder
+        self.encoder_id = 'gst_vorbis_enc'
 
     def testWebM(self):
         "Test conversion to webm"
-        self.encoder_function = WebMEncoder
+        self.encoder_id = 'gst_webm_enc'
         self.test_duration = False  # webmmux encoder with streamable=true
                                     # does not return a valid duration
 
     def testM4a(self):
         "Test conversion to m4a"
-        self.encoder_function = AacEncoder
+        self.encoder_id = 'gst_aac_enc'
 
     def tearDown(self):
         decoder = FileDecoder(self.source)
 
+        encoder_cls = get_processor(self.encoder_id)
 
-
-        file_extension = '.' + self.encoder_function.file_extension()
+        file_extension = '.' + encoder_cls.file_extension()
 
         self.target = tmp_file_sink(prefix=self.__class__.__name__,
                                   suffix=file_extension)
-        encoder = self.encoder_function(self.target)
+        encoder = encoder_cls(self.target)
         (decoder | encoder).run()
 
         decoder_encoded = FileDecoder(self.target)
 
-        from timeside.analyzer import Waveform
-        a = Waveform()  # Arbitrary analyzer for running the next pipe
-        (decoder_encoded | a).run()
+        pipe = ProcessPipe(decoder_encoded)
+        pipe.run()
 
         import os
         os.unlink(self.target)
index a7655fcd258df41182b67ca7bccc7c6c531e6ff3..3aa38fe3c4d53fc07a5c2a413cb64deabf7ddaf3 100755 (executable)
@@ -2,10 +2,10 @@
 
 from __future__ import division
 
-#from timeside.core import *
+from timeside.core import get_processor, ProcessPipe
 from timeside.decoder.file import FileDecoder
 #from timeside.analyzer import *
-from timeside.encoder import *
+#from timeside.encoder import *
 #from timeside.component import *
 
 from unit_timeside import *
@@ -26,28 +26,29 @@ class TestTranscodingStreaming(unittest.TestCase):
 
     def testMp3(self):
         "Test conversion to mp3"
-        self.encoder_function = Mp3Encoder
+        self.encoder_id = 'gst_mp3_enc'
         self.filesize_delta = 156
 
     def testOgg(self):
         "Test conversion to ogg"
-        self.encoder_function = VorbisEncoder
+        self.encoder_id = 'gst_vorbis_enc'
 
     def testOpus(self):
         "Test conversion to opus"
-        self.encoder_function = OpusEncoder
+        self.encoder_id = 'gst_opus_enc'
         self.expected_sample_rate = 48000
 
     def testWebM(self):
         "Test conversion to webm"
-        self.encoder_function = WebMEncoder
+        self.encoder_id = 'gst_webm_enc'
         self.test_duration = False  # webmmux encoder with streamable=true
                                     # does not return a valid duration
 
     def tearDown(self):
         decoder = FileDecoder(self.source)
+        encoder_cls = get_processor(self.encoder_id)
 
-        file_extension = '.' + self.encoder_function.file_extension()
+        file_extension = '.' + encoder_cls.file_extension()
 
         self.target_filesink = tmp_file_sink(prefix=self.__class__.__name__,
                                              suffix=file_extension)
@@ -55,7 +56,7 @@ class TestTranscodingStreaming(unittest.TestCase):
         self.target_appsink = tmp_file_sink(prefix=self.__class__.__name__,
                                             suffix=file_extension)
 
-        encoder = self.encoder_function(self.target_filesink, streaming=True)
+        encoder = encoder_cls(self.target_filesink, streaming=True)
         pipe = (decoder | encoder)
 
         with open(self.target_appsink, 'w') as f:
index f1a0bcd0184e278512aac20824e88756d3908732..9bc74e0d6dbfd94cc3cfbe5420d03c575fbc820f 100644 (file)
@@ -1,37 +1,46 @@
 # -*- coding: utf-8 -*-
+from __future__ import absolute_import
 
-import api
-import core
-import decoder
-import analyzer
-import grapher
-import encoder
+from . import api
+from . import core
+from . import decoder
+from . import analyzer
+from . import grapher
+from . import encoder
 
 __version__ = '0.5.5'
 
 __all__ = ['api', 'core', 'decoder', 'analyzer', 'grapher', 'encoder']
 
-print __file__
-print __name__
 
 def _discover_modules():
     import sys
     import pkgutil
     import importlib
-    pkg = 'timeside'
-    #__import__(pkg)
-    package = sys.modules[pkg]
-    prefix = pkg + "."
 
-    for importer, modname, ispkg in pkgutil.iter_modules(package.__path__,
-                                                          prefix):
-        #print modname
-        if modname.split('.')[1] in ['decoder', 'analyzer', 'encoder', 'grapher']:
-            print modname
-            mod = importlib.import_module(modname)
+    #pkg_path = os.path.abspath()
 
-            del mod
-        del modname
+    #__import__(pkg)
 
+    proc_modules = ['decoder', 'analyzer', 'encoder', 'grapher']
+
+    for module in proc_modules:
+        pkg = '.'.join([__name__, module])
+        importlib.import_module(pkg)
+        package = sys.modules[pkg]
+        prefix = pkg + "."
+
+        for importer, modname, ispkg in pkgutil.walk_packages(package.__path__,
+                                                              prefix):
+            try:
+                importlib.import_module(modname)
+                #__import__(modname)
+            except ImportError as e:
+                if e.message.find('yaafelib'):
+                    print 'No Yaafe'
+                elif e.message.find('aubio'):
+                    print 'No aubio'
+                else:
+                    raise e
 
 _discover_modules()
index b49b82aeb8c73b538b4d142a1aa57cda44ec4b77..7da90fd52b7c79246469b7da44159d3588d20424 100644 (file)
@@ -1,41 +1,27 @@
 # -*- coding: utf-8 -*-
+from __future__ import absolute_import
 
 # ----- Load external libraries ------
 # Aubio
 try:
     WITH_AUBIO = True
-    from aubio_temporal import AubioTemporal
-    from aubio_pitch import AubioPitch
-    from aubio_mfcc import AubioMfcc
-    from aubio_melenergy import AubioMelEnergy
-    from aubio_specdesc import AubioSpecdesc
+    import aubio
 except ImportError:
     WITH_AUBIO = False
-
+else:
+    del aubio
 # Yaafe
 try:
     WITH_YAAFE = True
-    from yaafe import Yaafe
-
+    import yaafelib
 except ImportError:
     WITH_YAAFE = False
-
+else:
+    del yaafelib
 # Vamp Plugins
 try:
-    from vamp_plugin import VampSimpleHost
+    from vamp_plugin import VampSimpleHost
     VampSimpleHost.SimpleHostProcess(['-v'])
     WITH_VAMP = True
 except OSError:
     WITH_VAMP = False
-
-
-# ----- Load timeside analyzers ------
-from level import Level
-from dc import MeanDCShift
-from spectrogram import Spectrogram
-from waveform import Waveform
-from irit_speech_entropy import IRITSpeechEntropy
-from irit_speech_4hz import IRITSpeech4Hz
-from odf import OnsetDetectionFunction
-if WITH_YAAFE:
-    from limsi_sad import LimsiSad
diff --git a/timeside/analyzer/aubio_melenergy.py b/timeside/analyzer/aubio_melenergy.py
deleted file mode 100644 (file)
index 8bb8616..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2013 Paul Brossier <piem@piem.org>
-
-# 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: Paul Brossier <piem@piem.org>
-
-from timeside.core import implements, interfacedoc
-from timeside.analyzer.core import Analyzer
-from timeside.api import IAnalyzer
-from preprocessors import downmix_to_mono, frames_adapter
-
-import numpy
-from aubio import filterbank, pvoc
-
-
-class AubioMelEnergy(Analyzer):
-
-    """Aubio Mel Energy analyzer"""
-    implements(IAnalyzer)
-
-    def __init__(self):
-        super(AubioMelEnergy, self).__init__()
-        self.input_blocksize = 1024
-        self.input_stepsize = self.input_blocksize / 4
-
-    @interfacedoc
-    def setup(self, channels=None, samplerate=None,
-              blocksize=None, totalframes=None):
-        super(AubioMelEnergy, self).setup(
-            channels, samplerate, blocksize, totalframes)
-        self.n_filters = 40
-        self.n_coeffs = 13
-        self.pvoc = pvoc(self.input_blocksize, self.input_stepsize)
-        self.melenergy = filterbank(self.n_filters, self.input_blocksize)
-        self.melenergy.set_mel_coeffs_slaney(samplerate)
-        self.block_read = 0
-        self.melenergy_results = []
-
-    @staticmethod
-    @interfacedoc
-    def id():
-        return "aubio_melenergy"
-
-    @staticmethod
-    @interfacedoc
-    def name():
-        return "Mel Energy (aubio)"
-
-    @staticmethod
-    @interfacedoc
-    def unit():
-        return ""
-
-    @downmix_to_mono
-    @frames_adapter
-    def process(self, frames, eod=False):
-
-        fftgrain = self.pvoc(frames)
-        self.melenergy_results.append(self.melenergy(fftgrain))
-        self.block_read += 1
-        return frames, eod
-
-    def post_process(self):
-        melenergy = self.new_result(data_mode='value', time_mode='framewise')
-        melenergy.parameters = dict(n_filters=self.n_filters,
-                                    n_coeffs=self.n_coeffs)
-        melenergy.data_object.value = self.melenergy_results
-        self.process_pipe.results.add(melenergy)
diff --git a/timeside/analyzer/aubio_mfcc.py b/timeside/analyzer/aubio_mfcc.py
deleted file mode 100644 (file)
index 36bc208..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2013 Paul Brossier <piem@piem.org>
-
-# 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: Paul Brossier <piem@piem.org>
-
-from timeside.core import implements, interfacedoc
-from timeside.analyzer.core import Analyzer
-from timeside.api import IAnalyzer
-from preprocessors import downmix_to_mono, frames_adapter
-
-import numpy
-from aubio import mfcc, pvoc
-
-
-class AubioMfcc(Analyzer):
-
-    """Aubio MFCC analyzer"""
-    implements(IAnalyzer)
-
-    def __init__(self):
-        super(AubioMfcc, self).__init__()
-        self.input_blocksize = 1024
-        self.input_stepsize = self.input_blocksize / 4
-
-    @interfacedoc
-    def setup(self, channels=None, samplerate=None,
-              blocksize=None, totalframes=None):
-        super(AubioMfcc, self).setup(
-            channels, samplerate, blocksize, totalframes)
-        self.n_filters = 40
-        self.n_coeffs = 13
-        self.pvoc = pvoc(self.input_blocksize, self.input_stepsize)
-        self.mfcc = mfcc(self.input_blocksize,
-                         self.n_filters,
-                         self.n_coeffs,
-                         samplerate)
-        self.block_read = 0
-        self.mfcc_results = numpy.zeros([self.n_coeffs, ])
-
-    @staticmethod
-    @interfacedoc
-    def id():
-        return "aubio_mfcc"
-
-    @staticmethod
-    @interfacedoc
-    def name():
-        return "MFCC (aubio)"
-
-    @staticmethod
-    @interfacedoc
-    def unit():
-        return ""
-
-    @downmix_to_mono
-    @frames_adapter
-    def process(self, frames, eod=False):
-        fftgrain = self.pvoc(frames)
-        coeffs = self.mfcc(fftgrain)
-        self.mfcc_results = numpy.vstack((self.mfcc_results, coeffs))
-        self.block_read += 1
-        return frames, eod
-
-    def post_process(self):
-        mfcc = self.new_result(data_mode='value', time_mode='framewise')
-        mfcc.parameters = dict(n_filters=self.n_filters,
-                               n_coeffs=self.n_coeffs)
-        mfcc.data_object.value = self.mfcc_results
-        self.process_pipe.results.add(mfcc)
diff --git a/timeside/analyzer/aubio_pitch.py b/timeside/analyzer/aubio_pitch.py
deleted file mode 100644 (file)
index 4e1c764..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2013 Paul Brossier <piem@piem.org>
-
-# 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: Paul Brossier <piem@piem.org>
-
-from ..core import implements, interfacedoc
-from .core import Analyzer
-from ..api import IAnalyzer
-from preprocessors import downmix_to_mono, frames_adapter
-from aubio import pitch
-import numpy as np
-
-
-class AubioPitch(Analyzer):
-
-    """Aubio Pitch estimation analyzer"""
-    implements(IAnalyzer)  # TODO check if needed with inheritance
-
-    def __init__(self):
-        super(AubioPitch, self).__init__()
-        self.input_blocksize = 2048
-        self.input_stepsize = self.input_blocksize / 2
-
-    @interfacedoc
-    def setup(self, channels=None, samplerate=None,
-              blocksize=None, totalframes=None):
-        super(AubioPitch, self).setup(channels,
-                                      samplerate,
-                                      blocksize,
-                                      totalframes)
-        self.aubio_pitch = pitch(
-            "default", self.input_blocksize, self.input_stepsize,
-            samplerate)
-        self.aubio_pitch.set_unit("freq")
-        self.block_read = 0
-        self.pitches = []
-        self.pitch_confidences = []
-
-    @staticmethod
-    @interfacedoc
-    def id():
-        return "aubio_pitch"
-
-    @staticmethod
-    @interfacedoc
-    def name():
-        return "f0 (aubio)"
-
-    @staticmethod
-    @interfacedoc
-    def unit():
-        return "Hz"
-
-    def __str__(self):
-        return "pitch values"
-
-    @downmix_to_mono
-    @frames_adapter
-    def process(self, frames, eod=False):
-        #time = self.block_read * self.input_stepsize * 1. / self.samplerate()
-        self.pitches += [self.aubio_pitch(frames)[0]]
-        self.pitch_confidences += [
-            np.nan_to_num(self.aubio_pitch.get_confidence())]
-        self.block_read += 1
-        return frames, eod
-
-    def post_process(self):
-        pitch = self.new_result(data_mode='value', time_mode='framewise')
-
-        # parameters : None # TODO check with Piem "default" and "freq" in
-        # setup
-
-        pitch.id_metadata.id += '.' + "pitch"
-        pitch.id_metadata.name += ' ' + "pitch"
-        pitch.id_metadata.unit = "Hz"
-        pitch.data_object.value = self.pitches
-        self.process_pipe.results.add(pitch)
-
-        pitch_confidence = self.new_result(
-            data_mode='value', time_mode='framewise')
-        pitch_confidence.id_metadata.id += '.' + "pitch_confidence"
-        pitch_confidence.id_metadata.name += ' ' + "pitch confidence"
-        pitch_confidence.id_metadata.unit = None
-        pitch_confidence.data_object.value = self.pitch_confidences
-        self.process_pipe.results.add(pitch_confidence)
diff --git a/timeside/analyzer/aubio_specdesc.py b/timeside/analyzer/aubio_specdesc.py
deleted file mode 100644 (file)
index cc19fb6..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2013 Paul Brossier <piem@piem.org>
-
-# 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: Paul Brossier <piem@piem.org>
-
-from timeside.core import Processor, implements, interfacedoc, FixedSizeInputAdapter
-from timeside.analyzer.core import Analyzer
-from timeside.api import IAnalyzer
-from preprocessors import downmix_to_mono, frames_adapter
-
-from aubio import specdesc, pvoc
-
-
-class AubioSpecdesc(Analyzer):
-
-    """Aubio Spectral Descriptors collection analyzer"""
-    implements(IAnalyzer)
-
-    def __init__(self):
-        super(AubioSpecdesc, self).__init__()
-        self.input_blocksize = 1024
-        self.input_stepsize = self.input_blocksize / 4
-
-    @interfacedoc
-    def setup(self, channels=None, samplerate=None,
-              blocksize=None, totalframes=None):
-        super(
-            AubioSpecdesc,
-            self).setup(
-            channels,
-            samplerate,
-            blocksize,
-            totalframes)
-        self.block_read = 0
-        self.pvoc = pvoc(self.input_blocksize, self.input_stepsize)
-        self.methods = [
-            'default', 'energy', 'hfc', 'complex', 'phase', 'specdiff', 'kl',
-            'mkl', 'specflux', 'centroid', 'slope', 'rolloff', 'spread', 'skewness',
-            'kurtosis', 'decrease']
-        self.specdesc = {}
-        self.specdesc_results = {}
-        for method in self.methods:
-            self.specdesc[method] = specdesc(method, self.input_blocksize)
-            self.specdesc_results[method] = []
-
-    @staticmethod
-    @interfacedoc
-    def id():
-        return "aubio_specdesc"
-
-    @staticmethod
-    @interfacedoc
-    def name():
-        return "Spectral Descriptor (aubio)"
-
-    @staticmethod
-    @interfacedoc
-    def unit():
-        return ""
-
-    @downmix_to_mono
-    @frames_adapter
-    def process(self, frames, eod=False):
-        fftgrain = self.pvoc(frames)
-        for method in self.methods:
-            self.specdesc_results[method] += [
-                self.specdesc[method](fftgrain)[0]]
-        return frames, eod
-
-    def post_process(self):
-
-        # For each method store results in container
-        for method in self.methods:
-            res_specdesc = self.new_result(data_mode='value',
-                                           time_mode='framewise')
-            # Set metadata
-            res_specdesc.id_metadata.id += '.' + method
-            res_specdesc.id_metadata.name = ' ' + method
-            res_specdesc.data_object.value = self.specdesc_results[method]
-
-            self.process_pipe.results.add(res_specdesc)
diff --git a/timeside/analyzer/aubio_temporal.py b/timeside/analyzer/aubio_temporal.py
deleted file mode 100644 (file)
index f4be03f..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2013 Paul Brossier <piem@piem.org>
-
-# 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: Paul Brossier <piem@piem.org>
-
-from timeside.core import implements, interfacedoc
-from timeside.analyzer.core import Analyzer
-from timeside.api import IAnalyzer
-from preprocessors import downmix_to_mono, frames_adapter
-from aubio import onset, tempo
-
-import numpy
-
-
-class AubioTemporal(Analyzer):
-
-    """Aubio Temporal analyzer"""
-    implements(IAnalyzer)
-
-    def __init__(self):
-        super(AubioTemporal, self).__init__()
-        self.input_blocksize = 1024
-        self.input_stepsize = 256
-
-    @interfacedoc
-    def setup(self,
-              channels=None,
-              samplerate=None,
-              blocksize=None,
-              totalframes=None):
-        super(AubioTemporal, self).setup(
-            channels, samplerate, blocksize, totalframes)
-        self.o = onset(
-            "default", self.input_blocksize, self.input_stepsize, samplerate)
-        self.t = tempo(
-            "default", self.input_blocksize, self.input_stepsize, samplerate)
-        self.block_read = 0
-        self.onsets = []
-        self.beats = []
-        self.beat_confidences = []
-
-    @staticmethod
-    @interfacedoc
-    def id():
-        return "aubio_temporal"
-
-    @staticmethod
-    @interfacedoc
-    def name():
-        return "onsets (aubio)"
-
-    @staticmethod
-    @interfacedoc
-    def unit():
-        return ""
-
-    def __str__(self):
-        return "%s %s" % (str(self.value), self.unit())
-
-    @downmix_to_mono
-    @frames_adapter
-    def process(self, frames, eod=False):
-        if self.o(frames):
-            self.onsets += [self.o.get_last_s()]
-        if self.t(frames):
-            self.beats += [self.t.get_last_s()]
-            self.beat_confidences += [self.t.get_confidence()]
-        self.block_read += 1
-        return frames, eod
-
-    def post_process(self):
-
-        #---------------------------------
-        #  Onsets: Event (time, "Onset")
-        #---------------------------------
-        onsets = self.new_result(data_mode='label', time_mode='event')
-        onsets.id_metadata.id += '.' + 'onset'
-        onsets.id_metadata.name += ' ' + 'Onset'
-        onsets.id_metadata.unit = 's'
-        onsets.data_object.time = self.onsets
-        onsets.data_object.label = numpy.ones(len(self.onsets))
-        onsets.label_metadata.label = {1: 'Onset'}
-
-        self.process_pipe.results.add(onsets)
-
-        #---------------------------------
-        #  Onset Rate: Segment (time, duration, value)
-        #---------------------------------
-        onsetrate = self.new_result(data_mode='value', time_mode='segment')
-        onsetrate.id_metadata.id += '.' + "onset_rate"
-        onsetrate.id_metadata.name = " " + "Onset Rate"
-        onsetrate.id_metadata.unit = "bpm"
-        if len(self.onsets) > 1:
-            periods = numpy.diff(self.onsets)
-            periods = numpy.append(periods, periods[-1])
-            onsetrate.data_object.time = self.onsets
-            onsetrate.data_object.duration = periods
-            onsetrate.data_object.value = 60. / periods
-        else:
-            onsetrate.data_object.value = []
-            onsetrate.data_object.time = []
-
-        self.process_pipe.results.add(onsetrate)
-
-        #---------------------------------
-        #  Beats: Event (time, "Beat")
-        #---------------------------------
-        beats = self.new_result(data_mode='label', time_mode='event')
-        beats.id_metadata.id += '.' + "beat"
-        beats.id_metadata.name += " " + "Beats"
-        beats.id_metadata.unit = "s"
-        beats.data_object.time = self.beats
-        beats.data_object.label = numpy.ones(len(self.beats))
-        beats.label_metadata.label = {1: 'Beat'}
-
-        self.process_pipe.results.add(beats)
-
-        #---------------------------------
-        #  Beat confidences: Event (time, value)
-        #---------------------------------
-        beat_confidences = self.new_result(
-            data_mode='value', time_mode='event')
-        beat_confidences.id_metadata.id += '.' + "beat_confidence"
-        beat_confidences.id_metadata.name += " " + "Beat confidences"
-        beat_confidences.id_metadata.unit = None
-        beat_confidences.data_object.time = self.beats
-        beat_confidences.data_object.value = self.beat_confidences
-
-        self.process_pipe.results.add(beat_confidences)
-
-        #---------------------------------
-        #  BPM: Segment (time, duration, value)
-        #---------------------------------
-        bpm = self.new_result(data_mode='value', time_mode='segment')
-        bpm.id_metadata.id += '.' + "bpm"
-        bpm.id_metadata.name += ' ' + "bpm"
-        bpm.id_metadata.unit = "bpm"
-        if len(self.beats) > 1:
-            periods = numpy.diff(self.beats)
-            periods = numpy.append(periods, periods[-1])
-            bpm.data_object.time = self.beats
-            bpm.data_object.duration = periods
-            bpm.data_object.value = 60. / periods
-        else:
-            bpm.data_object.value = []
-
-        self.process_pipe.results.add(bpm)
index 574f26d726cf80c0dea1f0da0e80b6e82f845802..8136ad983334a36b079963fbb5556765a383c377 100644 (file)
@@ -24,7 +24,7 @@ from timeside.core import implements, interfacedoc
 from timeside.analyzer.core import Analyzer
 from timeside.api import IValueAnalyzer
 import numpy as np
-from .utils import MACHINE_EPSILON
+from timeside.analyzer.utils import MACHINE_EPSILON
 
 
 class Level(Analyzer):
index 294d9533b3aa349725135bd03386d504413212c5..9044c5287971e0cef684e2ecd123be5d27dc3423 100644 (file)
@@ -23,7 +23,8 @@ from timeside.core import implements, interfacedoc
 from timeside.analyzer.core import Analyzer
 from timeside.api import IAnalyzer
 import timeside
-from timeside.analyzer import WITH_YAAFE
+#from timeside.analyzer import WITH_YAAFE
+WITH_YAAFE = True
 if WITH_YAAFE:
     from yaafe import Yaafe
     import yaafelib
index 75520eda58031fa1e25b2ec9536aca6e162a8ae9..7320296b728665d15aa7a1d957a798186c44d45a 100644 (file)
@@ -21,7 +21,7 @@
 
 from timeside.core import implements, interfacedoc
 from timeside.analyzer.core import Analyzer
-from timeside.analyzer import Spectrogram
+from .spectrogram import Spectrogram
 from timeside.api import IAnalyzer
 import numpy as np
 from numpy import pi as Pi
index ee708624c90fe83d6d215219b6b0b83dd8a7f858..d30c2e8b313fe96dd7413b4ae39a53645667e701 100644 (file)
@@ -22,7 +22,7 @@
 from timeside.core import implements, interfacedoc
 from timeside.analyzer.core import Analyzer
 from timeside.api import IAnalyzer
-from preprocessors import downmix_to_mono, frames_adapter
+from timeside.analyzer.preprocessors import downmix_to_mono, frames_adapter
 import numpy as np
 
 
index b5fdbd14e8458ec71f06538f59750356a31e9b6b..bdd1a9b156eab242a8014694082ab1b9f59acc52 100644 (file)
@@ -24,7 +24,7 @@ from timeside.analyzer.core import Analyzer
 from timeside.api import IAnalyzer
 import numpy as np
 
-from preprocessors import downmix_to_mono, frames_adapter
+from timeside.analyzer.preprocessors import downmix_to_mono, frames_adapter
 
 
 class Waveform(Analyzer):
index 7024c464f497cb2e7c7ddb592f0039071e98e2ff..978753fbe8f884d79a8ddd37ef96ebb626f908af 100644 (file)
@@ -27,7 +27,8 @@ Created on Thu Jun 13 16:05:02 2013
 from timeside.core import implements, interfacedoc
 from timeside.analyzer.core import Analyzer
 from timeside.api import IAnalyzer
-from timeside.analyzer import WITH_YAAFE
+#from timeside.analyzer import WITH_YAAFE
+WITH_YAAFE = True
 if WITH_YAAFE:
     from yaafelib import *
 import numpy
index 97447fb542b11947434ea4ddb50ee9b2311861de..38e7632fa4482f834324cf0af0da1832397db59e 100644 (file)
 
 # You should have received a copy of the GNU General Public License
 # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
+from __future__ import absolute_import
 
 
-from timeside.component import Interface
+from .component import Interface
 
 
 class IProcessor(Interface):
index 0d68cc750323b31fc48329e1a28fc0e4019bd622..723a1822eecc2df47145e3df3266b9056c2fb6f3 100644 (file)
 # You should have received a copy of the GNU General Public License
 # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
 
-from timeside.component import *
-from timeside.api import IProcessor
-from timeside.exceptions import Error, ApiError
-
+from .component import Component, MetaComponent, abstract
+from .component import implements, implementations, interfacedoc
+from .api import IProcessor
+from .exceptions import Error, ApiError
 
 import re
-import time
 import numpy
 import uuid
 
@@ -39,9 +38,8 @@ _processors = {}
 
 
 class MetaProcessor(MetaComponent):
-
-    """Metaclass of the Processor class, used mainly for ensuring that processor
-    id's are wellformed and unique"""
+    """Metaclass of the Processor class, used mainly for ensuring
+    that processor id's are wellformed and unique"""
 
     valid_id = re.compile("^[a-z][_a-z0-9]*$")
 
@@ -58,7 +56,8 @@ class MetaProcessor(MetaComponent):
                     pass
                 else:
                     raise ApiError("%s and %s have the same id: '%s'"
-                                   % (new_class.__name__, _processors[id].__name__, id))
+                                   % (new_class.__name__,
+                                      _processors[id].__name__, id))
             if not MetaProcessor.valid_id.match(id):
                 raise ApiError("%s has a malformed id: '%s'"
                                % (new_class.__name__, id))
@@ -76,7 +75,7 @@ class Processor(Component):
     Attributes:
               parents :  List of parent Processors that must be processed
                          before the current Processor
-              pipe :     The current ProcessPipe in which the Processor will run
+              pipe :     The ProcessPipe in which the Processor will run
         """
     __metaclass__ = MetaProcessor
 
index ebd2f39496e079e6bfcd87100a73f0d879cb683f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,7 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#from file import FileDecoder
-#from array import ArrayDecoder
-#from live import LiveDecoder
-#
-#__all__ = ['FileDecoder', 'ArrayDecoder', 'LiveDecoder']
index 4dacc4cbe10a3fc6e94952dbf0dd5e1c7a4eb4e0..d5abd4bf0b1e3ca47216bc09902c7a854b911d4c 100644 (file)
@@ -28,7 +28,7 @@
 
 
 from timeside.decoder.core import *
-
+import numpy as np
 
 class ArrayDecoder(Decoder):
 
index f3f9afbdea38708db899f28c6354056d60b62bc2..9c2307fb12a32f2023927aaf1f4a394163d66825 100644 (file)
@@ -32,16 +32,6 @@ from timeside.core import Processor, implements, interfacedoc, abstract
 from timeside.api import IDecoder
 from timeside.tools import *
 
-from utils import get_uri, get_media_uri_info, stack, get_sha1
-
-import Queue
-from gst import _gst as gst
-import numpy as np
-
-
-GST_APPSINK_MAX_BUFFERS = 10
-QUEUE_SIZE = 10
-
 
 class Decoder(Processor):
 
index 88bedc1b995abcb96b35acf96b6e411bcec12b1c..2da8f6dadea5e8e499178237c74fecf796e5210b 100644 (file)
 
 from __future__ import division
 
-from timeside.decoder.core import *
-from timeside.tools.gstutils import MainloopThread
+from timeside.decoder.core import Decoder, IDecoder, implements, interfacedoc
+from timeside.tools.gstutils import MainloopThread, gobject, gst_buffer_to_numpy_array
 import threading
 
+from timeside.decoder.utils import get_uri, get_media_uri_info, stack, get_sha1
+
+import Queue
+from gst import _gst as gst
+
+GST_APPSINK_MAX_BUFFERS = 10
+QUEUE_SIZE = 10
+
+import numpy as np
+
 
 class FileDecoder(Decoder):
 
index c8dcb8d0f566ac7e026988d76ba1ab0794655ea1..0651d5dc68ac1e08d767c2e316f1201cb81d97fa 100644 (file)
@@ -31,6 +31,13 @@ from __future__ import division
 from timeside.decoder.core import *
 from timeside.tools.gstutils import MainloopThread
 
+import Queue
+from gst import _gst as gst
+
+
+GST_APPSINK_MAX_BUFFERS = 10
+QUEUE_SIZE = 10
+
 
 class LiveDecoder(Decoder):
 
index f04257de8920e0e7c58dd8ca7cce679b53cdd277..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,13 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#from ogg import VorbisEncoder
-#from wav import WavEncoder
-#from mp3 import Mp3Encoder
-#from flac import FlacEncoder
-#from m4a import AacEncoder
-#from webm import WebMEncoder
-#from audiosink import AudioSink
-#from opus import OpusEncoder
-#
-#__all__ = ['VorbisEncoder', 'WavEncoder', 'Mp3Encoder', 'FlacEncoder',
-#           'AacEncoder', 'WebMEncoder', 'AudioSink', 'OpusEncoder']
index e362997d7cbb9955f0d89480a983610c03935e8b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from waveform_simple import Waveform
-from waveform_centroid import WaveformCentroid
-from waveform_transparent import WaveformTransparent
-from waveform_contour import WaveformContourBlack, WaveformContourWhite
-from spectrogram_log import SpectrogramLog
-from spectrogram_lin import SpectrogramLinear
-from render_analyzers import DisplayOnsetDetectionFunction, DisplayWaveform
-from render_analyzers import Display4hzSpeechSegmentation
-
-__all__ = ['Waveform', 'WaveformCentroid', 'WaveformTransparent',
-           'WaveformContourBlack', 'WaveformContourWhite',
-           'SpectrogramLog', 'SpectrogramLinear',
-           'DisplayOnsetDetectionFunction', 'DisplayWaveform',
-           'Display4hzSpeechSegmentation']
index a100d839e150b26d21699314de54a0cfa33b2d6d..c16e9f3715312cdba3d204ec69c2c6e042f20208 100644 (file)
 # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
 from __future__ import division
 
-from timeside.core import implements, interfacedoc, abstract
+from timeside.core import implements, interfacedoc, abstract, get_processor
 from timeside.api import IGrapher
 from core import Grapher, Image
-from timeside import analyzer
+from .. import analyzer
 
 
 class DisplayAnalyzer(Grapher):
@@ -96,24 +96,24 @@ class DisplayAnalyzer(Grapher):
 
 # From here define new Grapher based on Analyzers
 if analyzer.WITH_AUBIO:
-    aubiopitch = analyzer.AubioPitch()
+    aubiopitch = get_processor('aubio_pitch')
     DisplayAubioPitch = DisplayAnalyzer.create(analyzer=aubiopitch,
                                                result_id='aubio_pitch.pitch',
                                                grapher_id='grapher_aubio_pitch',
                                                grapher_name='Aubio Pitch')
 
 
-odf = analyzer.OnsetDetectionFunction()
+odf = get_processor('odf')
 DisplayOnsetDetectionFunction = DisplayAnalyzer.create(analyzer=odf,
                                                        result_id='odf',
                                                        grapher_id='grapher_odf',
                                                        grapher_name='Onset detection function')
-wav = analyzer.Waveform()
+wav = get_processor('waveform_analyzer')
 DisplayWaveform = DisplayAnalyzer.create(analyzer=wav,
                                          result_id='waveform_analyzer',
                                          grapher_id='grapher_waveform',
                                          grapher_name='Waveform from Analyzer')
-irit4hz = analyzer.IRITSpeech4Hz()
+irit4hz = get_processor('irit_speech_4hz')
 Display4hzSpeechSegmentation = DisplayAnalyzer.create(analyzer=irit4hz,
                                                       result_id='irit_speech_4hz.segments',
                                                       grapher_id='grapher_irit_speech_4hz_segments',