class DeezerComplete(Provider): """Deezer Plugin representing complete tracks on Deezer's infrastructure""" implements(IProvider) @staticmethod @interfacedoc def id(): return 'deezer_complete' @staticmethod @interfacedoc def name(): return "Deezer Complete" @staticmethod @interfacedoc def ressource_access(): return False @interfacedoc def get_source_from_id(self, external_id, path, download=False): return '' @interfacedoc def get_source_from_url(self, url, path, download=False): return '' @interfacedoc def get_id_from_url(self, url): return url.split("/")[-1:][0]
class WaveformContourWhite(WaveformContourBlack): """an white amplitude contour wavform. """ implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=(255, 255, 255), color_scheme='default'): super(WaveformContourWhite, self).__init__(width, height, bg_color, color_scheme) self.color_offset = 60 @staticmethod @interfacedoc def id(): return "waveform_contour_white" @staticmethod @interfacedoc def name(): return "Contour white"
class NewGrapher(cls): _id = grapher_id implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=(0, 0, 0), color_scheme='default'): super(NewGrapher, self).__init__(width, height, bg_color, color_scheme) self.parents.append(analyzer) self._result_id = result_id # TODO : make it generic when analyzer will be "atomize" @staticmethod @interfacedoc def id(): return grapher_id @staticmethod @interfacedoc def name(): return grapher_name __doc__ = """Builds a PIL image representing """ + grapher_name
class WavEncoder(GstEncoder): """WAV encoder based on Gstreamer""" implements(IEncoder) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(WavEncoder, self).setup(channels, samplerate, blocksize, totalframes) self.pipe = ''' appsrc name=src ! audioconvert ! wavenc ''' if self.filename and self.streaming: self.pipe += ''' ! tee name=t ! queue ! filesink location=%s t. ! queue ! appsink name=app sync=False ''' % self.filename elif self.filename: self.pipe += '! filesink location=%s async=False sync=False ' % self.filename else: self.pipe += '! queue ! appsink name=app sync=False ' self.start_pipeline(channels, samplerate) @staticmethod @interfacedoc def id(): return "wav_encoder" @staticmethod @interfacedoc def format(): return "WAV" @staticmethod @interfacedoc def version(): return "1.0" @staticmethod @interfacedoc def file_extension(): return "gst.wav" @staticmethod @interfacedoc def mime_type(): return "audio/x-wav" @interfacedoc def set_metadata(self, metadata): # TODO pass
class IRITDiverg(Analyzer): implements(IAnalyzer) ''' ''' def __init__(self, blocksize=1024, stepsize=None): super(IRITDiverg, self).__init__() self.parents['waveform'] = Waveform() self.ordre = 2 @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(IRITDiverg, self).setup(channels, samplerate, blocksize, totalframes) @staticmethod @interfacedoc def id(): return "irit_diverg" @staticmethod @interfacedoc def name(): return "IRIT Forward/Backward Divergence Segmentation" @staticmethod @interfacedoc def unit(): return "" def __str__(self): return "Stationnary Segments" def process(self, frames, eod=False): return frames, eod def post_process(self): audio_data = self.parents['waveform'].results['waveform_analyzer'].data if audio_data.shape[1] > 1: data = list(audio_data.mean(axis=1)) else: data = list(audio_data) frontieres = segment(data, self.samplerate(), self.ordre) segs = self.new_result(data_mode='label', time_mode='event') segs.id_metadata.id += '.' + 'segments' segs.id_metadata.name += ' ' + 'Segments' label = {0: 'Instable', 1: 'Forward', -1: 'Backward'} segs.data_object.label_metadata.label = label segs.data_object.label = [s[1] for s in frontieres] segs.data_object.time = [(float(s[0]) / self.samplerate()) for s in frontieres] self.add_result(segs) return
class WaveformContourWhite(WaveformContourBlack): """ Builds a PIL image representing an amplitude coutour (envelop) of the audio stream. """ implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=(255, 255, 255), color_scheme='default'): super(WaveformContourWhite, self).__init__(width, height, bg_color, color_scheme) self.color_offset = 60 @staticmethod @interfacedoc def id(): return "waveform_contour_white" @staticmethod @interfacedoc def name(): return "Contour white"
class Gain(Processor): """Gain effect processor""" implements(IEffect) @interfacedoc def __init__(self, gain=1.0): super(Gain, self).__init__() self.gain = gain @staticmethod @interfacedoc def id(): return "fx_gain" @staticmethod @interfacedoc def version(): return "1.0" @staticmethod @interfacedoc def name(): return "Gain effect" def process(self, frames, eod=False): return numpy.multiply(frames, self.gain), eod
class Waveform(Grapher): """Simple monochrome waveform image. """ implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=(255, 255, 255), color_scheme='default'): super(Waveform, self).__init__(width, height, bg_color, color_scheme) self.line_color = (0, 0, 0) @staticmethod @interfacedoc def id(): return "waveform_simple" @staticmethod @interfacedoc def name(): return "Waveform simple" @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(Waveform, self).setup(channels, samplerate, blocksize, totalframes) @interfacedoc def process(self, frames, eod=False): if len(frames) != 1: if len(frames.shape) > 1: buffer = frames[:, 0] else: buffer = frames buffer.shape = (len(buffer), 1) for samples, end in self.pixels_adapter.process(buffer, eod): if self.pixel_cursor < self.image_width - 1: self.draw_peaks(self.pixel_cursor, peaks(samples), self.line_color) self.pixel_cursor += 1 if self.pixel_cursor == self.image_width - 1: self.draw_peaks(self.pixel_cursor, peaks(samples), self.line_color) self.pixel_cursor += 1 return frames, eod @interfacedoc def post_process(self, output=None): a = 1 for x in range(self.image_width): self.pixel[x, self.image_height / 2] = tuple( map(lambda p: p + a, self.pixel[x, self.image_height / 2]))
class VorbisEncoder(GstEncoder): """ gstreamer-based OGG Vorbis encoder """ implements(IEncoder) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(VorbisEncoder, self).setup(channels, samplerate, blocksize, totalframes) self.pipe = ''' appsrc name=src ! audioconvert ! audioresample ! vorbisenc quality=0.9 ! oggmux ''' if self.filename and self.streaming: self.pipe += ''' ! tee name=t ! queue ! filesink location=%s t. ! queue ! appsink name=app sync=False ''' % self.filename elif self.filename: self.pipe += '! filesink location=%s async=False sync=False ' % self.filename else: self.pipe += '! queue ! appsink name=app sync=False ' self.start_pipeline(channels, samplerate) @staticmethod @interfacedoc def id(): return "gst_vorbis_enc" @staticmethod @interfacedoc def description(): return "Vorbis GStreamer based encoder" @staticmethod @interfacedoc def format(): return "OGG" @staticmethod @interfacedoc def file_extension(): return "ogg" @staticmethod @interfacedoc def mime_type(): return "application/ogg" @interfacedoc def set_metadata(self, metadata): self.metadata = metadata
class AubioEncoder(Processor): implements(IEncoder) abstract() type = 'encoder' def __init__(self, output, streaming=False, overwrite=False): super (AubioEncoder, self).__init__() if isinstance(output, str): import os.path if os.path.isdir(output): raise IOError("Encoder output must be a file, not a directory") elif os.path.isfile(output) and not overwrite: raise IOError( "Encoder output %s exists, but overwrite set to False") self.filename = output else: self.filename = None self.streaming = streaming if not self.filename and not self.streaming: raise Exception('Must give an output') self.eod = False self.metadata = None self.num_samples = 0 @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(AubioEncoder, self).setup( channels, samplerate, blocksize, totalframes) print ('setting up aubio with with', samplerate, blocksize) self.sink = aubio.sink(self.filename, samplerate, channels) @interfacedoc def release(self): if hasattr (self, 'sink'): self.sink.close() delattr(self, 'sink') @interfacedoc def set_metadata(self, metadata): self.metadata = metadata @interfacedoc def process(self, frames, eod=False): self.eod = eod max_write = 4096 indices = range(max_write, frames.shape[0], max_write) for f_slice in np.array_split(frames, indices): write_frames = f_slice.shape[0] self.sink.do_multi(f_slice.T.copy(), write_frames) self.num_samples += write_frames return frames, eod
class DeezerPreview(Provider): """Deezer Plugin to retrieve deezer's 30 seconds tracks preview""" implements(IProvider) @staticmethod @interfacedoc def id(): return 'deezer_preview' @staticmethod @interfacedoc def name(): return "Deezer Preview" @staticmethod @interfacedoc def ressource_access(): return True @interfacedoc def get_source_from_id(self, external_id, path, download=False): request_url = 'https://api.deezer.com/track/' + external_id try: request = get(request_url) assert request.status_code == 200 except AssertionError: raise ProviderError('deezer_preview', external_id=external_id) request_dict = json.loads(request.content) source_uri = request_dict['preview'] if download: file_name = request_dict['artist']['name'] + '-' + request_dict[ 'title_short'] + '-' + external_id file_name = slugify(file_name) + '.mp3' file_path = os.path.join(path, file_name) r = get(source_uri) if not os.path.exists(path): os.makedirs(path) with open(file_path, 'wb') as f: f.write(r.content) f.close() return file_path else: return source_uri @interfacedoc def get_source_from_url(self, url, path, download=False): deezer_track_id = self.get_id_from_url(url) try: return self.get_source_from_id(deezer_track_id, path, download) except ProviderError: raise ProviderError('deezer_preview', external_uri=url) @interfacedoc def get_id_from_url(self, url): return url.split("/")[-1:][0]
class AubioMfcc(Analyzer): """Aubio MFCC analyzer""" implements(IAnalyzer) def __init__(self): super(AubioMfcc, self).__init__() self.input_blocksize = 1024 self.input_stepsize = self.input_blocksize / 4 @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(AubioMfcc, self).setup(channels, samplerate, blocksize, totalframes) self.n_filters = 40 self.n_coeffs = 13 self.pvoc = pvoc(self.input_blocksize, self.input_stepsize) self.mfcc = mfcc(self.input_blocksize, self.n_filters, self.n_coeffs, samplerate) self.block_read = 0 self.mfcc_results = numpy.zeros([ self.n_coeffs, ]) @staticmethod @interfacedoc def id(): return "aubio_mfcc" @staticmethod @interfacedoc def name(): return "MFCC (aubio)" @staticmethod @interfacedoc def unit(): return "" @downmix_to_mono @frames_adapter def process(self, frames, eod=False): fftgrain = self.pvoc(frames) coeffs = self.mfcc(fftgrain) self.mfcc_results = numpy.vstack((self.mfcc_results, coeffs)) self.block_read += 1 return frames, eod def post_process(self): 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.process_pipe.results.add(mfcc)
class WaveformCentroid(Waveform): """Waveform where peaks are colored relatively to the spectral centroids of each frame buffer. """ implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=(0, 0, 0), color_scheme='default'): super(WaveformCentroid, self).__init__(width, height, bg_color, color_scheme) self.lower_freq = 200 colors = default_color_schemes[color_scheme]['waveform'] self.color_lookup = interpolate_colors(colors) @staticmethod @interfacedoc def id(): return "waveform_centroid" @staticmethod @interfacedoc def name(): return "Waveform spectral" @staticmethod @interfacedoc def version(): return "1.0" @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(WaveformCentroid, self).setup(channels, samplerate, blocksize, totalframes) @interfacedoc def process(self, frames, eod=False): if len(frames) != 1: buffer = frames[:, 0].copy() buffer.shape = (len(buffer), 1) for samples, end in self.pixels_adapter.process(buffer, eod): if self.pixel_cursor < self.image_width: (spectral_centroid, db_spectrum) = self.spectrum.process(samples, True) line_color = self.color_lookup[int(spectral_centroid * 255.0)] self.draw_peaks(self.pixel_cursor, peaks(samples), line_color) self.pixel_cursor += 1 return frames, eod
class OpusEncoder(GstEncoder): """Opus encoder based on Gstreamer""" implements(IEncoder) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(OpusEncoder, self).setup(channels, samplerate, blocksize, totalframes) self.pipe = '''appsrc name=src ! audioconvert ! audioresample ! opusenc audio=true bitrate=128000 ! oggmux ''' if self.filename and self.streaming: self.pipe += ''' ! tee name=t ! queue ! filesink location=%s t. ! queue! appsink name=app sync=False ''' % self.filename elif self.filename: self.pipe += '! filesink location=%s async=False sync=False ' % self.filename else: self.pipe += '! queue ! appsink name=app sync=False' self.start_pipeline(channels, samplerate) @staticmethod @interfacedoc def id(): return "opus_encoder" @staticmethod @interfacedoc def format(): return "Opus" @staticmethod @interfacedoc def file_extension(): return "opus" @staticmethod @interfacedoc def mime_type(): return "audio/ogg" @interfacedoc def set_metadata(self, metadata): self.metadata = metadata
class WaveformContourBlack(Waveform): """Black amplitude contour waveform. """ implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=(0, 0, 0), color_scheme='default'): super(WaveformContourBlack, self).__init__(width, height, bg_color, color_scheme) self.contour = numpy.zeros(self.image_width) self.ndiv = 4 self.x = numpy.r_[0:self.image_width - 1:1] self.symetry = True self.color_offset = 160 @staticmethod @interfacedoc def id(): return "waveform_contour_black" @staticmethod @interfacedoc def name(): return "Contour black" @staticmethod @interfacedoc def version(): return "1.0" @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(WaveformContourBlack, self).setup(channels, samplerate, blocksize, totalframes) @interfacedoc def process(self, frames, eod=False): if len(frames) != 1: buffer = frames[:, 0].copy() buffer.shape = (len(buffer), 1) for samples, end in self.pixels_adapter.process(buffer, eod): if self.pixel_cursor < self.image_width: self.contour[self.pixel_cursor] = numpy.max(peaks(samples)) self.pixel_cursor += 1 if eod: self.draw_peaks_contour() return frames, eod
class AubioMelEnergy(Analyzer): """Aubio Mel Energy analyzer""" implements(IAnalyzer) def __init__(self): super(AubioMelEnergy, self).__init__() self.input_blocksize = 1024 self.input_stepsize = self.input_blocksize / 4 @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(AubioMelEnergy, self).setup(channels, samplerate, blocksize, totalframes) self.n_filters = 40 self.n_coeffs = 13 self.pvoc = pvoc(self.input_blocksize, self.input_stepsize) self.melenergy = filterbank(self.n_filters, self.input_blocksize) self.melenergy.set_mel_coeffs_slaney(samplerate) self.block_read = 0 self.melenergy_results = [] @staticmethod @interfacedoc def id(): return "aubio_melenergy" @staticmethod @interfacedoc def name(): return "Mel Energy (aubio)" @staticmethod @interfacedoc def unit(): return "" @downmix_to_mono @frames_adapter def process(self, frames, eod=False): fftgrain = self.pvoc(frames) self.melenergy_results.append(self.melenergy(fftgrain)) self.block_read += 1 return frames, eod def post_process(self): melenergy = self.new_result(data_mode='value', time_mode='framewise') melenergy.parameters = dict(n_filters=self.n_filters, n_coeffs=self.n_coeffs) melenergy.data_object.value = self.melenergy_results self.process_pipe.results.add(melenergy)
class WaveformTransparent(Waveform): """Transparent waveform. """ implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=None, color_scheme='default'): super(WaveformTransparent, self).__init__(width, height, bg_color, color_scheme) self.line_color = (255, 255, 255) @staticmethod @interfacedoc def id(): return "waveform_transparent" @staticmethod @interfacedoc def name(): return "Waveform transparent" @staticmethod @interfacedoc def version(): return "1.0" @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(WaveformTransparent, self).setup(channels, samplerate, blocksize, totalframes) @interfacedoc def process(self, frames, eod=False): if len(frames) != 1: buffer = frames[:, 0] buffer.shape = (len(buffer), 1) for samples, end in self.pixels_adapter.process(buffer, eod): if self.pixel_cursor < self.image_width - 1: self.draw_peaks_inverted(self.pixel_cursor, peaks(samples), self.line_color) self.pixel_cursor += 1 if self.pixel_cursor == self.image_width - 1: self.draw_peaks_inverted(self.pixel_cursor, peaks(samples), self.line_color) self.pixel_cursor += 1 return frames, eod
class NewGrapher(cls): _id = grapher_id _staging = staging _from_analyzer = True _analyzer = analyzer _analyzer_parameters = analyzer_parameters _result_id = result_id _grapher_name = grapher_name implements(IGrapher) @interfacedoc def __init__(self, width=1024, height=256, bg_color=(0, 0, 0), color_scheme='default'): super(NewGrapher, self).__init__(width, height, bg_color, color_scheme) # Add a parent waveform analyzer if background == 'waveform': self._background = True bg_analyzer = timeside.plugins.analyzer.waveform.Waveform() self._bg_id = bg_analyzer.id() self.parents['bg_analyzer'] = bg_analyzer elif background == 'spectrogram': self._background = True bg_analyzer = timeside.plugins.analyzer.spectrogram.Spectrogram() self._bg_id = bg_analyzer.id() self.parents['bg_analyzer'] = bg_analyzer else: self._background = None parent_analyzer = analyzer(**analyzer_parameters) self.parents['analyzer'] = parent_analyzer self._result_id = result_id @staticmethod @interfacedoc def id(): return grapher_id @staticmethod @interfacedoc def version(): return grapher_version @staticmethod @interfacedoc def name(): return grapher_name __doc__ = """Image representing """ + grapher_name
class VampTempo(VampAnalyzer): """Tempo from QMUL vamp plugins""" implements(IValueAnalyzer) _schema = { '$schema': 'http://json-schema.org/schema#', 'properties': {}, 'type': 'object' } @store_parameters def __init__(self): super(VampTempo, self).__init__() # Define Vamp plugin key and output self.plugin_key = 'qm-vamp-plugins:qm-tempotracker' self.plugin_output = 'tempo' @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(VampTempo, self).setup(channels, samplerate, blocksize, totalframes) @staticmethod @interfacedoc def id(): return "vamp_tempo" @staticmethod @interfacedoc def name(): return "Tempo" @staticmethod @interfacedoc def version(): return "1.1.0" @staticmethod @interfacedoc def unit(): return "bpm" def post_process(self): super(VampTempo, self).post_process() tempo = self.new_result(data_mode='value', time_mode='global') if self.vamp_results['list']: tempo.data_object.value = self.vamp_results['list'][0]['values'] self.add_result(tempo)
class FlacEncoder(GstEncoder): """FLAC encoder based on Gstreamer""" implements(IEncoder) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(FlacEncoder, self).setup(channels, samplerate, blocksize, totalframes) self.pipe = ''' appsrc name=src ! audioconvert ! flacenc ''' if self.filename and self.streaming: self.pipe += ''' ! tee name=t ! queue ! filesink location=%s t. ! queue ! appsink name=app sync=False ''' % self.filename elif self.filename: self.pipe += '! filesink location=%s async=False sync=False ' % self.filename else: self.pipe += '! queue ! appsink name=app sync=False ' self.start_pipeline(channels, samplerate) @staticmethod @interfacedoc def id(): return "flac_encoder" @staticmethod @interfacedoc def format(): return "FLAC" @staticmethod @interfacedoc def file_extension(): return "flac" @staticmethod @interfacedoc def mime_type(): return 'audio/x-flac' @interfacedoc def set_metadata(self, metadata): self.metadata = metadata
class Spectrogram(Analyzer): """Spectrogram analyzer""" implements(IAnalyzer) def __init__(self, blocksize=2048, stepsize=None, fft_size=None): super(Spectrogram, self).__init__() self.input_blocksize = blocksize if stepsize: self.input_stepsize = stepsize else: self.input_stepsize = blocksize / 2 if not fft_size: self.FFT_SIZE = blocksize else: self.FFT_SIZE = fft_size self.values = [] @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(Spectrogram, self).setup(channels, samplerate, blocksize, totalframes) @staticmethod @interfacedoc def id(): return "spectrogram_analyzer" @staticmethod @interfacedoc def name(): return "Spectrogram Analyzer" @staticmethod @interfacedoc def unit(): return "" @downmix_to_mono @frames_adapter def process(self, frames, eod=False): self.values.append(np.abs(np.fft.rfft(frames, self.FFT_SIZE))) return frames, eod def post_process(self): spectrogram = self.new_result(data_mode='value', time_mode='framewise') spectrogram.parameters = {'FFT_SIZE': self.FFT_SIZE} spectrogram.data_object.value = self.values self.process_pipe.results.add(spectrogram)
class VampTuning(VampAnalyzer): """Tuning from NNLS Chroma vamp plugins""" implements(IValueAnalyzer) _schema = { '$schema': 'http://json-schema.org/schema#', 'properties': {}, 'type': 'object' } @store_parameters def __init__(self): super(VampTuning, self).__init__() # Define Vamp plugin key and output self.plugin_key = 'nnls-chroma:tuning' self.plugin_output = 'tuning' @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(VampTuning, self).setup(channels, samplerate, blocksize, totalframes) @staticmethod @interfacedoc def id(): return "vamp_tuning" @staticmethod @interfacedoc def name(): return "Tuning" @staticmethod @interfacedoc def version(): return "1.1.0" @staticmethod @interfacedoc def unit(): return "Hz" def post_process(self): super(VampTuning, self).post_process() tuning = self.new_result(data_mode='value', time_mode='global') tuning.data_object.value = self.vamp_results['list'][0]['values'] self.add_result(tuning)
class Essentia_Dissonance_Value(Analyzer): """Mean Dissonance Value from Essentia""" implements(IValueAnalyzer) _schema = {'$schema': 'http://json-schema.org/schema#', 'properties': { }, 'type': 'object'} @store_parameters def __init__(self): super(Essentia_Dissonance_Value, self).__init__() self.parents['dissonance'] = Essentia_Dissonance() @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(Essentia_Dissonance_Value, self).setup( channels, samplerate, blocksize, totalframes) @staticmethod @interfacedoc def id(): return "essentia_dissonance_value" @staticmethod @interfacedoc def name(): return "Dissonance mean value from Essentia" @staticmethod @interfacedoc def unit(): return "" @downmix_to_mono @frames_adapter def process(self, frames, eod=False): return frames, eod def post_process(self): dissonance = self.parents['dissonance'].results['essentia_dissonance'].data if dissonance.any(): disson_mean = dissonance[dissonance > 0].mean() else: disson_mean = 0 dissonance_value = self.new_result(data_mode='value', time_mode='global') dissonance_value.data_object.value = disson_mean self.add_result(dissonance_value)
class Waveform(Analyzer): """Waveform analyzer""" implements(IAnalyzer) # TODO check if needed with inheritance def __init__(self): super(Waveform, self).__init__() # self.input_blocksize = 2048 # self.input_stepsize = self.input_blocksize / 2 @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(Waveform, self).setup(channels, samplerate, blocksize, totalframes) self.values = [] self.result_blocksize = 1 self.result_stepsize = 1 @staticmethod @interfacedoc def id(): return "waveform_analyzer" @staticmethod @interfacedoc def name(): return "Waveform Analyzer" @staticmethod @interfacedoc def version(): return "1.0" @staticmethod @interfacedoc def unit(): return "" # @downmix_to_mono # @frames_adapter def process(self, frames, eod=False): self.values.append(frames) return frames, eod def post_process(self): waveform = self.new_result(data_mode='value', time_mode='framewise') waveform.data_object.value = np.vstack(self.values) self.add_result(waveform)
class SpectrogramLinear(SpectrogramLog): """Linear scaled spectrogram (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_lin" @staticmethod @interfacedoc def name(): return "Spectrogram Lin" @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))
class DummyAnalyzer(Analyzer): """A dummy analyzer returning random samples from audio frames""" implements(IAnalyzer) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(DummyAnalyzer, self).setup(channels, samplerate, blocksize, totalframes) self.values = numpy.array([0]) @staticmethod @interfacedoc def id(): return "dummy" @staticmethod @interfacedoc def version(): return "0.1" @staticmethod @interfacedoc def name(): return "Dummy analyzer" @staticmethod @interfacedoc def unit(): return "None" def process(self, frames, eod=False): size = frames.size if size: index = numpy.random.randint(0, size, 1) self.values = numpy.append(self.values, frames[index]) return frames, eod def post_process(self): result = self.new_result(data_mode='value', time_mode='global') result.data_object.value = self.values self.add_result(result)
class MeanDCShift(Analyzer): """Mean DC shift analyzer""" implements(IValueAnalyzer) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(MeanDCShift, self).setup(channels, samplerate, blocksize, totalframes) self.values = numpy.array([0]) @staticmethod @interfacedoc def id(): return "mean_dc_shift" @staticmethod @interfacedoc def name(): return "Mean DC shift Analyzer" @staticmethod @interfacedoc def version(): return "1.0" @staticmethod @interfacedoc def unit(): return "%" def process(self, frames, eod=False): if frames.size: self.values = numpy.append(self.values, numpy.mean(frames)) return frames, eod def post_process(self): dc_result = self.new_result(data_mode='value', time_mode='global') dc_result.data_object.value = numpy.round( numpy.mean(100 * self.values), 3) self.add_result(dc_result)
class Gain(Processor): implements(IEffect) @interfacedoc def __init__(self, gain=1.0): self.gain = gain @staticmethod @interfacedoc def id(): return "test_gain" @staticmethod @interfacedoc def name(): return "Gain test effect" def process(self, frames, eod=False): return numpy.multiply(frames, self.gain), eod
class VorbisEncoder(AubioEncoder): """OGG Vorbis encoder based on aubio""" implements(IEncoder) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(VorbisEncoder, self).setup(channels, samplerate, blocksize, totalframes) @staticmethod @interfacedoc def id(): return "vorbis_aubio_encoder" @staticmethod @interfacedoc def format(): return "OGG" @staticmethod @interfacedoc def version(): return "1.0" @staticmethod @interfacedoc def file_extension(): return "ogg" @staticmethod @interfacedoc def mime_type(): return 'audio/ogg'
class WavEncoder(AubioEncoder): """Wav encoder based on aubio""" implements(IEncoder) @interfacedoc def setup(self, channels=None, samplerate=None, blocksize=None, totalframes=None): super(WavEncoder, self).setup(channels, samplerate, blocksize, totalframes) @staticmethod @interfacedoc def id(): return "wav_aubio_encoder" @staticmethod @interfacedoc def format(): return "WAV" @staticmethod @interfacedoc def version(): return "1.0" @staticmethod @interfacedoc def file_extension(): return "wav" @staticmethod @interfacedoc def mime_type(): return 'audio/x-wav'