]> git.parisson.com Git - timeside.git/commitdiff
add SpectorgramBuffer with an extensible buffer based on tables, update docstrings
authorGuillaume Pellerin <yomguy@parisson.com>
Thu, 23 Oct 2014 11:08:02 +0000 (13:08 +0200)
committerGuillaume Pellerin <yomguy@parisson.com>
Thu, 23 Oct 2014 11:08:02 +0000 (13:08 +0200)
timeside/analyzer/spectrogram.py
timeside/analyzer/spectrogram_buffer.py [new file with mode: 0644]
timeside/core.py
timeside/grapher/render_analyzers.py
timeside/grapher/spectrogram_log.py

index 34c9c753fcba2378948e79f5506414ba9abe7236..5819153a7ac6eb162a9c4ad85781de909cc17827 100644 (file)
@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2013-2014 Parisson SARL
-# Copyright (c) 2013-2014 Thomas Fillon
+# Copyright (c) 2013 Paul Brossier <piem@piem.org>
 
 # This file is part of TimeSide.
 
 # You should have received a copy of the GNU General Public License
 # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
 
-# Author: Thomas Fillon <thomas@parisson.com>
-
+# Author: Paul Brossier <piem@piem.org>
 from __future__ import division
 from timeside.core import implements, interfacedoc
 from timeside.analyzer.core import Analyzer
 from timeside.api import IAnalyzer
 from timeside.analyzer.preprocessors import downmix_to_mono, frames_adapter
-from timeside.tools.parameters import Int, HasTraits
 from timeside.tools.buffering import BufferTable
+from ..tools.parameters import Int, HasTraits
+from timeside.tools.pyx.cfft import cfft
 
 import numpy as np
 
 
 class Spectrogram(Analyzer):
+
     """
-    Spectrogram analyzer
+    Spectrogram image builder with an extensible buffer based on tables
 
     Parameters
     ----------
@@ -73,9 +73,8 @@ class Spectrogram(Analyzer):
       pipe.run()
       res = spectrogram.results['spectrogram_analyzer']
       res.render()
-
-
     """
+
     implements(IAnalyzer)
 
     # Define Parameters
@@ -99,7 +98,7 @@ class Spectrogram(Analyzer):
         else:
             self.fft_size = fft_size
 
-        self.values = BufferTable()
+        self.values = []
 
     @interfacedoc
     def setup(self, channels=None, samplerate=None,
@@ -125,24 +124,22 @@ class Spectrogram(Analyzer):
     @downmix_to_mono
     @frames_adapter
     def process(self, frames, eod=False):
-            stft = np.fft.rfft(frames, self.fft_size)
-            self.values.append('stft', stft)
-            return frames, eod
+        self.values.append(np.abs(np.fft.rfft(frames, self.fft_size)))
+        return frames, eod
 
     def post_process(self):
         spectrogram = self.new_result(data_mode='value', time_mode='framewise')
         spectrogram.parameters = {'fft_size': self.fft_size}
-        spectrogram.data_object.value = np.abs(self.values['stft'])
+        # spectrogram.data_object.value = self.values['spectrogram']
+        spectrogram.data_object.value = self.values
         nb_freq = spectrogram.data_object.value.shape[1]
         spectrogram.data_object.y_value = (np.arange(0, nb_freq) *
                                            self.samplerate() / self.fft_size)
 
         self.add_result(spectrogram)
 
-    def release(self):
-        self.values.close()
 
 if __name__ == "__main__":
     import doctest
     import timeside
-    doctest.testmod(timeside.analyzer.spectrogram, verbose=True)
+    doctest.testmod(timeside.analyzer.spectrogram, verbose=True)
\ No newline at end of file
diff --git a/timeside/analyzer/spectrogram_buffer.py b/timeside/analyzer/spectrogram_buffer.py
new file mode 100644 (file)
index 0000000..25edaac
--- /dev/null
@@ -0,0 +1,110 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2013-2014 Parisson SARL
+# Copyright (c) 2013-2014 Thomas Fillon
+
+# 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: Thomas Fillon <thomas@parisson.com>
+
+from __future__ import division
+from timeside.core import implements, interfacedoc
+from timeside.analyzer.core import Analyzer
+from timeside.api import IAnalyzer
+from timeside.analyzer.preprocessors import downmix_to_mono, frames_adapter
+from timeside.tools.parameters import Int, HasTraits
+from timeside.tools.buffering import BufferTable
+from timeside.analyzer.spectrogram import Spectrogram
+
+import numpy as np
+
+
+class SpectrogramBuffer(Spectrogram):
+    """
+    Spectrogram image builder with an extensible buffer based on tables
+
+    Parameters
+    ----------
+    input_blocksize : int, optional
+        Blocksize of the input signal, default to 2048
+    input_stepsize : str, optional
+        The second parameter, default to half blocksize.
+    fft_size : int, optional
+        The size of the fft, default to blocksize.
+
+    Examples
+    --------
+    >>> import timeside
+    >>> from timeside.core import get_processor
+    >>> from timeside.tools.test_samples import samples
+    >>> audio_source = samples['sweep.wav']
+    >>> decoder = get_processor('file_decoder')(uri=audio_source)
+    >>> spectrogram = get_processor('spectrogram_analyzer')(input_blocksize=2048, input_stepsize=1024)
+    >>> pipe = (decoder | spectrogram)
+    >>> pipe.run()
+    >>> spectrogram.results.keys()
+    ['spectrogram_analyzer']
+    >>> result = spectrogram.results['spectrogram_analyzer']
+    >>> result.data.shape
+    (344, 1025)
+
+     .. plot::
+
+      import timeside
+      from timeside.core import get_processor
+      from timeside.tools.test_samples import samples
+      audio_source = samples['sweep.wav']
+      decoder = get_processor('file_decoder')(uri=audio_source)
+      spectrogram = get_processor('spectrogram_analyzer')(input_blocksize=2048,
+                                                          input_stepsize=1024)
+      pipe = (decoder | spectrogram)
+      pipe.run()
+      res = spectrogram.results['spectrogram_analyzer']
+      res.render()
+    """
+
+    implements(IAnalyzer)
+
+    def __init__(self, input_blocksize=2048, input_stepsize=None,
+                 fft_size=None):
+        super(SpectrogramBuffer, self).__init__()
+        self.values = BufferTable()
+
+    @staticmethod
+    @interfacedoc
+    def id():
+        return "spectrogram_analyzer_buffer"
+
+    @staticmethod
+    @interfacedoc
+    def name():
+        return "Spectrogram Analyzer with extensible buffer"
+
+    @downmix_to_mono
+    @frames_adapter
+    def process(self, frames, eod=False):
+            stft = np.fft.rfft(frames, self.fft_size)
+            self.values.append('stft', stft)
+            return frames, eod
+
+    def release(self):
+        self.values.close()
+
+
+if __name__ == "__main__":
+    import doctest
+    import timeside
+    doctest.testmod(timeside.analyzer.spectrogram_buffer, verbose=True)
\ No newline at end of file
index 30368d34690e96ba5a88a6dd67f53e17b00f9249..917752fcdf7de80955cf55713aec4ac5c2f8bb24 100644 (file)
@@ -298,12 +298,12 @@ def list_processors(interface=IProcessor, prefix=""):
 
 
 def list_processors_rst(interface=IProcessor, prefix=""):
-    print '\n' + prefix + interface.__name__
+    print '\n' + interface.__name__
     if len(prefix):
         underline_char = '-'
     else:
         underline_char = '='
-    print prefix + underline_char * len(interface.__name__) + '\n'
+    print underline_char * len(interface.__name__) + '\n'
     subinterfaces = interface.__subclasses__()
     for i in subinterfaces:
         list_processors_rst(interface=i, prefix=prefix + " ")
index 19fa7ab37c8a20b1b2d8f8cba02210ace62cc57a..1407eb991a56308202909de6771d805d777c3656 100644 (file)
@@ -29,7 +29,7 @@ from ..exceptions import PIDError
 class DisplayAnalyzer(Grapher):
 
     """
-    Builds a PIL image from analyzer result
+    image from analyzer result
     This is an Abstract base class
     """
     dpi = 72  # Web default value for Telemeta
@@ -121,7 +121,7 @@ class DisplayAnalyzer(Grapher):
             def name():
                 return grapher_name
 
-            __doc__ = """Builds a PIL image representing """ + grapher_name
+            __doc__ = """Image representing """ + grapher_name
 
         NewGrapher.__name__ = 'Display' + '.' + result_id
 
index 244178162b1ccd0b3eb3dd5a660d28e8a08f202a..b367d712e34b214461e95589c746484f570f6197 100644 (file)
@@ -29,7 +29,7 @@ import math
 
 class SpectrogramLog(Grapher):
 
-    """logarithmic scaled spectrogram (level vs. frequency vs. time).
+    """Logarithmic scaled spectrogram (level vs. frequency vs. time).
 
     Adds pixels iteratively thanks to the adapter providing
     fixed size frame buffers."""