From 4b179bca641661cfd34336bd63faf6e72e38adc0 Mon Sep 17 00:00:00 2001 From: Olivier Guilyardi Date: Fri, 27 Nov 2009 18:27:23 +0000 Subject: [PATCH] - merge all api's into timeside.api - add core.get_processor() - put all exceptions into exceptions.py - use SubProcessError instead of EncodeProcesError, DecodeProcessError and VampProcessError - rename TimeSideError to Error (= timeside.Error) --- analyze/__init__.py | 1 - analyze/api.py | 40 ----------- analyze/channels.py | 2 +- analyze/dc.py | 2 +- analyze/duration.py | 2 +- analyze/encoding.py | 2 +- analyze/format.py | 2 +- analyze/max_level.py | 2 +- analyze/mean_level.py | 2 +- analyze/resolution.py | 2 +- analyze/samplerate.py | 2 +- analyze/vamp/core.py | 22 ++---- api.py | 130 +++++++++++++++++++++++++++++++++- core.py | 22 +++--- decode/__init__.py | 3 +- decode/api.py | 76 -------------------- decode/flac.py | 2 +- decode/mp3.py | 2 +- decode/ogg.py | 2 +- decode/wav.py | 2 +- encode/__init__.py | 3 +- encode/api.py | 94 ------------------------ encode/flac.py | 2 +- encode/mp3.py | 2 +- encode/ogg.py | 2 +- encode/wav.py | 2 +- exceptions.py | 41 +++++++++++ graph/__init__.py | 1 - graph/api.py | 40 ----------- graph/spectrogram_audiolab.py | 2 +- graph/waveform_audiolab.py | 2 +- tests/test.py | 16 ++--- 32 files changed, 217 insertions(+), 310 deletions(-) delete mode 100644 analyze/api.py delete mode 100644 decode/api.py delete mode 100644 encode/api.py create mode 100644 exceptions.py delete mode 100644 graph/api.py diff --git a/analyze/__init__.py b/analyze/__init__.py index 97c5cad..307016e 100644 --- a/analyze/__init__.py +++ b/analyze/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from timeside.analyze.api import * from timeside.analyze.core import * from timeside.analyze.channels import * from timeside.analyze.format import * diff --git a/analyze/api.py b/analyze/api.py deleted file mode 100644 index 187dc29..0000000 --- a/analyze/api.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# -# 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: Guillaume Pellerin - -from timeside.api import IProcessor - -class IAnalyzer(IProcessor): - """Media item analyzer driver interface""" - - @staticmethod - def name(): - """Return the analyzer name, such as "Mean Level", "Max level", - "Total length, etc.. - """ - - @staticmethod - def unit(): - """Return the unit of the data such as "dB", "seconds", etc... - """ - - def render(self, media, options=None): - """Return the result data of the process""" - diff --git a/analyze/channels.py b/analyze/channels.py index e09c6ab..6ad202d 100644 --- a/analyze/channels.py +++ b/analyze/channels.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class ChannelAnalyser(AudioProcessor): diff --git a/analyze/dc.py b/analyze/dc.py index 28d0a68..43cfdb5 100644 --- a/analyze/dc.py +++ b/analyze/dc.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class MeanDCShiftAnalyser(AudioProcessor): diff --git a/analyze/duration.py b/analyze/duration.py index 4ea9401..64546d0 100644 --- a/analyze/duration.py +++ b/analyze/duration.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy import datetime diff --git a/analyze/encoding.py b/analyze/encoding.py index 3ca3b92..0448f47 100644 --- a/analyze/encoding.py +++ b/analyze/encoding.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class EncodingAnalyser(AudioProcessor): diff --git a/analyze/format.py b/analyze/format.py index 681afc3..2c7fdf3 100644 --- a/analyze/format.py +++ b/analyze/format.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class FormatAnalyser(AudioProcessor): diff --git a/analyze/max_level.py b/analyze/max_level.py index 95c2303..fa173fb 100644 --- a/analyze/max_level.py +++ b/analyze/max_level.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class MaxLevelAnalyzer(AudioProcessor): diff --git a/analyze/mean_level.py b/analyze/mean_level.py index ae9424d..7f18f37 100644 --- a/analyze/mean_level.py +++ b/analyze/mean_level.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class MeanLevelAnalyser(AudioProcessor): diff --git a/analyze/resolution.py b/analyze/resolution.py index b138205..6040fec 100644 --- a/analyze/resolution.py +++ b/analyze/resolution.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class ResolutionAnalyser(AudioProcessor): diff --git a/analyze/samplerate.py b/analyze/samplerate.py index 8093537..d235ebd 100644 --- a/analyze/samplerate.py +++ b/analyze/samplerate.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.analyze.core import * -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer import numpy class SampleRateAnalyzer(AudioProcessor): diff --git a/analyze/vamp/core.py b/analyze/vamp/core.py index 4c89c97..fb0a3f4 100644 --- a/analyze/vamp/core.py +++ b/analyze/vamp/core.py @@ -21,7 +21,8 @@ from timeside.core import * from tempfile import NamedTemporaryFile -from timeside.analyze.api import IAnalyzer +from timeside.api import IAnalyzer +from timeside.exceptions import SubProcessError import os import random import subprocess @@ -99,31 +100,16 @@ class VampCoreAnalyzer: stdout = subprocess.PIPE, close_fds = True) except: - raise VampProcessError('Command failure:', command, proc) + raise SubProcessError('Command failure:', command, proc) # Core processing while True: __chunk = proc.stdout.read(buffer_size) status = proc.poll() if status != None and status != 0: - raise VampProcessError('Command failure:', command, proc) + raise SubProcessError('Command failure:', command, proc) if len(__chunk) == 0: break yield __chunk -class VampProcessError(TimeSideError): - - def __init__(self, message, command, subprocess): - self.message = message - self.command = str(command) - self.subprocess = subprocess - - def __str__(self): - if self.subprocess.stderr != None: - error = self.subprocess.stderr.read() - else: - error = '' - return "%s ; command: %s; error: %s" % (self.message, - self.command, - error) diff --git a/api.py b/api.py index 48a7cf5..344871e 100644 --- a/api.py +++ b/api.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # -# Copyright (c) 2009 Olivier Guilyardi +# Copyright (C) 2007-2009 Parisson +# Copyright (c) 2007 Olivier Guilyardi +# Copyright (c) 2007-2009 Guillaume Pellerin # # This file is part of TimeSide. @@ -20,6 +22,7 @@ from timeside.component import Interface class IProcessor(Interface): + """Base processor interface""" @staticmethod def id(): @@ -31,3 +34,128 @@ class IProcessor(Interface): Typically this identifier is likely to be used during HTTP requests and be passed as a GET parameter. Thus it should be as short as possible.""" +class IEncoder(IProcessor): + """Encoder driver interface""" + + def __init__(self, output, nchannels, samplerate): + """The constructor must always accept the output, nchannels and samplerate + arguments. It may accepts extra arguments such as bitrate, depth, etc.., + but these must be optionnal, that is have a default value. + + The output must either be a filepath or a callback function/method for + for the streaming mode. The callback must accept one argument which is + block of binary data. + """ + + @staticmethod + def format(): + """Return the encode/encoding format as a short string + Example: "MP3", "OGG", "AVI", ... + """ + + @staticmethod + def description(): + """Return a string describing what this encode format provides, is good + for, etc... The description is meant to help the end user decide what + format is good for him/her + """ + + @staticmethod + def file_extension(): + """Return the filename extension corresponding to this encode format""" + + @staticmethod + def mime_type(): + """Return the mime type corresponding to this encode format""" + + def set_metadata(self, metadata): + """metadata is a tuple containing tuples for each descriptor return by + the dc.Ressource of the item, in the model order : + ((name1, value1),(name2, value2),(name1, value3), ...)""" + + def update(self): + """Updates the metadata into the file passed as the output argument + to the constructor. This method can't be called in streaming + mode.""" + + def process(self, frames): + """Encode the frames passed as a numpy array, where columns are channels. + + In streaming mode the callback passed to the constructor is called whenever + a block of encoded data is ready.""" + + def finish(self): + """Flush the encoded data and close the output file/stream. Calling this method + may cause the streaming callback to be called if in streaming mode.""" + + +class IDecoder(IProcessor): + """Decoder driver interface""" + + @staticmethod + def format(): + """Return the decode/encoding format as a short string + Example: "MP3", "OGG", "AVI", ... + """ + + @staticmethod + def description(): + """Return a string describing what this decode format provides, is good + for, etc... The description is meant to help the end user decide what + format is good for him/her + """ + + @staticmethod + def file_extension(): + """Return the filename extension corresponding to this decode format""" + + @staticmethod + def mime_type(): + """Return the mime type corresponding to this decode format""" + + def process(self, source, options=None): + """Perform the decoding process and stream the result through a generator + + source is the audio/video source file absolute path. + + It is highly recommended that decode drivers implement some sort of + cache instead of re-encoding each time process() is called. + + It should be possible to make subsequent calls to process() with + different items, using the same driver instance. + """ + +class IGrapher(IProcessor): + """Media item visualizer driver interface""" + + @staticmethod + def name(): + """Return the graph name, such as "Waveform", "Spectral view", + etc.. + """ + + def set_colors(self, background=None, scheme=None): + """Set the colors used for image generation. background is a RGB tuple, + and scheme a a predefined color theme name""" + pass + + def render(self, media_item, width=None, height=None, options=None): + """Generator that streams the graph output as a PNG image""" + +class IAnalyzer(IProcessor): + """Media item analyzer driver interface""" + + @staticmethod + def name(): + """Return the analyzer name, such as "Mean Level", "Max level", + "Total length, etc.. + """ + + @staticmethod + def unit(): + """Return the unit of the data such as "dB", "seconds", etc... + """ + + def render(self, media, options=None): + """Return the result data of the process""" + diff --git a/core.py b/core.py index c797db4..f2c87b7 100644 --- a/core.py +++ b/core.py @@ -19,13 +19,11 @@ from timeside.component import * from timeside.api import IProcessor +from timeside.exceptions import Error, ApiError import re -__all__ = ['Processor', 'Component', 'implements', 'processors', 'TimeSideError'] - -class TimeSideError(Exception): - """Exception base class for errors in TimeSide.""" - # FIXME: is this redundant with Django's error handling ? +__all__ = ['Processor', 'MetaProcessor', 'implements', 'processors', + 'get_processor'] _processors = {} @@ -40,12 +38,11 @@ class MetaProcessor(MetaComponent): if new_class in implementations(IProcessor): id = str(new_class.id()) if _processors.has_key(id): - raise TimeSideError("%s and %s have the same id: '%s'" + raise ApiError("%s and %s have the same id: '%s'" % (new_class.__name__, _processors[id].__name__, id)) if not MetaProcessor.valid_id.match(id): - raise TimeSideError("%s has a malformed id: '%s'" + raise ApiError("%s has a malformed id: '%s'" % (new_class.__name__, id)) - _processors[id] = new_class @@ -60,3 +57,12 @@ def processors(interface=IProcessor, recurse=True): any of the descendants of this interface.""" return implementations(interface, recurse) + +def get_processor(processor_id): + """Return a processor by its id""" + if not _processors.has_key(processor_id): + raise Error("No processor registered with id: '%s'" + % processor_id) + + return _processors[processor_id] + diff --git a/decode/__init__.py b/decode/__init__.py index 5af60e5..d04cfce 100644 --- a/decode/__init__.py +++ b/decode/__init__.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- -from timeside.decode.api import * from timeside.decode.core import * from timeside.decode.ogg import * from timeside.decode.flac import * from timeside.decode.wav import * -from timeside.decode.mp3 import * \ No newline at end of file +from timeside.decode.mp3 import * diff --git a/decode/api.py b/decode/api.py deleted file mode 100644 index e3e6744..0000000 --- a/decode/api.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- 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 . - -from timeside.api import IProcessor -from timeside.core import TimeSideError - -class IDecoder(IProcessor): - """Decoder driver interface""" - - @staticmethod - def format(): - """Return the decode/encoding format as a short string - Example: "MP3", "OGG", "AVI", ... - """ - - @staticmethod - def description(): - """Return a string describing what this decode format provides, is good - for, etc... The description is meant to help the end user decide what - format is good for him/her - """ - - @staticmethod - def file_extension(): - """Return the filename extension corresponding to this decode format""" - - @staticmethod - def mime_type(): - """Return the mime type corresponding to this decode format""" - - def process(self, source, options=None): - """Perform the decoding process and stream the result through a generator - - source is the audio/video source file absolute path. - - It is highly recommended that decode drivers implement some sort of - cache instead of re-encoding each time process() is called. - - It should be possible to make subsequent calls to process() with - different items, using the same driver instance. - """ - - -class DecodeProcessError(TimeSideError): - - def __init__(self, message, command, subprocess): - self.message = message - self.command = str(command) - self.subprocess = subprocess - - def __str__(self): - if self.subprocess.stderr != None: - error = self.subprocess.stderr.read() - else: - error = '' - return "%s ; command: %s; error: %s" % (self.message, - self.command, - error) diff --git a/decode/flac.py b/decode/flac.py index b9b02c2..5289713 100644 --- a/decode/flac.py +++ b/decode/flac.py @@ -24,7 +24,7 @@ import string import subprocess from timeside.decode.core import * -from timeside.decode.api import IDecoder +from timeside.api import IDecoder from mutagen.flac import FLAC from tempfile import NamedTemporaryFile diff --git a/decode/mp3.py b/decode/mp3.py index dc2c968..f4f1973 100644 --- a/decode/mp3.py +++ b/decode/mp3.py @@ -25,7 +25,7 @@ import string import subprocess from timeside.decode.core import * -from timeside.decode.api import IDecoder +from timeside.api import IDecoder class Mp3Decoder(DecoderCore): diff --git a/decode/ogg.py b/decode/ogg.py index 3e22af0..ffd6903 100644 --- a/decode/ogg.py +++ b/decode/ogg.py @@ -24,7 +24,7 @@ import string import subprocess from timeside.decode.core import * -from timeside.decode.api import IDecoder +from timeside.api import IDecoder from mutagen.oggvorbis import OggVorbis class OggDecoder(DecoderCore): diff --git a/decode/wav.py b/decode/wav.py index be23402..08bca88 100644 --- a/decode/wav.py +++ b/decode/wav.py @@ -24,7 +24,7 @@ import string import subprocess from timeside.decode.core import * -from timeside.decode.api import IDecoder +from timeside.api import IDecoder class WavDecoder(DecoderCore): """Defines methods to decode from WAV""" diff --git a/encode/__init__.py b/encode/__init__.py index c4f0419..a3dd62f 100644 --- a/encode/__init__.py +++ b/encode/__init__.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- -from timeside.encode.api import * from timeside.encode.core import * from timeside.encode.ogg import * from timeside.encode.wav import * from timeside.encode.mp3 import * -from timeside.encode.flac import * \ No newline at end of file +from timeside.encode.flac import * diff --git a/encode/api.py b/encode/api.py deleted file mode 100644 index 9314c82..0000000 --- a/encode/api.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- 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 . - -from timeside.core import TimeSideError -from timeside.api import IProcessor - -class IEncoder(IProcessor): - """Encoder driver interface""" - - def __init__(self, output, nchannels, samplerate): - """The constructor must always accept the output, nchannels and samplerate - arguments. It may accepts extra arguments such as bitrate, depth, etc.., - but these must be optionnal, that is have a default value. - - The output must either be a filepath or a callback function/method for - for the streaming mode. The callback must accept one argument which is - block of binary data. - """ - - @staticmethod - def format(): - """Return the encode/encoding format as a short string - Example: "MP3", "OGG", "AVI", ... - """ - - @staticmethod - def description(): - """Return a string describing what this encode format provides, is good - for, etc... The description is meant to help the end user decide what - format is good for him/her - """ - - @staticmethod - def file_extension(): - """Return the filename extension corresponding to this encode format""" - - @staticmethod - def mime_type(): - """Return the mime type corresponding to this encode format""" - - def set_metadata(self, metadata): - """metadata is a tuple containing tuples for each descriptor return by - the dc.Ressource of the item, in the model order : - ((name1, value1),(name2, value2),(name1, value3), ...)""" - - def update(self): - """Updates the metadata into the file passed as the output argument - to the constructor. This method can't be called in streaming - mode.""" - - def process(self, frames): - """Encode the frames passed as a numpy array, where columns are channels. - - In streaming mode the callback passed to the constructor is called whenever - a block of encoded data is ready.""" - - def finish(self): - """Flush the encoded data and close the output file/stream. Calling this method - may cause the streaming callback to be called if in streaming mode.""" - -class EncodeProcessError(TimeSideError): - - def __init__(self, message, command, subprocess): - self.message = message - self.command = str(command) - self.subprocess = subprocess - - def __str__(self): - if self.subprocess.stderr != None: - error = self.subprocess.stderr.read() - else: - error = '' - return "%s ; command: %s; error: %s" % (self.message, - self.command, - error) - diff --git a/encode/flac.py b/encode/flac.py index 3f43dbe..c03eb93 100644 --- a/encode/flac.py +++ b/encode/flac.py @@ -24,7 +24,7 @@ import string import subprocess from timeside.encode.core import * -from timeside.encode.api import IEncoder +from timeside.api import IEncoder from tempfile import NamedTemporaryFile class FlacEncoder(EncoderCore): diff --git a/encode/mp3.py b/encode/mp3.py index 51fdf87..a29d369 100644 --- a/encode/mp3.py +++ b/encode/mp3.py @@ -25,7 +25,7 @@ import string import subprocess from timeside.encode.core import * -from timeside.encode.api import IEncoder +from timeside.api import IEncoder class Mp3Encoder(EncoderCore): diff --git a/encode/ogg.py b/encode/ogg.py index ef19863..c0855f9 100644 --- a/encode/ogg.py +++ b/encode/ogg.py @@ -24,7 +24,7 @@ import string import subprocess from timeside.encode.core import * -from timeside.encode.api import IEncoder +from timeside.api import IEncoder class OggVorbisEncoder(EncoderCore): """Defines methods to encode to OGG Vorbis""" diff --git a/encode/wav.py b/encode/wav.py index 54b8199..1903050 100644 --- a/encode/wav.py +++ b/encode/wav.py @@ -23,7 +23,7 @@ import os import string from timeside.encode.core import * -from timeside.encode.api import IEncoder +from timeside.api import IEncoder class WavEncoder(EncoderCore): """Defines methods to encode to WAV""" diff --git a/exceptions.py b/exceptions.py new file mode 100644 index 0000000..40b4dcd --- /dev/null +++ b/exceptions.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2009 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 . + +class Error(Exception): + """Exception base class for errors in TimeSide.""" + +class ApiError(Exception): + """Exception base class for errors in TimeSide.""" + +class SubProcessError(Error): + """Exception for reporting errors from a subprocess""" + + def __init__(self, message, command, subprocess): + self.message = message + self.command = str(command) + self.subprocess = subprocess + + def __str__(self): + if self.subprocess.stderr != None: + error = self.subprocess.stderr.read() + else: + error = '' + return "%s ; command: %s; error: %s" % (self.message, + self.command, + error) diff --git a/graph/__init__.py b/graph/__init__.py index 5d006e6..ae5da9d 100644 --- a/graph/__init__.py +++ b/graph/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from timeside.graph.api import * from timeside.graph.waveform_audiolab import * from timeside.graph.spectrogram_audiolab import * diff --git a/graph/api.py b/graph/api.py deleted file mode 100644 index fa1e941..0000000 --- a/graph/api.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2007 Samalyse SARL# -# 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: Guillaume Pellerin -# Author: Olivier Guilyardi - -from timeside.api import IProcessor - -class IGrapher(IProcessor): - """Media item visualizer driver interface""" - - @staticmethod - def name(): - """Return the graph name, such as "Waveform", "Spectral view", - etc.. - """ - - def set_colors(self, background=None, scheme=None): - """Set the colors used for image generation. background is a RGB tuple, - and scheme a a predefined color theme name""" - pass - - def render(self, media_item, width=None, height=None, options=None): - """Generator that streams the graph output as a PNG image""" diff --git a/graph/spectrogram_audiolab.py b/graph/spectrogram_audiolab.py index b731fa6..709d8d3 100644 --- a/graph/spectrogram_audiolab.py +++ b/graph/spectrogram_audiolab.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.core import * -from timeside.graph.api import IGrapher +from timeside.api import IGrapher from tempfile import NamedTemporaryFile from timeside.graph.wav2png import * diff --git a/graph/waveform_audiolab.py b/graph/waveform_audiolab.py index 62de030..b11888c 100644 --- a/graph/waveform_audiolab.py +++ b/graph/waveform_audiolab.py @@ -20,7 +20,7 @@ # Author: Guillaume Pellerin from timeside.core import * -from timeside.graph.api import IGrapher +from timeside.api import IGrapher from tempfile import NamedTemporaryFile from timeside.graph.wav2png import * diff --git a/tests/test.py b/tests/test.py index 38cd4c9..c54b449 100755 --- a/tests/test.py +++ b/tests/test.py @@ -7,8 +7,8 @@ import magic from timeside.core import * -class TestAnalyzers(Component): - analyzers = processors(timeside.analyze.IAnalyzer) +class TestAnalyzers: + analyzers = processors(timeside.api.IAnalyzer) def list(self): analyzers = [] @@ -34,8 +34,8 @@ class TestAnalyzers(Component): print id + ' = ' + str(value) + ' ' + analyzer.unit() -class TestDecoders(Component): - decoders = processors(timeside.decode.IDecoder) +class TestDecoders: + decoders = processors(timeside.api.IDecoder) def list(self): decoders_list = [] @@ -71,8 +71,8 @@ class TestDecoders(Component): f.flush() f.close() -class TestEncoders(Component): - encoders = processors(timeside.encode.IEncoder) +class TestEncoders: + encoders = processors(timeside.api.IEncoder) def list(self): encoders = [] @@ -108,8 +108,8 @@ class TestEncoders(Component): file.close() -class TestGraphers(Component): - graphers = processors(timeside.graph.IGrapher) +class TestGraphers: + graphers = processors(timeside.api.IGrapher) def list(self): graphers = [] -- 2.39.5