]> git.parisson.com Git - timeside.git/commitdiff
add vorbis encoder, more tests, more BUGS !
authoryomguy <yomguy@parisson.com>
Fri, 25 Jun 2010 17:12:38 +0000 (17:12 +0000)
committeryomguy <yomguy@parisson.com>
Fri, 25 Jun 2010 17:12:38 +0000 (17:12 +0000)
timeside/encoder/__init__.py
timeside/encoder/ogg.py
timeside/encoder/wav.py
timeside/tests/api/test_vorbis.py [new file with mode: 0644]
timeside/tests/api/test_wav.py [new file with mode: 0644]

index 82481643b547c3fb743a77e570641dce4c163a7c..67ee689711fa9a66596ddd1a7f8af0f31c0deaa0 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 
 from core import *
-#from timeside.encoder.ogg import *
+from ogg import *
 from wav import *
 #from timeside.encoder.mp3 import *
 #from timeside.encoder.flac import *
index 566c5299190e666ebf26bd6d3533056c6d6d8c6f..fb89fd35e2f908be239c3e0140a6b4d313590981 100644 (file)
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2007-2009 Guillaume Pellerin <yomguy@parisson.com>
+# Copyright (c) 2010 Paul Brossier <piem@piem.org>
+# Copyright (c) 2010 Guillaume Pellerin <yomguy@parisson.com>
 
 # This file is part of TimeSide.
 
 # You should have received a copy of the GNU General Public License
 # along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
 
-# Author: Guillaume Pellerin <yomguy@parisson.com>
 
-import os
-import string
-import subprocess
-
-from timeside.encoder.core import *
+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 OggVorbisEncoder(EncoderCore):
-    """Defines methods to encode to OGG Vorbis"""
 
+class VorbisEncoder(Processor):
+    """ gstreamer-based vorbis encoder """
     implements(IEncoder)
 
-    def __init__(self):
-        self.bitrate_default = '192'
-        self.dub2args_dict = {'creator': 'artist',
-                             'relation': 'album'
-                             }
+    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(VorbisEncoder, self).setup(channels, samplerate, nframes)
+        # TODO open file for writing
+        # the output data format we want
+        pipeline = gst.parse_launch(''' appsrc name=src
+            ! audioconvert
+            ! vorbisenc
+            ! oggmux
+            ! 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 "oggenc"
-
-    def format(self):
-        return 'OggVorbis'
-
-    def file_extension(self):
-        return 'ogg'
-
-    def mime_type(self):
-        return 'application/ogg'
-
-    def description(self):
-        return """
-        Vorbis is a free software / open source project headed by the Xiph.Org
-        Foundation (formerly Xiphophorus company). The project produces an audio
-        format specification and software implementation (codec) for lossy audio
-        compression. Vorbis is most commonly used in conjunction with the Ogg
-        container format and it is therefore often referred to as Ogg Vorbis.
-        (source Wikipedia)
-        """
-
-    def get_file_info(self, file):
-        try:
-            file_out1, file_out2 = os.popen4('ogginfo "' + file + '"')
-            info = []
-            for line in file_out2.readlines():
-                info.append(clean_word(line[:-1]))
-            self.info = info
-            return self.info
-        except:
-            raise IOError('EncoderError: file does not exist.')
-
-    def write_tags(self, file):
-        from mutagen.oggvorbis import OggVorbis
-        media = OggVorbis(file)
-        for tag in self.metadata.keys():
-            media[tag] = str(self.metadata[tag])
-        media.save()
-
-    def get_args(self):
-        """Get process options and return arguments for the encoder"""
-        args = []
-        if not self.options is None:
-            if not ('verbose' in self.options and self.options['verbose'] != '0'):
-                args.append('-Q ')
-            if 'ogg_bitrate' in self.options:
-                args.append('-b '+self.options['ogg_bitrate'])
-            elif 'ogg_quality' in self.options:
-                args.append('-q '+self.options['ogg_quality'])
-            else:
-                args.append('-b '+self.bitrate_default)
-        else:
-            args.append('-Q -b '+self.bitrate_default)
-
-        for tag in self.metadata:
-            name = tag[0]
-            value = clean_word(tag[1])
-            args.append('-c %s="%s"' % (name, value))
-            if name in self.dub2args_dict.keys():
-                arg = self.dub2args_dict[name]
-                args.append('-c %s="%s"' % (arg, value))
-        return args
-
-    def process(self, source, metadata, options=None):
-        self.metadata = metadata
-        self.options = options
-        args = self.get_args()
-        args = ' '.join(args)
-        command = 'oggenc %s -' % args
-
-        stream = self.core_process(command, source)
-        for __chunk in stream:
-            yield __chunk
+        return "gst_vorbis_enc"
+
+    @staticmethod
+    @interfacedoc
+    def description():
+        return "Vorbis GStreamer based encoder"
+
+    @staticmethod
+    @interfacedoc
+    def file_extension():
+        return "ogg"
+
+    @staticmethod
+    @interfacedoc
+    def mime_type():
+        return "audio/ogg"
+
+    @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
+
 
 
index d790aaa03aff908a947aa34ce296387b56f5aa92..786564aef8596eca33e21f3547465da899b40b2f 100644 (file)
@@ -1,29 +1,7 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2007-2009 Guillaume Pellerin <yomguy@parisson.com>
-
-# 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 <http://www.gnu.org/licenses/>.
-
-# Author: Guillaume Pellerin <yomguy@parisson.com>
-
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2007-2009 Parisson
-# Copyright (c) 2007 Olivier Guilyardi <olivier@samalyse.com>
-# Copyright (c) 2007-2009 Guillaume Pellerin <pellerin@parisson.com>
+# Copyright (c) 2007-2010 Parisson
+# Copyright (c) 2010 Paul Brossier <piem@piem.org>
 #
 # This file is part of TimeSide.
 
@@ -89,12 +67,12 @@ class WavEncoder(Processor):
     @staticmethod
     @interfacedoc
     def id():
-        return "gstreamerenc"
+        return "gst_wav_enc"
 
     @staticmethod
     @interfacedoc
     def description():
-        return "Gstreamer based encoder"
+        return "Wav GStreamer based encoder"
 
     @staticmethod
     @interfacedoc
diff --git a/timeside/tests/api/test_vorbis.py b/timeside/tests/api/test_vorbis.py
new file mode 100644 (file)
index 0000000..ec2a568
--- /dev/null
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+
+from timeside.decoder import *
+from timeside.analyzer import *
+from timeside.encoder import *
+
+import os.path
+source = os.path.join(os.path.dirname(__file__), "../samples/sweep.wav")
+dest = os.path.join(os.path.dirname(__file__), "../results/sweep_wav.ogg")
+
+decoder  = FileDecoder(source)
+encoder  = VorbisEncoder(dest)
+
+(decoder | encoder).run()
diff --git a/timeside/tests/api/test_wav.py b/timeside/tests/api/test_wav.py
new file mode 100644 (file)
index 0000000..077a01e
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+from timeside.decoder import *
+from timeside.analyzer import *
+from timeside.encoder import *
+
+import os.path
+source = os.path.join(os.path.dirname(__file__),  "../samples/sweep.wav")
+dest = os.path.join(os.path.dirname(__file__), "../results/sweep_wav.wav")
+
+decoder  = FileDecoder(source)
+encoder  = WavEncoder(dest)
+
+(decoder | encoder).run()
+