From: Guillaume Pellerin Date: Mon, 28 Oct 2013 22:33:23 +0000 (+0100) Subject: cleanup, add a SpectrogramLinear grapher X-Git-Tag: 0.5.1-0~16 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=b7ab76cf253fc3c6739b06af02887b877768d3bd;p=timeside.git cleanup, add a SpectrogramLinear grapher --- diff --git a/timeside/analyzer/aubio_melenergy.py b/timeside/analyzer/aubio_melenergy.py index d1ac026..b353079 100644 --- a/timeside/analyzer/aubio_melenergy.py +++ b/timeside/analyzer/aubio_melenergy.py @@ -73,13 +73,8 @@ class AubioMelEnergy(Analyzer): return frames, eod def post_process(self): - melenergy = self.new_result(data_mode='value', time_mode='framewise') - - # Metadata melenergy.parameters = dict(n_filters=self.n_filters, n_coeffs=self.n_coeffs) - # Set Data melenergy.data_object.value = self.melenergy_results - self._results.add(melenergy) diff --git a/timeside/analyzer/aubio_mfcc.py b/timeside/analyzer/aubio_mfcc.py index c29c20c..3697b81 100644 --- a/timeside/analyzer/aubio_mfcc.py +++ b/timeside/analyzer/aubio_mfcc.py @@ -74,11 +74,8 @@ class AubioMfcc(Analyzer): return frames, eod def post_process(self): - # MFCC 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._results.add(mfcc) diff --git a/timeside/analyzer/aubio_pitch.py b/timeside/analyzer/aubio_pitch.py index 76bdb28..899d64d 100644 --- a/timeside/analyzer/aubio_pitch.py +++ b/timeside/analyzer/aubio_pitch.py @@ -72,13 +72,10 @@ class AubioPitch(Analyzer): return frames, eod def post_process(self): - # set Result pitch = self.new_result(data_mode='value', time_mode='framewise') # parameters : None # TODO check with Piem "default" and "freq" in # setup - # Set Data pitch.data_object.value = self.pitches - self._results.add(pitch) diff --git a/timeside/analyzer/aubio_specdesc.py b/timeside/analyzer/aubio_specdesc.py index 175cf08..b23d58b 100644 --- a/timeside/analyzer/aubio_specdesc.py +++ b/timeside/analyzer/aubio_specdesc.py @@ -88,7 +88,6 @@ class AubioSpecdesc(Analyzer): # Set metadata res_specdesc.id_metadata.id += '.' + method res_specdesc.id_metadata.name = ' ' + method - res_specdesc.data_object.value = self.specdesc_results[method] self._results.add(res_specdesc) diff --git a/timeside/analyzer/aubio_temporal.py b/timeside/analyzer/aubio_temporal.py index 8c9d03a..e6c0a9c 100644 --- a/timeside/analyzer/aubio_temporal.py +++ b/timeside/analyzer/aubio_temporal.py @@ -94,7 +94,6 @@ class AubioTemporal(Analyzer): onsets.data_object.label = numpy.ones(len(self.onsets)) onsets.data_object.time = self.onsets - onsets.label_metadata.label = {1: 'Onset'} self._results.add(onsets) diff --git a/timeside/analyzer/dc.py b/timeside/analyzer/dc.py index 88b5911..8ce3290 100644 --- a/timeside/analyzer/dc.py +++ b/timeside/analyzer/dc.py @@ -59,8 +59,6 @@ class MeanDCShift(Analyzer): def post_process(self): dc_result = self.new_result(data_mode='value', time_mode='global') - - # Set Data dc_result.data_object.value = numpy.round( numpy.mean(100 * self.values), 3) self._results.add(dc_result) diff --git a/timeside/analyzer/spectrogram.py b/timeside/analyzer/spectrogram.py index 17b6d78..0597e31 100644 --- a/timeside/analyzer/spectrogram.py +++ b/timeside/analyzer/spectrogram.py @@ -61,17 +61,10 @@ class Spectrogram(Analyzer): for samples in downsample_blocking(frames, self.input_stepsize): #time = self.block_read * self.input_stepsize * 1. / self.samplerate() self.values.append(np.abs(np.fft.rfft(samples, self.FFT_SIZE))) - return frames, eod def post_process(self): - # set Result spectrogram = self.new_result(data_mode='value', time_mode='framewise') - - # parameters : spectrogram.parameters = {'FFT_SIZE': self.FFT_SIZE} - - # Set Data spectrogram.data_object.value = self.values - self._results.add(spectrogram) diff --git a/timeside/analyzer/waveform.py b/timeside/analyzer/waveform.py index 8d5b0c9..ace57c8 100644 --- a/timeside/analyzer/waveform.py +++ b/timeside/analyzer/waveform.py @@ -60,14 +60,9 @@ class Waveform(Analyzer): def process(self, frames, eod=False): for samples in downsample_blocking(frames, self.input_blocksize): self.values.append(samples) - return frames, eod def post_process(self): - # set Result waveform = self.new_result(data_mode='value', time_mode='framewise') - - # Set Data waveform.data_object.value = np.asarray(self.values).flatten() - self._results.add(waveform) diff --git a/timeside/grapher/__init__.py b/timeside/grapher/__init__.py index 1c21ffc..d49a41e 100644 --- a/timeside/grapher/__init__.py +++ b/timeside/grapher/__init__.py @@ -6,3 +6,4 @@ from waveform_transparent import * from waveform_contour_black import * from waveform_contour_white import * from spectrogram import * +from spectrogram_linear import * diff --git a/timeside/grapher/spectrogram.py b/timeside/grapher/spectrogram.py index ade5f65..7d7f691 100644 --- a/timeside/grapher/spectrogram.py +++ b/timeside/grapher/spectrogram.py @@ -35,19 +35,7 @@ class Spectrogram(Grapher): super(Spectrogram, self).__init__(width, height, bg_color, color_scheme) self.colors = default_color_schemes[color_scheme]['spectrogram'] self.pixels = [] - - # generate the lookup which translates y-coordinate to fft-bin self.y_to_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 / 22050.0 * (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)) @staticmethod @interfacedoc @@ -64,6 +52,21 @@ class Spectrogram(Grapher): 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: diff --git a/timeside/grapher/spectrogram_linear.py b/timeside/grapher/spectrogram_linear.py new file mode 100644 index 0000000..3ccdbc2 --- /dev/null +++ b/timeside/grapher/spectrogram_linear.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2007-2010 Guillaume Pellerin +# Copyright (c) 2010 Olivier Guilyardi + +# 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 . + + +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)) diff --git a/timeside/grapher/utils.py b/timeside/grapher/utils.py index 178e76d..b262650 100644 --- a/timeside/grapher/utils.py +++ b/timeside/grapher/utils.py @@ -104,7 +104,6 @@ def smooth(x, window_len=10, window='hanning'): numpy.hanning, numpy.hamming, numpy.bartlett, numpy.blackman, numpy.convolve scipy.signal.lfilter - Examples -------- @@ -125,20 +124,16 @@ def smooth(x, window_len=10, window='hanning'): # TODO: the window parameter could be the window itself if an array instead of a string - if x.ndim != 1: raise ValueError, "smooth only accepts 1 dimension arrays." - if x.size < window_len: raise ValueError, "Input vector needs to be bigger than window size." - if window_len < 3: return x - if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']: raise ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'" - s=numpy.r_[2*x[0]-x[window_len:1:-1], x, 2*x[-1]-x[-1:-window_len:-1]] + s = numpy.r_[2*x[0]-x[window_len:1:-1], x, 2*x[-1]-x[-1:-window_len:-1]] if window == 'flat': #moving average w = numpy.ones(window_len,'d') @@ -163,9 +158,7 @@ def reduce_opacity(im, opacity): def im_watermark(im, inputtext, font=None, color=None, opacity=.6, margin=(30,30)): - """ - imprints a PIL image with the indicated text in lower-right corner - """ + """imprints a PIL image with the indicated text in lower-right corner""" if im.mode != "RGBA": im = im.convert("RGBA") textlayer = Image.new("RGBA", im.size, (0,0,0,0)) @@ -206,5 +199,3 @@ def mean(samples): def normalize(contour): contour = contour-min(contour) return contour/max(contour) - -