From: yomguy Date: Thu, 17 Jun 2010 15:43:56 +0000 (+0000) Subject: push example processors to modules, rm old modules X-Git-Tag: 0.3.2~152 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=52d723735314c46764bc1105bb5700c553e15121;p=timeside.git push example processors to modules, rm old modules --- diff --git a/README b/README index 7f11054..5488b2a 100644 --- a/README +++ b/README @@ -1,13 +1,37 @@ -============== -README (draft) -============== +====== +README +====== -# Dependencies -# ============ +TimeSide is a set of client and server side components for audio-enabling web sites and applications. It includes a powerful DHTML-based interactive player, with support for time-marking. The server side components provide generic APIs for easy transcoding, metadata embedding, sound visualization and audio analysis. -python (>= 2.3.5-7), python-xml, python-mutagen, python-imaging (>= 1.1.6), -python-numpy, python-scipy, python-scikits-audiolab (>= 0.10), -python-setuptools (>= 0.6b3), python-support (>= 0.3), python-ctypes (>= 1.0.1), -libsndfile1 (>= 1.0.17), sox (>= 14.2), vorbis-tools, flac, libgd2-xpm, -lame (>= 3.98.2) +Platforms +========= +TimeSide is intended to work on all Unix / Linux platforms. +MacOS X and Windows versions will soon be explorated. + +Dependencies +============ + +python (>= 2.4), python-xml, python-mutagen, python-imaging (>= 1.1.6), +python-numpy, python-setuptools (>= 0.6b3), libsndfile1 (>= 1.0.17), +python-gst0.10, gstreamer0.10-plugins-base + +License +======= + +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. + + +Contact and Informations +======================== + +See http://code.google.com/p/timeside/ diff --git a/analyzer/__init__.py b/analyzer/__init__.py index f0af279..0bd2039 100644 --- a/analyzer/__init__.py +++ b/analyzer/__init__.py @@ -2,5 +2,5 @@ from timeside.analyzer.core import * from timeside.analyzer.duration import * from timeside.analyzer.max_level import * -from timeside.analyzer.mean_level import * -from timeside.analyzer.dc import * +#from timeside.analyzer.mean_level import * +#from timeside.analyzer.dc import * diff --git a/analyzer/core.py b/analyzer/core.py index 17cbfa1..cbb9a17 100644 --- a/analyzer/core.py +++ b/analyzer/core.py @@ -20,7 +20,6 @@ # Authors: # Guillaume Pellerin -from timeside.core import * -from timeside.grapher.core import * -import numpy +pass + diff --git a/analyzer/duration.py b/analyzer/duration.py index 456a527..7c2269c 100644 --- a/analyzer/duration.py +++ b/analyzer/duration.py @@ -19,18 +19,21 @@ # Author: Guillaume Pellerin +from timeside.core import Processor, implements, interfacedoc, FixedSizeInputAdapter from timeside.analyzer.core import * from timeside.api import IValueAnalyzer -import datetime class Duration(Processor): + """A rather useless duration analyzer. Its only purpose is to test the + nframes characteristic.""" implements(IValueAnalyzer) @interfacedoc - def setup(self, channels=None, samplerate=None, nframes=None): + def setup(self, channels, samplerate, nframes): + if not nframes: + raise Exception("nframes argument required") super(Duration, self).setup(channels, samplerate, nframes) - self.value = 0 @staticmethod @interfacedoc @@ -45,14 +48,8 @@ class Duration(Processor): @staticmethod @interfacedoc def unit(): - return "h:m:s" - - def __str__(self): - return "%s %s" % (str(self.value), unit()) - - def process(self, frames, eod=False): - return frames, eod + return "seconds" def result(self): - return datetime.timedelta(0,numpy.round(self.nframes / float(self.samplerate), 0)) - + return self.input_nframes / float(self.input_samplerate) + \ No newline at end of file diff --git a/analyzer/max_level.py b/analyzer/max_level.py index 93ff3ec..9ecc323 100644 --- a/analyzer/max_level.py +++ b/analyzer/max_level.py @@ -20,9 +20,9 @@ # Author: Guillaume Pellerin +from timeside.core import Processor, implements, interfacedoc, FixedSizeInputAdapter from timeside.analyzer.core import * from timeside.api import IValueAnalyzer -import numpy class MaxLevel(Processor): @@ -31,7 +31,7 @@ class MaxLevel(Processor): @interfacedoc def setup(self, channels=None, samplerate=None, nframes=None): super(MaxLevel, self).setup(channels, samplerate, nframes) - self.value = -140 + self.max_value = 0 @staticmethod @interfacedoc @@ -46,18 +46,17 @@ class MaxLevel(Processor): @staticmethod @interfacedoc def unit(): - return "dB" - - def __str__(self): - return "%s %s" % (str(self.value), unit()) + # power? amplitude? + return "" def process(self, frames, eod=False): - max = numpy.round(20*numpy.log10(frames.max()), 2) - if max > self.value: - self.value = max + max = frames.max() + if max > self.max_value: + self.max_value = max return frames, eod def result(self): - return self.value + return self.max_value + diff --git a/decoder/core.py b/decoder/core.py index 85d818e..08d6e94 100644 --- a/decoder/core.py +++ b/decoder/core.py @@ -23,6 +23,177 @@ from timeside.core import * import subprocess +# -*- coding: utf-8 -*- +# +# Copyright (C) 2007-2009 Parisson +# Copyright (c) 2007 Olivier Guilyardi +# Copyright (c) 2007-2009 Guillaume Pellerin +# +# 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 . + +# Author: Paul Brossier + +from timeside.core import Processor, implements, interfacedoc +from timeside.api import IDecoder +from numpy import array, frombuffer, getbuffer, float32 + +import pygst +pygst.require('0.10') +import gst +import gobject +gobject.threads_init () + + +class FileDecoder(Processor): + """ gstreamer-based decoder """ + implements(IDecoder) + + # duration ms, before discovery process times out + MAX_DISCOVERY_TIME = 3000 + + audioformat = None + audiochannels = None + audiorate = None + audionframes = None + mimetype = '' + + # IProcessor methods + + @staticmethod + @interfacedoc + def id(): + return "gstreamerdec" + + def setup(self, channels = None, samplerate = None, nframes = None): + # the output data format we want + caps = "audio/x-raw-float, width=32" + pipeline = gst.parse_launch('''uridecodebin uri=%s + ! audioconvert + ! %s + ! appsink name=sink sync=False ''' % (self.uri, caps)) + # store a pointer to appsink in our decoder object + self.sink = pipeline.get_by_name('sink') + # adjust length of emitted buffers + # self.sink.set_property('blocksize', 0x10000) + # start pipeline + pipeline.set_state(gst.STATE_PLAYING) + + @interfacedoc + def channels(self): + return self.audiochannels + + @interfacedoc + def samplerate(self): + return self.audiorate + + @interfacedoc + def nframes(self): + return self.audionframes + + @interfacedoc + def process(self, frames = None, eod = False): + try: + buf = self.sink.emit('pull-buffer') + except SystemError, e: + # should never happen + print 'SystemError', e + return array([0.]), True + if buf == None: + return array([0.]), True + return self.gst_buffer_to_numpy_array(buf), False + + @interfacedoc + def release(self): + # nothing to do for now + pass + + ## IDecoder methods + + @interfacedoc + def __init__(self, uri): + + # is this a file? + import os.path + if os.path.exists(uri): + # get the absolute path + uri = os.path.abspath(uri) + # first run the file/uri through the discover pipeline + self.discover(uri) + # and make a uri of it + from urllib import quote + self.uri = 'file://'+quote(uri) + + @interfacedoc + def format(self): + # TODO check + return self.mimetype + + @interfacedoc + def encoding(self): + # TODO check + return self.mimetype.split('/')[-1] + + @interfacedoc + def resolution(self): + # TODO check: width or depth? + return self.audiowidth + + @interfacedoc + def metadata(self): + # TODO check + return self.tags + + ## gst.extend discoverer + + def discover(self, path): + """ gstreamer based helper function to get file attributes """ + from gst.extend import discoverer + d = discoverer.Discoverer(path, timeout = self.MAX_DISCOVERY_TIME) + d.connect('discovered', self.discovered) + self.mainloop = gobject.MainLoop() + d.discover() + self.mainloop.run() + + def discovered(self, d, is_media): + """ gstreamer based helper executed upon discover() completion """ + if is_media and d.is_audio: + # copy the discoverer attributes to self + self.audiorate = d.audiorate + self.mimetype= d.mimetype + self.audiochannels = d.audiochannels + self.audiowidth = d.audiowidth + # conversion from time in nanoseconds to frames + from math import ceil + duration = d.audiorate * d.audiolength * 1.e-9 + self.audionframes = int (ceil ( duration ) ) + self.tags = d.tags + elif not d.is_audio: + print "error, no audio found!" + else: + print "fail", path + self.mainloop.quit() + + def gst_buffer_to_numpy_array(self, buf): + """ gstreamer buffer to numpy array conversion """ + chan = self.audiochannels + samples = frombuffer(buf.data, dtype=float32) + samples.resize([len(samples)/chan, chan]) + return samples + + class SubProcessPipe: def __init__(self, command, stdin=None): @@ -45,7 +216,7 @@ class SubProcessPipe: self.output = self.proc.stdout -class DecoderCore(Processor): +class DecoderSubProcessCore(Processor): """Defines the main parts of the decoding tools : paths, metadata parsing, data streaming thru system command""" diff --git a/encoder/__init__.py b/encoder/__init__.py index 2818f2d..7eadf71 100644 --- a/encoder/__init__.py +++ b/encoder/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from timeside.encoder.core import * -from timeside.encoder.ogg import * +#from timeside.encoder.ogg import * from timeside.encoder.wav import * -from timeside.encoder.mp3 import * -from timeside.encoder.flac import * +#from timeside.encoder.mp3 import * +#from timeside.encoder.flac import * diff --git a/encoder/core.py b/encoder/core.py index 3053165..9786de1 100644 --- a/encoder/core.py +++ b/encoder/core.py @@ -21,7 +21,6 @@ # Author: Guillaume Pellerin from timeside.core import * - import subprocess class SubProcessPipe: @@ -43,7 +42,7 @@ class SubProcessPipe: self.input = self.proc.stdin self.output = self.proc.stdout -class EncoderCore(Processor): +class EncoderSubProcessCore(Processor): """Defines the main parts of the encoding tools : paths, metadata parsing, data streaming thru system command""" diff --git a/encoder/wav.py b/encoder/wav.py index 4a7a90c..d790aaa 100644 --- a/encoder/wav.py +++ b/encoder/wav.py @@ -19,61 +19,106 @@ # Author: Guillaume Pellerin -import os -import string +# -*- coding: utf-8 -*- +# +# Copyright (C) 2007-2009 Parisson +# Copyright (c) 2007 Olivier Guilyardi +# Copyright (c) 2007-2009 Guillaume Pellerin +# +# This file is part of TimeSide. -from timeside.encoder.core import * +# 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 . + +# Author: Paul Brossier + +from timeside.core import Processor, implements, interfacedoc from timeside.api import IEncoder +from numpy import array, frombuffer, getbuffer, float32 + +import pygst +pygst.require('0.10') +import gst +import gobject +gobject.threads_init () -class WavEncoder(EncoderCore): - """Defines methods to encode to WAV""" +class WavEncoder(Processor): + """ gstreamer-based encoder """ implements(IEncoder) - def __init__(self): - pass + def __init__(self, output): + self.file = None + if isinstance(output, basestring): + self.filename = output + else: + raise Exception("Streaming not supported") + + @interfacedoc + def setup(self, channels=None, samplerate=None, nframes=None): + super(WavEncoder, self).setup(channels, samplerate, nframes) + # TODO open file for writing + # the output data format we want + pipeline = gst.parse_launch(''' appsrc name=src + ! audioconvert + ! wavenc + ! filesink location=%s ''' % self.filename) + # store a pointer to appsink in our encoder object + self.src = pipeline.get_by_name('src') + srccaps = gst.Caps("""audio/x-raw-float, + endianness=(int)1234, + channels=(int)%s, + width=(int)32, + rate=(int)%d""" % (int(channels), int(samplerate))) + self.src.set_property("caps", srccaps) + + # start pipeline + pipeline.set_state(gst.STATE_PLAYING) + self.pipeline = pipeline @staticmethod + @interfacedoc def id(): - return "wavenc" - - def format(self): - return 'WAV' - - def file_extension(self): - return 'wav' - - def mime_type(self): - return 'audio/x-wav' - - def description(self): - return """ - WAV (or WAVE), short for Waveform audio format, also known as Audio for - Windows, is a Microsoft and IBM audio file format standard for storing - an audio bitstream on PCs. It is an application of the RIFF bitstream - format method for storing data in “chunks”, and thus is also close to - the 8SVX and the AIFF format used on Amiga and Macintosh computers, - respectively. It is the main format used on Windows systems for raw and - typically uncompressed audio. The usual bitstream encoding is the Pulse - Code Modulation (PCM) format. - """ - - def get_file_info(self): - try: - file1, file2 = os.popen4('wavinfo "'+self.dest+'"') - info = [] - for line in file2.readlines(): - info.append(clean_word(line[:-1])) - self.info = info - return self.info - except: - raise IOError('EncoderError: wavinfo id not installed or file does not exist.') - - def process(self, source, metadata, options=None): - self.metadata = metadata - self.options = options - command = 'sox -t wav - -s -q -b 16 -r 44100 -t wav -c2 -' - - stream = self.core_process(command, source) - for __chunk in stream: - yield __chunk + return "gstreamerenc" + + @staticmethod + @interfacedoc + def description(): + return "Gstreamer based encoder" + + @staticmethod + @interfacedoc + def file_extension(): + return "wav" + + @staticmethod + @interfacedoc + def mime_type(): + return "audio/x-wav" + + @interfacedoc + def set_metadata(self, metadata): + #TODO + pass + + @interfacedoc + def process(self, frames, eod=False): + buf = self.numpy_array_to_gst_buffer(frames) + self.src.emit('push-buffer', buf) + if eod: self.src.emit('end-of-stream') + return frames, eod + + def numpy_array_to_gst_buffer(self, frames): + """ gstreamer buffer to numpy array conversion """ + buf = gst.Buffer(getbuffer(frames)) + return buf diff --git a/grapher/__init__.py b/grapher/__init__.py index 07ed7ba..616ebf6 100644 --- a/grapher/__init__.py +++ b/grapher/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- from timeside.grapher.core import * -from timeside.grapher.waveform_audiolab import * -from timeside.grapher.spectrogram_audiolab import * +from timeside.grapher.waveform import * +from timeside.grapher.spectrogram import * diff --git a/grapher/spectrogram.py b/grapher/spectrogram.py new file mode 100644 index 0000000..0962842 --- /dev/null +++ b/grapher/spectrogram.py @@ -0,0 +1,80 @@ +# -*- 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 Processor, implements, interfacedoc, FixedSizeInputAdapter +from timeside.api import IGrapher +from timeside.grapher import * + + +class Spectrogram(Processor): + implements(IGrapher) + + FFT_SIZE = 0x400 + + @interfacedoc + def __init__(self, width=None, height=None, output=None, bg_color=None, color_scheme=None): + if width: + self.width = width + else: + self.width = 1500 + if height: + self.height = height + else: + self.height = 200 + self.bg_color = bg_color + self.color_scheme = color_scheme + self.filename = output + self.graph = None + + @staticmethod + @interfacedoc + def id(): + return "spectrogram" + + @staticmethod + @interfacedoc + def name(): + return "Spectrogram" + + @interfacedoc + def set_colors(self, background, scheme): + self.bg_color = background + self.color_scheme = scheme + + @interfacedoc + def setup(self, channels=None, samplerate=None, nframes=None): + super(Spectrogram, self).setup(channels, samplerate, nframes) + if self.graph: + self.graph = None + self.graph = SpectrogramImage(self.width, self.height, self.nframes(), self.samplerate(), self.FFT_SIZE, + bg_color=self.bg_color, color_scheme=self.color_scheme, filename=self.filename) + + @interfacedoc + def process(self, frames, eod=False): + self.graph.process(frames, eod) + return frames, eod + + @interfacedoc + def render(self): + if self.filename: + self.graph.save() + return self.graph.image + diff --git a/grapher/waveform.py b/grapher/waveform.py new file mode 100644 index 0000000..982192c --- /dev/null +++ b/grapher/waveform.py @@ -0,0 +1,79 @@ +# -*- 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 Processor, implements, interfacedoc, FixedSizeInputAdapter +from timeside.api import IGrapher +from timeside.grapher import * + + +class Waveform(Processor): + implements(IGrapher) + + FFT_SIZE = 0x400 + + @interfacedoc + def __init__(self, width=None, height=None, output=None, bg_color=None, color_scheme=None): + if width: + self.width = width + else: + self.width = 1500 + if height: + self.height = height + else: + self.height = 200 + self.bg_color = bg_color + self.color_scheme = color_scheme + self.filename = output + self.graph = None + + @staticmethod + @interfacedoc + def id(): + return "waveform" + + @staticmethod + @interfacedoc + def name(): + return "Waveform" + + @interfacedoc + def set_colors(self, background, scheme): + self.bg_color = background + self.color_scheme = scheme + + @interfacedoc + def setup(self, channels=None, samplerate=None, nframes=None): + super(Waveform, self).setup(channels, samplerate, nframes) + if self.graph: + self.graph = None + self.graph = WaveformImage(self.width, self.height, self.nframes(), self.samplerate(), self.FFT_SIZE, + bg_color=self.bg_color, color_scheme=self.color_scheme, filename=self.filename) + + @interfacedoc + def process(self, frames, eod=False): + self.graph.process(frames, eod) + return frames, eod + + @interfacedoc + def render(self): + if self.filename: + self.graph.save() + return self.graph.image diff --git a/tests/api/test_pipe.py b/tests/api/test_pipe.py index 2d07fe4..eaa0850 100644 --- a/tests/api/test_pipe.py +++ b/tests/api/test_pipe.py @@ -1,22 +1,19 @@ # -*- coding: utf-8 -*- -from timeside.tests.api import examples +from timeside.tests.api.examples import Gain from timeside.core import * +from timeside.decoder import * +from timeside.analyzer import * +from timeside.encoder import * from timeside.api import * from sys import stdout -use_gst = 1 -if use_gst: - from timeside.tests.api.gstreamer import FileDecoder, WavEncoder -else: - from timeside.tests.api.examples import FileDecoder, WavEncoder - import os.path source = os.path.join(os.path.dirname(__file__), "../samples/guitar.wav") print "Normalizing %s" % source decoder = FileDecoder(source) -maxlevel = examples.MaxLevel() -duration = examples.Duration() +maxlevel = MaxLevel() +duration = Duration() (decoder | maxlevel | duration).run() @@ -28,11 +25,10 @@ print "input maxlevel: %f" % maxlevel.result() print "gain: %f" % gain print "duration: %f %s" % (duration.result(), duration.unit()) -gain = examples.Gain(gain) +gain = Gain(gain) encoder = WavEncoder("normalized.wav") -fixed = examples.FixedInputProcessor() -subpipe = gain | fixed | maxlevel +subpipe = gain | maxlevel (decoder | subpipe | encoder).run() diff --git a/tests/api/test_pipe_spectrogram.py b/tests/api/test_pipe_spectrogram.py index 7365124..5ba90eb 100644 --- a/tests/api/test_pipe_spectrogram.py +++ b/tests/api/test_pipe_spectrogram.py @@ -1,20 +1,16 @@ # -*- coding: utf-8 -*- -from timeside.tests.api import examples + +import os from timeside.core import * from timeside.api import * -import os.path - -use_gst = 1 -if use_gst: - from timeside.tests.api.gstreamer import FileDecoder, WavEncoder -else: - from timeside.tests.api.examples import FileDecoder, WavEncoder +from timeside.decoder import * +from timeside.grapher import * image_file = '../results/img/spectrogram.png' source = os.path.join(os.path.dirname(__file__), "../samples/sweep.wav") decoder = FileDecoder(source) -spectrogram = examples.Spectrogram(width=1024, height=256, output=image_file, bg_color=(0,0,0), color_scheme='default') +spectrogram = Spectrogram(width=1024, height=256, output=image_file, bg_color=(0,0,0), color_scheme='default') (decoder | spectrogram).run() diff --git a/tests/api/test_pipe_waveform.py b/tests/api/test_pipe_waveform.py index 6de21d7..d21ecdc 100644 --- a/tests/api/test_pipe_waveform.py +++ b/tests/api/test_pipe_waveform.py @@ -1,14 +1,10 @@ # -*- coding: utf-8 -*- -from timeside.tests.api import examples + +import os from timeside.core import * from timeside.api import * -import os - -use_gst = 1 -if use_gst: - from timeside.tests.api.gstreamer import FileDecoder -else: - from timeside.tests.api.examples import FileDecoder +from timeside.decoder import * +from timeside.grapher import * sample_dir = '../samples' img_dir = '../results/img' @@ -26,7 +22,7 @@ for source, image in test_dict.iteritems(): image = img_dir + os.sep + image print 'Test : decoder(%s) | waveform (%s)' % (source, image) decoder = FileDecoder(audio) - waveform = examples.Waveform(width=1024, height=256, output=image, bg_color=(0,0,0), color_scheme='default') + waveform = Waveform(width=1024, height=256, output=image, bg_color=(0,0,0), color_scheme='default') (decoder | waveform).run() print 'frames per pixel = ', waveform.graph.samples_per_pixel print "render waveform to: %s" % image diff --git a/tools/grapher_scheme.py b/tools/grapher_scheme.py index f7c04ef..4549767 100644 --- a/tools/grapher_scheme.py +++ b/tools/grapher_scheme.py @@ -12,7 +12,7 @@ class GrapherScheme: (0, 0, 0), (58/4,68/4,65/4), (80/2,100/2,153/2), (90,180,100), (224,224,44), (255,60,30), (255,255,255) ]} - self.width = 512 + self.width = 2048 self.height = 128 self.bg_color = (255,255,255) self.force = True diff --git a/tools/waveform_batch.py b/tools/waveform_batch.py index c458f07..bba5036 100644 --- a/tools/waveform_batch.py +++ b/tools/waveform_batch.py @@ -20,15 +20,14 @@ # Author: Guillaume Pellerin -version = '0.1.beta' +version = '0.1-beta' import os import sys -from timeside.tests.api import examples from timeside.core import * -from timeside.api import * +from timeside.decoder import * +from timeside.grapher import * from grapher_scheme import * -from timeside.tests.api.gstreamer import FileDecoder class Media2Waveform(object): @@ -72,7 +71,7 @@ class Media2Waveform(object): print 'Rendering ', source, ' to ', image, '...' audio = os.path.join(os.path.dirname(__file__), source) decoder = FileDecoder(audio) - waveform = examples.Waveform(width=self.width, height=self.height, output=image, + waveform = Waveform(width=self.width, height=self.height, output=image, bg_color=self.bg_color, color_scheme=self.color_scheme) (decoder | waveform).run() print 'frames per pixel = ', waveform.graph.samples_per_pixel