Package timeside :: Module api
[hide private]
[frames] | no frames]

Source Code for Module timeside.api

  1  # -*- coding: utf-8 -*- 
  2  # 
  3  # Copyright (C) 2007-2013 Parisson SARL 
  4  # Copyright (c) 2007 Olivier Guilyardi <olivier@samalyse.com> 
  5  # Copyright (c) 2007-2009 Guillaume Pellerin <pellerin@parisson.com> 
  6  # 
  7  # This file is part of TimeSide. 
  8   
  9  # TimeSide is free software: you can redistribute it and/or modify 
 10  # it under the terms of the GNU General Public License as published by 
 11  # the Free Software Foundation, either version 2 of the License, or 
 12  # (at your option) any later version. 
 13   
 14  # TimeSide is distributed in the hope that it will be useful, 
 15  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 16  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 17  # GNU General Public License for more details. 
 18   
 19  # You should have received a copy of the GNU General Public License 
 20  # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>. 
 21   
 22   
 23  from timeside.component import Interface 
24 25 26 -class IProcessor(Interface):
27 """Common processor interface""" 28 29 @staticmethod
30 - def id():
31 """Short alphanumeric, lower-case string which uniquely identify this 32 processor, suitable for use as an HTTP/GET argument value, in filenames, 33 etc..."""
34 35 # implementation: only letters and digits are allowed. An exception will 36 # be raised by MetaProcessor if the id is malformed or not unique amongst 37 # registered processors. 38
39 - def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None):
40 """Allocate internal resources and reset state, so that this processor is 41 ready for a new run. 42 43 The channels, samplerate and/or blocksize and/or totalframes arguments 44 may be required by processors which accept input. An error will occur if any of 45 these arguments is passed to an output-only processor such as a decoder. 46 """
47 48 # implementations should always call the parent method 49
50 - def channels(self):
51 """Number of channels in the data returned by process(). May be different from 52 the number of channels passed to setup()"""
53
54 - def samplerate(self):
55 """Samplerate of the data returned by process(). May be different from 56 the samplerate passed to setup()"""
57
58 - def blocksize():
59 """The total number of frames that this processor can output for each step 60 in the pipeline, or None if the number is unknown."""
61
62 - def totalframes():
63 """The total number of frames that this processor will output, or None if 64 the number is unknown."""
65
66 - def process(self, frames=None, eod=False):
67 """Process input frames and return a (output_frames, eod) tuple. 68 Both input and output frames are 2D numpy arrays, where columns are 69 channels, and containing an undetermined number of frames. eod=True 70 means that the end-of-data has been reached. 71 72 Output-only processors (such as decoders) will raise an exception if the 73 frames argument is not None. All processors (even encoders) return data, 74 even if that means returning the input unchanged. 75 76 Warning: it is required to call setup() before this method."""
77
78 - def post_process(self):
79 ''' 80 Post-Process data after processign the input frames with process() 81 82 Processors such as analyzers will produce Results during the Post-Process 83 '''
84
85 - def release(self):
86 """Release resources owned by this processor. The processor cannot 87 be used anymore after calling this method."""
88 89 # implementations should always call the parent method 90
91 - def mediainfo(self):
92 """ 93 Information about the media object 94 uri 95 start 96 duration 97 """
98 99 @staticmethod
100 - def uuid():
101 """Return the UUID of the processor"""
102
103 104 -class IEncoder(IProcessor):
105 """Encoder driver interface. Each encoder is expected to support a specific 106 format.""" 107
108 - def __init__(self, output):
109 """Create a new encoder. output can either be a filename or a python callback 110 function/method for streaming mode. 111 112 The streaming callback prototype is: callback(data, eod) 113 Where data is a block of binary data of an undetermined size, and eod 114 True when end-of-data is reached."""
115 116 # implementation: the constructor must always accept the output argument. It may 117 # accept extra arguments such as bitrate, depth, etc.., but these must be optionnal 118 119 @staticmethod
120 - def format():
121 """Return the encode/encoding format as a short string 122 Example: "MP3", "OGG", "AVI", ... 123 """
124 125 @staticmethod
126 - def description():
127 """Return a string describing what this encode format provides, is good 128 for, etc... The description is meant to help the end user decide what 129 format is good for him/her 130 """
131 132 @staticmethod
133 - def file_extension():
134 """Return the filename extension corresponding to this encode format"""
135 136 @staticmethod
137 - def mime_type():
138 """Return the mime type corresponding to this encode format"""
139
140 - def set_metadata(self, metadata):
141 """Set the metadata to be embedded in the encoded output. 142 143 In non-streaming mode, this method updates the metadata directly into the 144 output file, without re-encoding the audio data, provided this file already 145 exists. 146 147 It isn't required to call this method, but if called, it must be before 148 process()."""
149
150 151 -class IDecoder(IProcessor):
152 """Decoder driver interface. Decoders are different of encoders in that 153 a given driver may support several input formats, hence this interface doesn't 154 export any static method, all informations are dynamic.""" 155
156 - def __init__(self, filename):
157 """Create a new decoder for filename."""
158 # implementation: additional optionnal arguments are allowed 159
160 - def format():
161 """Return a user-friendly file format string"""
162
163 - def encoding():
164 """Return a user-friendly encoding string"""
165
166 - def resolution():
167 """Return the sample width (8, 16, etc..) of original audio file/stream, 168 or None if not applicable/known"""
169
170 - def metadata(self):
171 """Return the metadata embedded into the encoded stream, if any."""
172
173 -class IGrapher(IProcessor):
174 """Media item visualizer driver interface""" 175 176 # implementation: graphers which need to know the total number of frames 177 # should raise an exception in setup() if the totalframes argument is None 178
179 - def __init__(self, width, height):
180 """Create a new grapher. width and height are generally 181 in pixels but could be something else for eg. svg rendering, etc.. """
182 183 # implementation: additional optionnal arguments are allowed 184 185 @staticmethod
186 - def name():
187 """Return the graph name, such as "Waveform", "Spectral view", 188 etc.. """
189
190 - def set_colors(self, background=None, scheme=None):
191 """Set the colors used for image generation. background is a RGB tuple, 192 and scheme a a predefined color theme name"""
193
194 - def render(self, output=None):
195 """Return a PIL Image object visually representing all of the data passed 196 by repeatedly calling process() and write the image to the output if specified"""
197
198 199 -class IAnalyzer(IProcessor):
200 """Media item analyzer driver interface. This interface is abstract, it doesn't 201 describe a particular type of analyzer but is rather meant to group analyzers. 202 In particular, the way the result is returned may greatly vary from sub-interface 203 to sub-interface. For example the IValueAnalyzer returns a final single numeric 204 result at the end of the whole analysis. But some other analyzers may return 205 numpy arrays, and this, either at the end of the analysis, or from process() 206 for each block of data (as in Vamp).""" 207
208 - def __init__(self):
209 """Create a new analyzer."""
210 # implementation: additional optionnal arguments are allowed 211 212 @staticmethod
213 - def name():
214 """Return the analyzer name, such as "Mean Level", "Max level", 215 "Total length, etc.. """
216 217 @staticmethod
218 - def unit():
219 """Return the unit of the data such as "dB", "seconds", etc... """
220
221 222 -class IValueAnalyzer(IAnalyzer):
223 """Interface for analyzers which return a single numeric value from result()""" 224
225 - def result():
226 """Return the final result of the analysis performed over the data passed by 227 repeatedly calling process()"""
228
229 - def results():
230 """Return the final results of the analysis performed over the data passed by 231 repeatedly calling process()"""
232
233 - def __str__(self):
234 """Return a human readable string containing both result and unit 235 ('5.30dB', '4.2s', etc...)"""
236
237 238 -class IEffect(IProcessor):
239 """Effect processor interface""" 240
241 - def __init__(self):
242 """Create a new effect."""
243 # implementation: additional optionnal arguments are allowed 244 245 @staticmethod
246 - def name():
247 """Return the effect name"""
248