self.image = "/tmp/test_waveform_contour_wh_sweep_ogg.png"
self.grapher = WaveformContourWhite(width=1024, height=256, bg_color=(255,255,255), color_scheme='default')
- # SPECTROGRAMS
+ # LOG SPECTROGRAMS
def testWav2Spectrogram(self):
"Test WAV to Spectrogram"
- from timeside.grapher.spectrogram import Spectrogram
+ from timeside.grapher.spectrogram_log import SpectrogramLog
self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.wav")
- self.image = "/tmp/test_spectrogram_sweep_wav.png"
- self.grapher = Spectrogram(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+ self.image = "/tmp/test_spectrogram_log_sweep_wav.png"
+ self.grapher = SpectrogramLog(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
- def testMp32Spectrogram(self):
- "Test MP3 to Spectrogram"
- from timeside.grapher.spectrogram import Spectrogram
+ def testMp32SpectrogramLog(self):
+ "Test MP3 to SpectrogramLog"
+ from timeside.grapher.spectrogram_log import SpectrogramLog
self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.mp3")
- self.image = "/tmp/test_spectrogram_sweep_mp3.png"
- self.grapher = Spectrogram(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+ self.image = "/tmp/test_spectrogram_log_sweep_mp3.png"
+ self.grapher = SpectrogramLog(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
- def testFlac2Spectrogram(self):
- "Test FLAC to Spectrogram"
- from timeside.grapher.spectrogram import Spectrogram
+ def testFlac2SpectrogramLog(self):
+ "Test FLAC to SpectrogramLog"
+ from timeside.grapher.spectrogram_log import SpectrogramLog
self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.flac")
- self.image = "/tmp/test_spectrogram_sweep_flac.png"
- self.grapher = Spectrogram(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+ self.image = "/tmp/test_spectrogram_log_sweep_flac.png"
+ self.grapher = SpectrogramLog(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
- def testOgg2Spectrogram(self):
- "Test OGG to Spectrogram"
- from timeside.grapher.spectrogram import Spectrogram
+ def testOgg2SpectrogramLog(self):
+ "Test OGG to SpectrogramLog"
+ from timeside.grapher.spectrogram_log import SpectrogramLog
self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.ogg")
- self.image = "/tmp/test_spectrogram_sweep_ogg.png"
- self.grapher = Spectrogram(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+ self.image = "/tmp/test_spectrogram_log_sweep_ogg.png"
+ self.grapher = SpectrogramLog(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+
+ # LIN SPECTROGRAMS
+ def testWav2Spectrogram(self):
+ "Test WAV to SpectrogramLinear"
+ from timeside.grapher.spectrogram_lin import SpectrogramLinear
+ self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.wav")
+ self.image = "/tmp/test_spectrogram_lin_sweep_wav.png"
+ self.grapher = SpectrogramLinear(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+
+ def testMp32SpectrogramLinear(self):
+ "Test MP3 to SpectrogramLinear"
+ from timeside.grapher.spectrogram_lin import SpectrogramLinear
+ self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.mp3")
+ self.image = "/tmp/test_spectrogram_lin_sweep_mp3.png"
+ self.grapher = SpectrogramLinear(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+
+ def testFlac2SpectrogramLinear(self):
+ "Test FLAC to SpectrogramLinear"
+ from timeside.grapher.spectrogram_lin import SpectrogramLinear
+ self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.flac")
+ self.image = "/tmp/test_spectrogram_lin_sweep_flac.png"
+ self.grapher = SpectrogramLinear(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
+
+ def testOgg2SpectrogramLinear(self):
+ "Test OGG to SpectrogramLinear"
+ from timeside.grapher.spectrogram_lin import SpectrogramLinear
+ self.source = os.path.join (os.path.dirname(__file__), "samples/sweep.ogg")
+ self.image = "/tmp/test_spectrogram_lin_sweep_ogg.png"
+ self.grapher = SpectrogramLinear(width=1024, height=256, bg_color=(0,0,0), color_scheme='default')
def tearDown(self):
decoder = FileDecoder(self.source)
from waveform_transparent import *
from waveform_contour_black import *
from waveform_contour_white import *
-from spectrogram import *
-from spectrogram_linear import *
+from spectrogram_log import *
+from spectrogram_lin import *
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2007-2010 Guillaume Pellerin <yomguy@parisson.com>
-# Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
-
-# 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/>.
-
-
-from timeside.core import implements, interfacedoc
-from timeside.api import IGrapher
-from timeside.grapher.core import *
-
-
-class Spectrogram(Grapher):
- """ Builds a PIL image representing a spectrogram of the audio stream (level vs. frequency vs. time).
- Adds pixels iteratively thanks to the adapter providing fixed size frame buffers."""
-
- implements(IGrapher)
-
- @interfacedoc
- def __init__(self, width=1024, height=256, bg_color=(0,0,0), color_scheme='default'):
- super(Spectrogram, self).__init__(width, height, bg_color, color_scheme)
- self.colors = default_color_schemes[color_scheme]['spectrogram']
- self.pixels = []
- self.y_to_bin = []
-
- @staticmethod
- @interfacedoc
- def id():
- return "spectrogram"
-
- @staticmethod
- @interfacedoc
- def name():
- return "Spectrogram"
-
- @interfacedoc
- def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None):
- super(Spectrogram, self).setup(channels, samplerate, blocksize, totalframes)
- self.image = Image.new("P", (self.image_height, self.image_width))
- self.image.putpalette(interpolate_colors(self.colors, True))
- self.set_scale()
-
- def set_scale(self):
- """generate the lookup which translates y-coordinate to fft-bin"""
-
- f_min = float(self.lower_freq)
- f_max = float(self.higher_freq)
- y_min = math.log10(f_min)
- y_max = math.log10(f_max)
- for y in range(self.image_height):
- freq = math.pow(10.0, y_min + y / (self.image_height - 1.0) *(y_max - y_min))
- fft_bin = freq / f_max * (self.fft_size/2 + 1)
- if fft_bin < self.fft_size/2:
- alpha = fft_bin - int(fft_bin)
- self.y_to_bin.append((int(fft_bin), alpha * 255))
-
- def draw_spectrum(self, x, spectrum):
- for (index, alpha) in self.y_to_bin:
- self.pixels.append( int( ((255.0-alpha) * spectrum[index] + alpha * spectrum[index + 1] )) )
- for y in range(len(self.y_to_bin), self.image_height):
- self.pixels.append(0)
-
- @interfacedoc
- def process(self, frames, eod=False):
- if len(frames) != 1:
- chunk = frames[:,0].copy()
- chunk.shape = (len(chunk),1)
- for samples, end in self.pixels_adapter.process(chunk, eod):
- if self.pixel_cursor < self.image_width:
- (spectral_centroid, db_spectrum) = self.spectrum.process(samples, True)
- self.draw_spectrum(self.pixel_cursor, db_spectrum)
- self.pixel_cursor += 1
- return frames, eod
-
- def render(self, filename):
- """ Apply last 2D transforms and write all pixels to the file. """
- self.image.putdata(self.pixels)
- self.image.transpose(Image.ROTATE_90).save(filename)
--- /dev/null
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2007-2010 Guillaume Pellerin <yomguy@parisson.com>
+# Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
+
+# 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/>.
+
+
+from timeside.core import implements, interfacedoc
+from timeside.api import IGrapher
+from timeside.grapher.core import *
+from timeside.grapher.spectrogram_log import SpectrogramLog
+
+
+class SpectrogramLinear(SpectrogramLog):
+ """ Builds a PIL image representing a spectrogram of the audio stream (level vs. frequency vs. time).
+ Adds pixels iteratively thanks to the adapter providing fixed size frame buffers."""
+
+ implements(IGrapher)
+
+ @interfacedoc
+ def __init__(self, width=1024, height=256, bg_color=(0,0,0), color_scheme='default'):
+ super(SpectrogramLinear, self).__init__(width, height, bg_color, color_scheme)
+
+ @staticmethod
+ @interfacedoc
+ def id():
+ return "spectrogram_linear"
+
+ @staticmethod
+ @interfacedoc
+ def name():
+ return "Spectrogram linear"
+
+ @interfacedoc
+ def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None):
+ super(SpectrogramLinear, self).setup(channels, samplerate, blocksize, totalframes)
+
+ def set_scale(self):
+ """generate the lookup which translates y-coordinate to fft-bin"""
+
+ f_min = float(self.lower_freq)
+ f_max = float(self.higher_freq)
+ y_min = f_min
+ y_max = f_max
+ for y in range(self.image_height):
+ freq = y_min + y / (self.image_height - 1.0) *(y_max - y_min)
+ fft_bin = freq / f_max * (self.fft_size/2 + 1)
+ if fft_bin < self.fft_size/2:
+ alpha = fft_bin - int(fft_bin)
+ self.y_to_bin.append((int(fft_bin), alpha * 255))
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2007-2010 Guillaume Pellerin <yomguy@parisson.com>
-# Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
-
-# 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/>.
-
-
-from timeside.core import implements, interfacedoc
-from timeside.api import IGrapher
-from timeside.grapher.core import *
-from timeside.grapher.spectrogram import Spectrogram
-
-
-class SpectrogramLinear(Spectrogram):
- """ Builds a PIL image representing a spectrogram of the audio stream (level vs. frequency vs. time).
- Adds pixels iteratively thanks to the adapter providing fixed size frame buffers."""
-
- implements(IGrapher)
-
- @interfacedoc
- def __init__(self, width=1024, height=256, bg_color=(0,0,0), color_scheme='default'):
- super(SpectrogramLinear, self).__init__(width, height, bg_color, color_scheme)
-
- @staticmethod
- @interfacedoc
- def id():
- return "spectrogram_linear"
-
- @staticmethod
- @interfacedoc
- def name():
- return "Spectrogram linear"
-
- @interfacedoc
- def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None):
- super(SpectrogramLinear, self).setup(channels, samplerate, blocksize, totalframes)
-
- def set_scale(self):
- """generate the lookup which translates y-coordinate to fft-bin"""
-
- f_min = float(self.lower_freq)
- f_max = float(self.higher_freq)
- y_min = f_min
- y_max = f_max
- for y in range(self.image_height):
- freq = y_min + y / (self.image_height - 1.0) *(y_max - y_min)
- fft_bin = freq / f_max * (self.fft_size/2 + 1)
- if fft_bin < self.fft_size/2:
- alpha = fft_bin - int(fft_bin)
- self.y_to_bin.append((int(fft_bin), alpha * 255))
--- /dev/null
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2007-2010 Guillaume Pellerin <yomguy@parisson.com>
+# Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
+
+# 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/>.
+
+
+from timeside.core import implements, interfacedoc
+from timeside.api import IGrapher
+from timeside.grapher.core import *
+
+
+class SpectrogramLog(Grapher):
+ """ Builds a PIL image representing a spectrogram of the audio stream (level vs. frequency vs. time).
+ Adds pixels iteratively thanks to the adapter providing fixed size frame buffers."""
+
+ implements(IGrapher)
+
+ @interfacedoc
+ def __init__(self, width=1024, height=256, bg_color=(0,0,0), color_scheme='default'):
+ super(SpectrogramLog, self).__init__(width, height, bg_color, color_scheme)
+ self.colors = default_color_schemes[color_scheme]['spectrogram']
+ self.pixels = []
+ self.y_to_bin = []
+
+ @staticmethod
+ @interfacedoc
+ def id():
+ return "spectrogram"
+
+ @staticmethod
+ @interfacedoc
+ def name():
+ return "SpectrogramLog"
+
+ @interfacedoc
+ def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None):
+ super(SpectrogramLog, self).setup(channels, samplerate, blocksize, totalframes)
+ self.image = Image.new("P", (self.image_height, self.image_width))
+ self.image.putpalette(interpolate_colors(self.colors, True))
+ self.set_scale()
+
+ def set_scale(self):
+ """generate the lookup which translates y-coordinate to fft-bin"""
+
+ f_min = float(self.lower_freq)
+ f_max = float(self.higher_freq)
+ y_min = math.log10(f_min)
+ y_max = math.log10(f_max)
+ for y in range(self.image_height):
+ freq = math.pow(10.0, y_min + y / (self.image_height - 1.0) *(y_max - y_min))
+ fft_bin = freq / f_max * (self.fft_size/2 + 1)
+ if fft_bin < self.fft_size/2:
+ alpha = fft_bin - int(fft_bin)
+ self.y_to_bin.append((int(fft_bin), alpha * 255))
+
+ def draw_spectrum(self, x, spectrum):
+ for (index, alpha) in self.y_to_bin:
+ self.pixels.append( int( ((255.0-alpha) * spectrum[index] + alpha * spectrum[index + 1] )) )
+ for y in range(len(self.y_to_bin), self.image_height):
+ self.pixels.append(0)
+
+ @interfacedoc
+ def process(self, frames, eod=False):
+ if len(frames) != 1:
+ chunk = frames[:,0].copy()
+ chunk.shape = (len(chunk),1)
+ for samples, end in self.pixels_adapter.process(chunk, eod):
+ if self.pixel_cursor < self.image_width:
+ (spectral_centroid, db_spectrum) = self.spectrum.process(samples, True)
+ self.draw_spectrum(self.pixel_cursor, db_spectrum)
+ self.pixel_cursor += 1
+ return frames, eod
+
+ def render(self, filename):
+ """ Apply last 2D transforms and write all pixels to the file. """
+ self.image.putdata(self.pixels)
+ self.image.transpose(Image.ROTATE_90).save(filename)