[pitivi] Timeline: Add new smart audio mixing.



commit aa7b963a721dcdf8fda1581e386f042e03722f9e
Author: Edward Hervey <bilboed bilboed com>
Date:   Tue Jun 9 11:24:24 2009 +0200

    Timeline: Add new smart audio mixing.
    
    Currently it's using a fixed output caps, it should be changed to be the
    audio caps from the project output audio settings.

 pitivi/elements/Makefile.am |    1 +
 pitivi/elements/mixer.py    |   96 +++++++++++++++++++++++++++++++++++++++++++
 pitivi/factories/test.py    |   11 +++--
 pitivi/timeline/track.py    |   15 +++++++
 4 files changed, 118 insertions(+), 5 deletions(-)
---
diff --git a/pitivi/elements/Makefile.am b/pitivi/elements/Makefile.am
index f0c91f7..516c4d3 100644
--- a/pitivi/elements/Makefile.am
+++ b/pitivi/elements/Makefile.am
@@ -4,6 +4,7 @@ elements_PYTHON = 		\
 	__init__.py 		\
 	arraysink.py 		\
 	imagefreeze.py 		\
+	mixer.py		\
 	singledecodebin.py 	\
 	smartscale.py		\
 	thumbnailsink.py 	\
diff --git a/pitivi/elements/mixer.py b/pitivi/elements/mixer.py
new file mode 100644
index 0000000..f62974e
--- /dev/null
+++ b/pitivi/elements/mixer.py
@@ -0,0 +1,96 @@
+# PiTiVi , Non-linear video editor
+#
+#       pitivi/elements/mixer.py
+#
+# Copyright (c) 2009, Edward Hervey <bilboed bilboed com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""
+Audio and Video mixers
+"""
+
+import gobject
+import gst
+
+class SmartAdderBin(gst.Bin):
+
+    __gstdetails__ = (
+        "Smart Adder",
+        "Generic/Audio",
+        "Convenience wrapper around adder, accepts anything",
+        "Edward Hervey <bilboed bilboed com>"
+        )
+
+    __gsttemplates__ = (
+        gst.PadTemplate("src", gst.PAD_SRC, gst.PAD_ALWAYS,
+                        gst.Caps("audio/x-raw-int;audio/x-raw-float")),
+        gst.PadTemplate("sink_%u", gst.PAD_SINK, gst.PAD_REQUEST,
+                        gst.Caps("audio/x-raw-int;audio/x-raw-float"))
+
+        )
+
+    def __init__(self):
+        gst.Bin.__init__(self)
+        self.adder = gst.element_factory_make("adder", "real-adder")
+        # FIXME : USE THE PROJECT SETTINGS FOR THESE CAPS !
+        csp = gst.element_factory_make("capsfilter")
+        csp.props.caps = gst.Caps("audio/x-raw-int,depth=32,width=32,signed=True,rate=44100,channels=2,endianness=1234")
+        self.add(self.adder, csp)
+        self.adder.link(csp)
+        srcpad = gst.GhostPad("src", csp.get_pad("src"))
+        srcpad.set_active(True)
+        self.add_pad(srcpad)
+        self.pad_count = 0
+        self.inputs = {} # key:pad_name, value:(sinkpad, aconv, aresample, adderpad)
+
+    def do_request_new_pad(self, template, name=None):
+        self.warning("template:%r, name:%r" % (template, name))
+        if name == None:
+            name = "sink_%u" % self.pad_count
+        if name in self.inputs.keys():
+            return None
+
+        aconv = gst.element_factory_make("audioconvert", "aconv-%d" % self.pad_count)
+        aresample = gst.element_factory_make("audioresample", "aresample-%d" % self.pad_count)
+        self.add(aconv, aresample)
+        aconv.sync_state_with_parent()
+        aresample.sync_state_with_parent()
+        aconv.link(aresample)
+        adderpad = self.adder.get_request_pad("sink%d")
+        aresample.get_pad("src").link(adderpad)
+
+        pad = gst.GhostPad(name, aconv.get_pad("sink"))
+        pad.set_active(True)
+        self.add_pad(pad)
+        self.inputs[name] = (pad, aconv, aresample, adderpad)
+        self.pad_count += 1
+        return pad
+
+    def do_release_pad(self, pad):
+        self.warning("pad:%r", pad)
+        name = pad.get_name()
+        if name in self.inputs.keys():
+            sinkpad, aconv, aresample, adderpad = self.inputs.pop(name)
+            self.remove_pad(sinkpad)
+            aconv.unlink(aresample)
+            aresample.get_pad("src").unlink(adderpad)
+            self.adder.release_request_pad(adderpad)
+            self.remove(aconv, aresample)
+
+
+gobject.type_register(SmartAdderBin)
+gst.element_register(SmartAdderBin, 'smart-adder-bin')
diff --git a/pitivi/factories/test.py b/pitivi/factories/test.py
index 1934661..959d7cb 100644
--- a/pitivi/factories/test.py
+++ b/pitivi/factories/test.py
@@ -66,14 +66,15 @@ class AudioTestSourceFactory(SourceFactory):
             output_stream = self.output_streams[0]
 
         bin = gst.Bin()
-        videotestsrc = gst.element_factory_make('audiotestsrc')
-        videotestsrc.props.wave = self.wave
+        audiotestsrc = gst.element_factory_make('audiotestsrc', "real-audiotestsrc")
+        audiotestsrc.props.wave = self.wave
+        ares = gst.element_factory_make("audioresample", "default-audioresample")
+        aconv = gst.element_factory_make("audioconvert", "default-audioconvert")
         capsfilter = gst.element_factory_make('capsfilter')
         capsfilter.props.caps = output_stream.caps.copy()
 
-        bin.add(videotestsrc)
-        bin.add(capsfilter)
-        videotestsrc.link(capsfilter)
+        bin.add(audiotestsrc, ares, aconv, capsfilter)
+        gst.element_link_many(audiotestsrc, aconv, ares, capsfilter)
 
         target = capsfilter.get_pad('src')
         ghost = gst.GhostPad('src', target)
diff --git a/pitivi/timeline/track.py b/pitivi/timeline/track.py
index 9daaef6..23f75e7 100644
--- a/pitivi/timeline/track.py
+++ b/pitivi/timeline/track.py
@@ -27,6 +27,7 @@ from pitivi.utils import UNKNOWN_DURATION
 from pitivi.stream import VideoStream, AudioStream
 from pitivi.factories.test import VideoTestSourceFactory, \
         AudioTestSourceFactory
+from pitivi.elements.mixer import SmartAdderBin
 
 class TrackError(Exception):
     pass
@@ -317,6 +318,10 @@ class Track(Signallable):
         if default_track_object:
             self.setDefaultTrackObject(default_track_object)
 
+        self.mixer = self._getMixerForStream(stream)
+        if self.mixer:
+            self.composition.add(self.mixer)
+
     def _getDefaultTrackObjectForStream(self, stream):
         if isinstance(stream, VideoStream):
             return self._getDefaultVideoTrackObject(stream)
@@ -337,6 +342,16 @@ class Track(Signallable):
 
         return track_object
 
+    def _getMixerForStream(self, stream):
+        if isinstance(stream, AudioStream):
+            gnl = gst.element_factory_make("gnloperation", "top-level-audio-mixer")
+            m = SmartAdderBin()
+            gnl.add(m)
+            gnl.props.expandable = True
+            gnl.props.priority = 0
+            return gnl
+        return None
+
     def _getStart(self):
         return self.composition.props.start
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]