After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 545197 - jackaudiosrc
jackaudiosrc
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
git master
Other All
: Normal enhancement
: 0.10.9
Assigned To: Stefan Sauer (gstreamer, gtkdoc dev)
GStreamer Maintainers
: 352356 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2008-07-28 17:47 UTC by Tristan Matthews
Modified: 2008-08-07 09:20 UTC
See Also:
GNOME target: ---
GNOME version: Unversioned Enhancement


Attachments
jack module with intitial jackaudiosrc (624.05 KB, application/x-compressed-tar)
2008-07-28 17:55 UTC, Tristan Matthews
  Details
patch to gst-plugins bad that adds jackaudiosrc (91.63 KB, patch)
2008-07-29 15:37 UTC, Tristan Matthews
needs-work Details | Review
patch to gst-plugins-bad/ext/jack that adds jackaudiosrc (47.15 KB, patch)
2008-08-04 17:56 UTC, Tristan Matthews
none Details | Review
patch to gst-plugins-bad/ext/jack that adds jackaudiosrc (42.49 KB, patch)
2008-08-04 21:52 UTC, Tristan Matthews
needs-work Details | Review
plugin to gst-plugins-bad that adds jackaudiosrc (41.63 KB, patch)
2008-08-06 18:55 UTC, Tristan Matthews
committed Details | Review

Description Tristan Matthews 2008-07-28 17:47:41 UTC
Currently, the gst-plugins-bad module has a jackaudiosink, but no jackaudiosrc. I've started a jackaudiosrc, however, it adds some latency since the jack buffers have to be written to a ring buffer, which gstreamer elements reads from. Ideally, jack would write straight to the gstreamer elements.
Comment 1 Tristan Matthews 2008-07-28 17:55:55 UTC
Created attachment 115440 [details]
jack module with intitial jackaudiosrc

This module is based on gst-template and the jack module from gst-plugins-bad
Comment 2 Stefan Sauer (gstreamer, gtkdoc dev) 2008-07-29 13:16:13 UTC
gstjackaudiosrc.c: In Funktion »gst_jack_ring_buffer_acquire«:
gstjackaudiosrc.c:478: Warnung: Implizite Deklaration der Funktion »free«

you need to #include "stdlib.h"
Otherwise it works great. I piped qsynth thru
gst-launch jackaudiosrc connect=0 ! volume volume=0.5 ! jackaudiosink connect=0

Can you make a patch against gst-plugin-bad?
Comment 3 Tristan Matthews 2008-07-29 13:21:12 UTC
I should have that patch up later today.
Comment 4 Tristan Matthews 2008-07-29 15:37:06 UTC
Created attachment 115499 [details] [review]
patch to gst-plugins bad that adds jackaudiosrc
Comment 5 Stefan Sauer (gstreamer, gtkdoc dev) 2008-08-04 06:29:47 UTC
*** Bug 352356 has been marked as a duplicate of this bug. ***
Comment 6 Stefan Sauer (gstreamer, gtkdoc dev) 2008-08-04 06:54:25 UTC
The patch needs some work :/
* it has formatting changes
* it has some comments fro the template plugin (see e.g. Makefile.am)
* there are changes to jackaudiosink.{c,h}:
* gstjackringbuffer.h implements a class that is inlucded in both src/sink
  - there should be a gstjackringbuffer.c with the implementation
* jackaudiosrc.{c,h} the naming is not according to the conventions
  GST_TYPE_JACKAUDIOSRC -> GST_TYPE_JACK_AUDIO_SRC
  GST_JACKAUDIOSRC -> GST_JACK_AUDIO_SRC
  ...

$ diffstat jacksrc.diff 
 Makefile.am          |   23 -
 gstjack.c            |   43 +
 gstjack.h            |   48 ++
 gstjackaudioclient.h |   33 -
 gstjackaudiosink.c   | 1167 ++++++++++++++++++++++++---------------------------
 gstjackaudiosink.h   |   79 +--
 gstjackaudiosrc.c    |  815 +++++++++++++++++++++++++++++++++++
 gstjackaudiosrc.h    |  103 ++++
 gstjackbin.c         |    3 
 gstjackringbuffer.h  |   97 ++++
Comment 7 Tristan Matthews 2008-08-04 17:56:28 UTC
Created attachment 115844 [details] [review]
patch to gst-plugins-bad/ext/jack that adds jackaudiosrc

patch now ignores white space changes, uses 2 spaces for indentation rather than 4, removed comments leftover from gst-template, naming convention changed to JACK_AUDIO_SRC instead of JACKAUDIOSRC.
To be applied to gst-plugins/ext/jack
Comment 8 Tristan Matthews 2008-08-04 18:01:16 UTC
changes to jackaudiosink.{c,h} are needed to avoid duplicate code between jackaudiosrc/sink
jackaudiosrc and jackaudiosink each implement jackringbuffer differently, so for now the implementations are in gstjackaudiosrc.c and gstjackaudiosink.c respectively.
Comment 9 Tristan Matthews 2008-08-04 21:43:17 UTC
Comment on attachment 115844 [details] [review]
patch to gst-plugins-bad/ext/jack that adds jackaudiosrc

Index: jack/Makefile.am
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-bad/ext/jack/Makefile.am,v
retrieving revision 1.8
diff -p -u -w -r1.8 Makefile.am
--- jack/Makefile.am	8 Mar 2007 15:24:52 -0000	1.8
+++ jack/Makefile.am	4 Aug 2008 21:38:38 -0000
@@ -1,11 +1,11 @@
 
 plugin_LTLIBRARIES = libgstjack.la
 
-libgstjack_la_SOURCES = gstjack.c gstjackaudiosink.c gstjackaudioclient.c
+libgstjack_la_SOURCES = gstjack.c gstjackaudiosrc.c gstjackaudiosink.c gstjackaudioclient.c
 libgstjack_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(JACK_CFLAGS)
 libgstjack_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(JACK_LIBS)
 libgstjack_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
-noinst_HEADERS = gstjackaudiosink.h gstjackaudioclient.h
+noinst_HEADERS = gstjackaudiosrc.h gstjackaudiosink.h gstjackaudioclient.h gstjack.h gstjackringbuffer.h
 
 EXTRA_DIST = README
Index: jack/gstjack.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-bad/ext/jack/gstjack.c,v
retrieving revision 1.46
diff -p -u -w -r1.46 gstjack.c
--- jack/gstjack.c	13 Mar 2008 14:25:19 -0000	1.46
+++ jack/gstjack.c	4 Aug 2008 21:38:38 -0000
@@ -21,11 +21,34 @@
 #include "config.h"
 #endif
 
+#include "gstjackaudiosrc.h"
 #include "gstjackaudiosink.h"
 
+GType
+gst_jack_connect_get_type()
+{
+  static GType jack_connect_type = 0;
+  static const GEnumValue jack_connect[] = {
+    {GST_JACK_CONNECT_NONE,
+      "Don't automatically connect ports to physical ports", "none"},
+    {GST_JACK_CONNECT_AUTO,
+      "Automatically connect ports to physical ports", "auto"},
+    {0, NULL, NULL},
+  };
+
+  if (!jack_connect_type) {
+    jack_connect_type = g_enum_register_static ("GstJackConnect", jack_connect);
+  }
+  return jack_connect_type;
+}
+
+
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
+  if (!gst_element_register (plugin, "jackaudiosrc", GST_RANK_PRIMARY,
+        GST_TYPE_JACK_AUDIO_SRC))
+    return FALSE;
   if (!gst_element_register (plugin, "jackaudiosink", GST_RANK_PRIMARY,
           GST_TYPE_JACK_AUDIO_SINK))
     return FALSE;
@@ -33,8 +56,18 @@ plugin_init (GstPlugin * plugin)
   return TRUE;
 }
 
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+/* gstreamer looks for this structure to register jackaudiosrcs
+ *
+ * exchange the string 'Template jackaudiosrc' with your jackaudiosrc description
+ */
+GST_PLUGIN_DEFINE (
+    GST_VERSION_MAJOR,
     GST_VERSION_MINOR,
     "jack",
     "Jack elements",
-    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
+    plugin_init,
+    VERSION,
+    "LGPL",
+    "GStreamer",
+    "http://gstreamer.net/"
+    )
Index: jack/gstjack.h
===================================================================
RCS file: jack/gstjack.h
diff -N jack/gstjack.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jack/gstjack.h	4 Aug 2008 21:38:38 -0000
@@ -0,0 +1,48 @@
+/* GStreamer
+ * Copyright (C) 2006 Wim Taymans <wim@fluendo.com>
+ *
+ * gstjacksink.h:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GST_JACK_H_
+#define _GST_JACK_H_
+
+
+/**
+ * GstJackConnect:
+ * @GST_JACK_CONNECT_NONE: Don't automatically connect to physical ports.
+ *     In this mode, the element will accept any number of input channels and will
+ *     create (but not connect) an output port for each channel.
+ * @GST_JACK_CONNECT_AUTO: In this mode, the element will try to connect each
+ *     output port to a random physical jack input pin. The sink will
+ *     expose the number of physical channels on its pad caps.
+ *
+ * Specify how the output ports will be connected.
+ */
+
+typedef enum {
+  GST_JACK_CONNECT_NONE,
+  GST_JACK_CONNECT_AUTO
+} GstJackConnect;
+
+typedef jack_default_audio_sample_t sample_t;
+
+#define GST_TYPE_JACK_CONNECT (gst_jack_connect_get_type())
+GType gst_jack_connect_get_type();
+
+#endif  // _GST_JACK_H_
Index: jack/gstjackaudiosink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-bad/ext/jack/gstjackaudiosink.c,v
retrieving revision 1.10
diff -p -u -w -r1.10 gstjackaudiosink.c
--- jack/gstjackaudiosink.c	13 Jun 2008 11:59:19 -0000	1.10
+++ jack/gstjackaudiosink.c	4 Aug 2008 21:38:38 -0000
@@ -59,62 +59,11 @@
 #include <string.h>
 
 #include "gstjackaudiosink.h"
+#include "gstjackringbuffer.h"
 
 GST_DEBUG_CATEGORY_STATIC (gst_jack_audio_sink_debug);
 #define GST_CAT_DEFAULT gst_jack_audio_sink_debug
 
-typedef jack_default_audio_sample_t sample_t;
-
-#define GST_TYPE_JACK_RING_BUFFER        \
-        (gst_jack_ring_buffer_get_type())
-#define GST_JACK_RING_BUFFER(obj)        \
-        (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_JACK_RING_BUFFER,GstJackRingBuffer))
-#define GST_JACK_RING_BUFFER_CLASS(klass) \
-        (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_JACK_RING_BUFFER,GstJackRingBufferClass))
-#define GST_JACK_RING_BUFFER_GET_CLASS(obj) \
-        (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_JACK_RING_BUFFER, GstJackRingBufferClass))
-#define GST_JACK_RING_BUFFER_CAST(obj)        \
-        ((GstJackRingBuffer *)obj)
-#define GST_IS_JACK_RING_BUFFER(obj)     \
-        (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_JACK_RING_BUFFER))
-#define GST_IS_JACK_RING_BUFFER_CLASS(klass)\
-        (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_JACK_RING_BUFFER))
-
-typedef struct _GstJackRingBuffer GstJackRingBuffer;
-typedef struct _GstJackRingBufferClass GstJackRingBufferClass;
-
-struct _GstJackRingBuffer
-{
-  GstRingBuffer object;
-
-  gint sample_rate;
-  gint buffer_size;
-  gint channels;
-};
-
-struct _GstJackRingBufferClass
-{
-  GstRingBufferClass parent_class;
-};
-
-static void gst_jack_ring_buffer_class_init (GstJackRingBufferClass * klass);
-static void gst_jack_ring_buffer_init (GstJackRingBuffer * ringbuffer,
-    GstJackRingBufferClass * klass);
-static void gst_jack_ring_buffer_dispose (GObject * object);
-static void gst_jack_ring_buffer_finalize (GObject * object);
-
-static GstRingBufferClass *ring_parent_class = NULL;
-
-static gboolean gst_jack_ring_buffer_open_device (GstRingBuffer * buf);
-static gboolean gst_jack_ring_buffer_close_device (GstRingBuffer * buf);
-static gboolean gst_jack_ring_buffer_acquire (GstRingBuffer * buf,
-    GstRingBufferSpec * spec);
-static gboolean gst_jack_ring_buffer_release (GstRingBuffer * buf);
-static gboolean gst_jack_ring_buffer_start (GstRingBuffer * buf);
-static gboolean gst_jack_ring_buffer_pause (GstRingBuffer * buf);
-static gboolean gst_jack_ring_buffer_stop (GstRingBuffer * buf);
-static guint gst_jack_ring_buffer_delay (GstRingBuffer * buf);
-
 static gboolean
 gst_jack_audio_sink_allocate_channels (GstJackAudioSink * sink, gint channels)
 {
@@ -173,7 +122,7 @@ gst_jack_audio_sink_free_channels (GstJa
 
 /* ringbuffer abstract base class */
 static GType
-gst_jack_ring_buffer_get_type (void)
+gst_jack_ring_buffer_get_type()
 {
   static GType ringbuffer_type = 0;
 
@@ -689,24 +638,11 @@ enum
   PROP_LAST
 };
 
+#if 0
 #define GST_TYPE_JACK_CONNECT (gst_jack_connect_get_type())
-static GType
-gst_jack_connect_get_type (void)
-{
-  static GType jack_connect_type = 0;
-  static const GEnumValue jack_connect[] = {
-    {GST_JACK_CONNECT_NONE,
-        "Don't automatically connect ports to physical ports", "none"},
-    {GST_JACK_CONNECT_AUTO,
-        "Automatically connect ports to physical ports", "auto"},
-    {0, NULL, NULL},
-  };
-
-  if (!jack_connect_type) {
-    jack_connect_type = g_enum_register_static ("GstJackConnect", jack_connect);
-  }
-  return jack_connect_type;
-}
+GType
+gst_jack_connect_get_type();
+#endif
 
 #define _do_init(bla) \
     GST_DEBUG_CATEGORY_INIT (gst_jack_audio_sink_debug, "jacksink", 0, "jacksink element");
@@ -849,6 +785,7 @@ gst_jack_audio_sink_getcaps (GstBaseSink
     max = 0;
     if (ports != NULL) {
       for (; ports[max]; max++);
+
       free (ports);
     } else
       max = 0;
Index: jack/gstjackaudiosink.h
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-bad/ext/jack/gstjackaudiosink.h,v
retrieving revision 1.3
diff -p -u -w -r1.3 gstjackaudiosink.h
--- jack/gstjackaudiosink.h	8 Mar 2007 15:24:52 -0000	1.3
+++ jack/gstjackaudiosink.h	4 Aug 2008 21:38:38 -0000
@@ -27,6 +27,7 @@
 #include <gst/gst.h>
 #include <gst/audio/gstbaseaudiosink.h>
 
+#include "gstjack.h"
 #include "gstjackaudioclient.h"
 
 G_BEGIN_DECLS
@@ -42,22 +43,6 @@ typedef struct _GstJackAudioSink GstJack
 typedef struct _GstJackAudioSinkClass GstJackAudioSinkClass;
 
 /**
- * GstJackConnect:
- * @GST_JACK_CONNECT_NONE: Don't automatically connect to physical ports.
- *     In this mode, the element will accept any number of input channels and will
- *     create (but not connect) an output port for each channel.
- * @GST_JACK_CONNECT_AUTO: In this mode, the element will try to connect each
- *     output port to a random physical jack input pin. The sink will
- *     expose the number of physical channels on its pad caps.
- *
- * Specify how the output ports will be connected.
- */
-typedef enum {
-  GST_JACK_CONNECT_NONE,
-  GST_JACK_CONNECT_AUTO
-} GstJackConnect;
-
-/**
  * GstJackAudioSink:
  * 
  * Opaque #GstJackAudioSink.
@@ -85,7 +70,7 @@ struct _GstJackAudioSinkClass {
   GstBaseAudioSinkClass parent_class;
 };
 
-GType gst_jack_audio_sink_get_type (void);
+GType gst_jack_audio_sink_get_type ();
 
 G_END_DECLS
 
Index: jack/gstjackaudiosrc.c
===================================================================
RCS file: jack/gstjackaudiosrc.c
diff -N jack/gstjackaudiosrc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jack/gstjackaudiosrc.c	4 Aug 2008 21:38:39 -0000
@@ -0,0 +1,841 @@
+/* GStreamer
+ * Copyright (C) 2008 Tristan Matthews <tristan@sat.qc.ca>
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:element-jackaudiosrc
+ * @see_also: #GstBaseAudioSrc, #GstRingBuffer
+ *
+ * A Src that inputs data from Jack ports.
+ * 
+ * It will create N Jack ports named in_&lt;name&gt;_&lt;num&gt; where 
+ * &lt;name&gt; is the element name and &lt;num&gt; is starting from 1.
+ * Each port corresponds to a gstreamer channel.
+ * 
+ * The samplerate as exposed on the caps is always the same as the samplerate of
+ * the jack server.
+ * 
+ * When the #GstJackAudioSrc:connect property is set to auto, this element
+ * will try to connect each input port to a random physical jack output pin. 
+ * 
+ * When the #GstJackAudioSrc:connect property is set to none, the element will
+ * accept any number of output channels and will create (but not connect) an
+ * input port for each channel.
+ * 
+ * The element will generate an error when the Jack server is shut down when it
+ * was PAUSED or PLAYING. This element does not support dynamic rate and buffer
+ * size changes at runtime.
+ * 
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch jackaudiosrc connect=0 ! jackaudiosink connect=0
+ * ]| Get audio input into gstreamer from jack.
+ * </refsect2>
+ *
+ * Last reviewed on 2008-07-22 (0.10.4)
+ */
+
+#include <gst/gst.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gstjackaudiosrc.h"
+#include "gstjackringbuffer.h"
+
+GST_DEBUG_CATEGORY_STATIC(gst_jackaudiosrc_debug);
+#define GST_CAT_DEFAULT gst_jackaudiosrc_debug
+
+static gboolean 
+gst_jack_audio_src_allocate_channels(GstJackAudioSrc * src, gint channels)
+{
+  jack_client_t *client;
+
+  client = gst_jack_audio_client_get_client(src->client);
+
+  /* remove ports we don't need */
+  while (src->port_count > channels) 
+    jack_port_unregister(client, src->ports[--src->port_count]);
+
+  /* alloc enough input ports */
+  src->ports = g_realloc(src->ports, sizeof(jack_port_t *) * channels);
+
+  /* create an input port for each channel */
+  while (src->port_count < channels) 
+  {
+    gchar *name;
+
+    /* port names start from 1 and are local to the element */
+    name =
+      g_strdup_printf("in_%s_%d", GST_ELEMENT_NAME(src),
+          src->port_count + 1);
+    src->ports[src->port_count] =
+      jack_port_register(client, name, JACK_DEFAULT_AUDIO_TYPE,
+          JackPortIsInput, 0);
+    if (src->ports[src->port_count] == NULL)
+      return FALSE;
+
+    src->port_count++;
+
+    g_free(name);
+  }
+  return TRUE;
+}
+
+static void 
+gst_jack_audio_src_free_channels(GstJackAudioSrc * src)
+{
+  gint res, i = 0;
+  jack_client_t *client;
+
+  client = gst_jack_audio_client_get_client(src->client);
+
+  /* get rid of all ports */
+  while (src->port_count) 
+  {
+    GST_LOG_OBJECT(src, "unregister port %d", i);
+    if ((res = jack_port_unregister(client, src->ports[i++]))) 
+      GST_DEBUG_OBJECT(src, "unregister of port failed (%d)", res);
+
+    src->port_count--;
+  }
+  g_free(src->ports);
+  src->ports = NULL;
+}
+
+/* ringbuffer abstract base class */
+static GType 
+gst_jack_ring_buffer_get_type()
+{
+  static GType ringbuffer_type = 0;
+
+  if (!ringbuffer_type) {
+    static const GTypeInfo ringbuffer_info = { sizeof(GstJackRingBufferClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_jack_ring_buffer_class_init,
+      NULL,
+      NULL,
+      sizeof(GstJackRingBuffer),
+      0,
+      (GInstanceInitFunc) gst_jack_ring_buffer_init,
+      NULL
+    };
+
+    ringbuffer_type =
+      g_type_register_static(GST_TYPE_RING_BUFFER,
+          "GstJackAudioSrcRingBuffer", &ringbuffer_info, 0);
+  }
+  return ringbuffer_type;
+}
+
+static void 
+gst_jack_ring_buffer_class_init(GstJackRingBufferClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstObjectClass *gstobject_class;
+  GstRingBufferClass *gstringbuffer_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstobject_class = (GstObjectClass *) klass;
+  gstringbuffer_class = (GstRingBufferClass *) klass;
+
+  ring_parent_class = g_type_class_peek_parent(klass);
+
+  gobject_class->dispose = GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_dispose);
+  gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_finalize);
+
+  gstringbuffer_class->open_device =
+    GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_open_device);
+  gstringbuffer_class->close_device =
+    GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_close_device);
+  gstringbuffer_class->acquire =
+    GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_acquire);
+  gstringbuffer_class->release =
+    GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_release);
+  gstringbuffer_class->start = GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_start);
+  gstringbuffer_class->pause = GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_pause);
+  gstringbuffer_class->resume = GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_start);
+  gstringbuffer_class->stop = GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_stop);
+
+  gstringbuffer_class->delay = GST_DEBUG_FUNCPTR(gst_jack_ring_buffer_delay);
+}
+
+/* this is the callback of jack. This should be RT-safe.
+ * Writes samples from the jack input port's buffer to the gst ring buffer.
+ */
+static int 
+jack_process_cb(jack_nframes_t nframes, void *arg)
+{
+  GstJackAudioSrc *src;
+  GstRingBuffer *buf;
+  GstJackRingBuffer *abuf;
+  gint len, givenLen;
+  guint8 *writeptr, *dataStart;
+  gint writeseg;
+  gint channels, i, j;
+  sample_t **buffers, *data;
+
+  buf = GST_RING_BUFFER_CAST(arg);
+  abuf = GST_JACK_RING_BUFFER_CAST(arg);
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  channels = buf->spec.channels;
+  len = sizeof(sample_t) * nframes * channels;
+
+  /* alloc pointers to samples */
+  buffers = g_alloca(sizeof(sample_t *) * channels);
+  data = g_alloca(len);
+
+  /* get input buffers */
+  for (i = 0; i < channels; i++) 
+    buffers[i] = (sample_t *)jack_port_get_buffer(src->ports[i], nframes);
+
+  //writeptr = data; 
+  dataStart = (guint8*) data;
+
+  /* the samples in the jack input buffers have to be interleaved into the 
+   * ringbuffer 
+   */
+
+  for (i = 0; i < nframes; ++i) 
+    for (j = 0; j < channels; ++j)
+      *data++ = buffers[j][i]; 
+
+  if (gst_ring_buffer_prepare_read(buf, &writeseg, &writeptr, &givenLen))
+  {
+    memcpy(writeptr, (char *) dataStart, givenLen);
+
+    GST_DEBUG("copy %d frames: %p, %d bytes, %d channels", nframes, writeptr, len / channels, channels);
+
+    /* clear written samples in the ringbuffer */
+    // gst_ring_buffer_clear(buf, 0);
+
+    /* we wrote one segment */
+    gst_ring_buffer_advance(buf, 1);
+  }
+  return 0;
+}
+
+/* we error out */
+static int 
+jack_sample_rate_cb(jack_nframes_t nframes, void *arg)
+{
+  GstJackAudioSrc *src;
+  GstJackRingBuffer *abuf;
+
+  abuf = GST_JACK_RING_BUFFER_CAST(arg);
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(arg));
+
+  if (abuf->sample_rate != -1 && abuf->sample_rate != nframes)
+    goto not_supported;
+
+  return 0;
+
+  /* ERRORS */
+not_supported:
+  {
+    GST_ELEMENT_ERROR(src, RESOURCE, SETTINGS,
+        (NULL), ("Jack changed the sample rate, which is not supported"));
+    return 1;
+  }
+}
+
+/* we error out */
+static int 
+jack_buffer_size_cb(jack_nframes_t nframes, void *arg)
+{
+  GstJackAudioSrc *src;
+  GstJackRingBuffer *abuf;
+
+  abuf = GST_JACK_RING_BUFFER_CAST(arg);
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(arg));
+
+  if (abuf->buffer_size != -1 && abuf->buffer_size != nframes)
+    goto not_supported;
+
+  return 0;
+
+  /* ERRORS */
+not_supported:
+  {
+    GST_ELEMENT_ERROR(src, RESOURCE, SETTINGS,
+        (NULL), ("Jack changed the buffer size, which is not supported"));
+    return 1;
+  }
+}
+
+static void 
+jack_shutdown_cb(void *arg)
+{
+  GstJackAudioSrc *src;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(arg));
+
+  GST_DEBUG_OBJECT(src, "shutdown");
+
+  GST_ELEMENT_ERROR(src, RESOURCE, NOT_FOUND,
+      (NULL), ("Jack server shutdown"));
+}
+
+static void 
+gst_jack_ring_buffer_init(GstJackRingBuffer * buf, GstJackRingBufferClass * g_class)
+{
+  buf->channels = -1;
+  buf->buffer_size = -1;
+  buf->sample_rate = -1;
+}
+
+static void 
+gst_jack_ring_buffer_dispose(GObject * object)
+{
+  G_OBJECT_CLASS(ring_parent_class)->dispose(object);
+}
+
+static void 
+gst_jack_ring_buffer_finalize(GObject * object)
+{
+  GstJackRingBuffer *ringbuffer;
+  ringbuffer = GST_JACK_RING_BUFFER_CAST(object);
+  G_OBJECT_CLASS(ring_parent_class)->finalize(object);
+}
+
+/* the _open_device method should make a connection with the server
+*/
+static gboolean 
+gst_jack_ring_buffer_open_device(GstRingBuffer * buf)
+{
+  GstJackAudioSrc *src;
+  jack_status_t status = 0;
+  const gchar *name;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  GST_DEBUG_OBJECT(src, "open");
+
+  name = g_get_application_name();
+  if (!name)
+    name = "GStreamer";
+
+  src->client = gst_jack_audio_client_new(name, src->server,
+      GST_JACK_CLIENT_SOURCE,
+      jack_shutdown_cb,
+      jack_process_cb, jack_buffer_size_cb, jack_sample_rate_cb, buf, &status);
+  if (src->client == NULL)
+    goto could_not_open;
+
+  GST_DEBUG_OBJECT(src, "opened");
+
+  return TRUE;
+
+  /* ERRORS */
+could_not_open:
+  {
+    if (status & JackServerFailed) {
+      GST_ELEMENT_ERROR(src, RESOURCE, NOT_FOUND,
+          (NULL), ("Cannot connect to the Jack server (status %d)", status));
+    } else {
+      GST_ELEMENT_ERROR(src, RESOURCE, OPEN_WRITE,
+          (NULL), ("Jack client open error (status %d)", status));
+    }
+    return FALSE;
+  }
+}
+
+/* close the connection with the server
+*/
+static gboolean 
+gst_jack_ring_buffer_close_device(GstRingBuffer * buf)
+{
+  GstJackAudioSrc *src;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  GST_DEBUG_OBJECT(src, "close");
+
+  gst_jack_audio_src_free_channels(src);
+  gst_jack_audio_client_free(src->client);
+  src->client = NULL;
+
+  return TRUE;
+}
+
+
+/* allocate a buffer and setup resources to process the audio samples of
+ * the format as specified in @spec.
+ *
+ * We allocate N jack ports, one for each channel. If we are asked to
+ * automatically make a connection with physical ports, we connect as many
+ * ports as there are physical ports, leaving leftover ports unconnected.
+ *
+ * It is assumed that samplerate and number of channels are acceptable since our
+ * getcaps method will always provide correct values. If unacceptable caps are
+ * received for some reason, we fail here.
+ */
+static gboolean 
+gst_jack_ring_buffer_acquire(GstRingBuffer * buf, GstRingBufferSpec * spec)
+{
+  GstJackAudioSrc *src;
+  GstJackRingBuffer *abuf;
+  const char **ports;
+  gint sample_rate, buffer_size;
+  gint i, channels, res;
+  jack_client_t *client;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+  abuf = GST_JACK_RING_BUFFER_CAST(buf);
+
+  GST_DEBUG_OBJECT(src, "acquire");
+
+  client = gst_jack_audio_client_get_client(src->client);
+
+  /* sample rate must be that of the server */
+  sample_rate = jack_get_sample_rate(client);
+  if (sample_rate != spec->rate)
+    goto wrong_samplerate;
+
+  channels = spec->channels;
+
+  if (!gst_jack_audio_src_allocate_channels(src, channels))
+    goto out_of_ports;
+
+  buffer_size = jack_get_buffer_size(client);
+
+  /* the segment size in bytes, this is large enough to hold a buffer of 32bit floats
+   * for all channels  */
+  spec->segsize = buffer_size * sizeof(gfloat) * channels;
+  spec->latency_time = gst_util_uint64_scale(spec->segsize,
+      (GST_SECOND / GST_USECOND), spec->rate * spec->bytes_per_sample);
+  /* segtotal based on buffer-time latency */
+  spec->segtotal = spec->buffer_time / spec->latency_time;
+
+  GST_DEBUG_OBJECT(src, "segsize %d, segtotal %d", spec->segsize,
+      spec->segtotal);
+
+  /* allocate the ringbuffer memory now */
+  buf->data = gst_buffer_new_and_alloc(spec->segtotal * spec->segsize);
+  memset(GST_BUFFER_DATA(buf->data), 0, GST_BUFFER_SIZE(buf->data));
+
+  if ((res = gst_jack_audio_client_set_active(src->client, TRUE)))
+    goto could_not_activate;
+
+  /* if we need to automatically connect the ports, do so now. We must do this
+   * after activating the client. */
+  if (src->connect == GST_JACK_CONNECT_AUTO) {
+    /* find all the physical output ports. A physical output port is a port
+     * associated with a hardware device. Someone needs connect to a physical
+     * port in order to capture something. */
+    ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
+    if (ports == NULL) {
+      /* no ports? fine then we don't do anything except for posting a warning
+       * message. */
+      GST_ELEMENT_WARNING(src, RESOURCE, NOT_FOUND, (NULL),
+          ("No physical output ports found, leaving ports unconnected"));
+      goto done;
+    }
+
+    for (i = 0; i < channels; i++) 
+    {
+      /* stop when all output ports are exhausted */
+      if (ports[i] == NULL) {
+        /* post a warning that we could not connect all ports */
+        GST_ELEMENT_WARNING(src, RESOURCE, NOT_FOUND, (NULL),
+            ("No more physical ports, leaving some ports unconnected"));
+        break;
+      }
+      GST_DEBUG_OBJECT(src, "try connecting to %s",
+          jack_port_name(src->ports[i]));
+      /* connect the physical port to a port */
+
+      res = jack_connect(client, ports[i], jack_port_name(src->ports[i]));
+      g_print("connecting to %s\n", jack_port_name(src->ports[i]));
+      if (res != 0 && res != EEXIST)
+        goto cannot_connect;
+    }
+    free(ports);
+  }
+done:
+
+  abuf->sample_rate = sample_rate;
+  abuf->buffer_size = buffer_size;
+  abuf->channels = spec->channels;
+
+  return TRUE;
+
+  /* ERRORS */
+wrong_samplerate:
+  {
+    GST_ELEMENT_ERROR(src, RESOURCE, SETTINGS, (NULL),
+        ("Wrong samplerate, server is running at %d and we received %d",
+         sample_rate, spec->rate));
+    return FALSE;
+  }
+out_of_ports:
+  {
+    GST_ELEMENT_ERROR(src, RESOURCE, SETTINGS, (NULL),
+        ("Cannot allocate more Jack ports"));
+    return FALSE;
+  }
+could_not_activate:
+  {
+    GST_ELEMENT_ERROR(src, RESOURCE, SETTINGS, (NULL),
+        ("Could not activate client (%d:%s)", res, g_strerror(res)));
+    return FALSE;
+  }
+cannot_connect:
+  {
+    GST_ELEMENT_ERROR(src, RESOURCE, SETTINGS, (NULL),
+        ("Could not connect input ports to physical ports (%d:%s)",
+         res, g_strerror(res)));
+    free(ports);
+    return FALSE;
+  }
+}
+
+/* function is called with LOCK */
+static gboolean 
+gst_jack_ring_buffer_release(GstRingBuffer * buf)
+{
+  GstJackAudioSrc *src;
+  GstJackRingBuffer *abuf;
+  gint res;
+
+  abuf = GST_JACK_RING_BUFFER_CAST(buf);
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  GST_DEBUG_OBJECT(src, "release");
+
+  if ((res = gst_jack_audio_client_set_active(src->client, FALSE))) {
+    /* we only warn, this means the server is probably shut down and the client
+     * is gone anyway. */
+    GST_ELEMENT_WARNING(src, RESOURCE, CLOSE, (NULL),
+        ("Could not deactivate Jack client (%d)", res));
+  }
+
+  abuf->channels = -1;
+  abuf->buffer_size = -1;
+  abuf->sample_rate = -1;
+
+  /* free the buffer */
+  gst_buffer_unref(buf->data);
+  buf->data = NULL;
+
+  return TRUE;
+}
+
+static gboolean 
+gst_jack_ring_buffer_start(GstRingBuffer * buf)
+{
+  GstJackAudioSrc *src;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  GST_DEBUG_OBJECT(src, "start");
+
+  return TRUE;
+}
+
+static gboolean 
+gst_jack_ring_buffer_pause(GstRingBuffer * buf)
+{
+  GstJackAudioSrc *src;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  GST_DEBUG_OBJECT(src, "pause");
+
+  return TRUE;
+}
+
+static gboolean 
+gst_jack_ring_buffer_stop(GstRingBuffer * buf)
+{
+  GstJackAudioSrc *src;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  GST_DEBUG_OBJECT(src, "stop");
+
+  return TRUE;
+}
+
+static guint 
+gst_jack_ring_buffer_delay(GstRingBuffer * buf)
+{
+  GstJackAudioSrc *src;
+  guint res = 0;
+
+  src = GST_JACK_AUDIO_SRC(GST_OBJECT_PARENT(buf));
+
+  GST_DEBUG_OBJECT(src, "delay %u", res);
+
+  return res;
+}
+
+/* Audiosrc signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+#define DEFAULT_PROP_CONNECT 	GST_JACK_CONNECT_AUTO
+#define DEFAULT_PROP_SERVER 	NULL
+
+enum
+{
+  PROP_0,
+  PROP_CONNECT,
+  PROP_SERVER,
+  PROP_LAST
+};
+
+
+/* the capabilities of the inputs and outputs.
+ *
+ * describe the real formats here.
+ */
+
+static GstStaticPadTemplate src_factory = 
+GST_STATIC_PAD_TEMPLATE("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS("audio/x-raw-float, "
+      "endianness = (int) { " G_STRINGIFY(G_BYTE_ORDER) " }, "
+      "width = (int) 32, "
+      "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]")
+    );
+
+#define _do_init(bla) \
+  GST_DEBUG_CATEGORY_INIT(gst_jackaudiosrc_debug, "jacksrc", 0, "jacksrc element");
+
+GST_BOILERPLATE_FULL(GstJackAudioSrc, gst_jackaudiosrc, GstBaseAudioSrc,
+    GST_TYPE_BASE_AUDIO_SRC, _do_init);
+
+static void gst_jackaudiosrc_set_property(GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_jackaudiosrc_get_property(GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstCaps *gst_jackaudiosrc_getcaps(GstBaseSrc * bsrc);
+static GstRingBuffer *gst_jackaudiosrc_create_ringbuffer(GstBaseAudioSrc *src);
+
+/* GObject vmethod implementations */
+
+static void 
+gst_jackaudiosrc_base_init(gpointer gclass)
+{
+  static GstElementDetails gst_jackaudiosrc_details = {
+    "Audio Source (Jack)",
+    "Source/Audio",
+    "Input from Jack",
+    "Tristan Matthews <tristan@sat.qc.ca>"
+  };
+  GstElementClass *element_class = GST_ELEMENT_CLASS(gclass);
+
+  gst_element_class_add_pad_template(element_class,
+      gst_static_pad_template_get(&src_factory));
+  gst_element_class_set_details(element_class, &gst_jackaudiosrc_details);
+}
+
+/* initialize the jackaudiosrc's class */
+static void 
+gst_jackaudiosrc_class_init(GstJackAudioSrcClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+  GstBaseSrcClass *gstbasesrc_class;
+  GstBaseAudioSrcClass *gstbaseaudiosrc_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  gstbasesrc_class = (GstBaseSrcClass *) klass;
+  gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
+
+  gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_jackaudiosrc_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_jackaudiosrc_get_property);
+
+  g_object_class_install_property(gobject_class, PROP_CONNECT,
+      g_param_spec_enum("connect", "Connect",
+        "Specify how the input ports will be connected",
+        GST_TYPE_JACK_CONNECT, DEFAULT_PROP_CONNECT, G_PARAM_READWRITE));
+
+  g_object_class_install_property(gobject_class, PROP_SERVER,
+      g_param_spec_string("server", "Server",
+        "The Jack server to connect to (NULL = default)",
+        DEFAULT_PROP_SERVER, G_PARAM_READWRITE));
+
+  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR(gst_jackaudiosrc_getcaps);
+  gstbaseaudiosrc_class->create_ringbuffer =
+    GST_DEBUG_FUNCPTR(gst_jackaudiosrc_create_ringbuffer);
+
+  /* ref class from a thread-safe context to work around missing bit of
+   * thread-safety in GObject */
+  g_type_class_ref(GST_TYPE_JACK_RING_BUFFER);
+
+  gst_jack_audio_client_init();
+}
+
+/* initialize the new element
+ * instantiate pads and add them to element
+ * set pad calback functions
+ * initialize instance structure
+ */
+static void 
+gst_jackaudiosrc_init(GstJackAudioSrc * src, GstJackAudioSrcClass * gclass)
+{
+  //gst_base_src_set_live(GST_BASE_SRC (src), TRUE);
+  src->connect = DEFAULT_PROP_CONNECT;
+  src->server = g_strdup(DEFAULT_PROP_SERVER);
+  src->ports = NULL;
+  src->port_count = 0;
+}
+
+static void 
+gst_jackaudiosrc_set_property(GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstJackAudioSrc *src = GST_JACK_AUDIO_SRC(object);
+
+  switch (prop_id) 
+  {
+    case PROP_CONNECT:
+      src->connect = g_value_get_enum(value);
+      break;
+    case PROP_SERVER:
+      g_free(src->server);
+      src->server = g_value_dup_string(value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+      break;
+  }
+}
+
+static void 
+gst_jackaudiosrc_get_property(GObject * object, guint prop_id, 
+    GValue * value, GParamSpec * pspec)
+{
+  GstJackAudioSrc *src = GST_JACK_AUDIO_SRC(object);
+
+  switch (prop_id) 
+  {
+    case PROP_CONNECT:
+      g_value_set_enum(value, src->connect);
+      break;
+    case PROP_SERVER:
+      g_value_set_string(value, src->server);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstCaps *
+gst_jackaudiosrc_getcaps(GstBaseSrc * bsrc)
+{
+  GstJackAudioSrc *src = GST_JACK_AUDIO_SRC(bsrc);
+  const char **ports;
+  gint min, max;
+  gint rate;
+  jack_client_t *client;
+
+  if (src->client == NULL)
+    goto no_client;
+
+  client = gst_jack_audio_client_get_client(src->client);
+
+  if (src->connect == GST_JACK_CONNECT_AUTO) {
+    /* get a port count, this is the number of channels we can automatically
+     * connect. */
+    ports = jack_get_ports(client, NULL, NULL,
+        JackPortIsPhysical | JackPortIsOutput);
+    max = 0;
+    if (ports != NULL) {
+      for (; ports[max]; max++);
+
+      free(ports);
+    } else
+      max = 0;
+  } else {
+    /* we allow any number of pads, something else is going to connect the
+     * pads. */
+    max = G_MAXINT;
+  }
+  min = MIN(1, max);
+
+  rate = jack_get_sample_rate(client);
+
+  GST_DEBUG_OBJECT(src, "got %d-%d ports, samplerate: %d", min, max, rate);
+
+  if (!src->caps) {
+    src->caps = gst_caps_new_simple("audio/x-raw-float",
+        "endianness", G_TYPE_INT, G_BYTE_ORDER,
+        "width", G_TYPE_INT, 32,
+        "rate", G_TYPE_INT, rate,
+        "channels", GST_TYPE_INT_RANGE, min, max, NULL);
+  }
+  GST_INFO_OBJECT(src, "returning caps %" GST_PTR_FORMAT, src->caps);
+
+  return gst_caps_ref(src->caps);
+
+  /* ERRORS */
+no_client:
+  {
+    GST_DEBUG_OBJECT(src, "device not open, using template caps");
+    /* base class will get template caps for us when we return NULL */
+    return NULL;
+  }
+}
+
+static GstRingBuffer *
+gst_jackaudiosrc_create_ringbuffer(GstBaseAudioSrc * src)
+{
+  GstRingBuffer *buffer;
+
+  buffer = g_object_new(GST_TYPE_JACK_RING_BUFFER, NULL);
+  GST_DEBUG_OBJECT(src, "created ringbuffer @%p", buffer);
+
+  return buffer;
+}
+
Index: jack/gstjackaudiosrc.h
===================================================================
RCS file: jack/gstjackaudiosrc.h
diff -N jack/gstjackaudiosrc.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jack/gstjackaudiosrc.h	4 Aug 2008 21:38:39 -0000
@@ -0,0 +1,94 @@
+/* GStreamer
+ * Copyright (C) 2008 Tristan Matthews <tristan@sat.qc.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_JACK_AUDIO_SRC_H__
+#define __GST_JACK_AUDIO_SRC_H__
+
+#include <jack/jack.h>
+
+#include <gst/gst.h>
+#include <gst/audio/gstaudiosrc.h>
+
+#include "gstjackaudioclient.h"
+#include "gstjack.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_JACK_AUDIO_SRC             (gst_jackaudiosrc_get_type())
+#define GST_JACK_AUDIO_SRC(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_JACK_AUDIO_SRC,GstJackAudioSrc))
+#define GST_JACK_AUDIO_SRC_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_JACK_AUDIO_SRC,GstJackAudioSrcClass))
+#define GST_IS_JACK_AUDIO_SRC(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_JACK_AUDIO_SRC))
+#define GST_IS_JACK_AUDIO_SRC_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_JACK_AUDIO_SRC))
+
+typedef struct _GstJackAudioSrc GstJackAudioSrc;
+typedef struct _GstJackAudioSrcClass GstJackAudioSrcClass;
+
+struct _GstJackAudioSrc
+{
+    GstBaseAudioSrc src;
+
+    /*< private >*/
+    /* cached caps */
+    GstCaps         *caps;
+
+    /* properties */
+    GstJackConnect connect;
+    gchar           *server;
+
+    /* our client */
+    GstJackAudioClient *client;
+
+    /* our ports */
+    jack_port_t    **ports;
+    int port_count;
+};
+
+struct _GstJackAudioSrcClass
+{
+    GstBaseAudioSrcClass parent_class;
+};
+
+GType gst_jackaudiosrc_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_JACK_AUDIO_SRC_H__ */
Index: jack/gstjackringbuffer.h
===================================================================
RCS file: jack/gstjackringbuffer.h
diff -N jack/gstjackringbuffer.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ jack/gstjackringbuffer.h	4 Aug 2008 21:38:39 -0000
@@ -0,0 +1,87 @@
+/*
+ * GStreamer
+ * Copyright (C) 2006 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2008 Tristan Matthews <tristan@sat.qc.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#define GST_TYPE_JACK_RING_BUFFER               (gst_jack_ring_buffer_get_type())
+#define GST_JACK_RING_BUFFER(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_JACK_RING_BUFFER,GstJackRingBuffer))
+#define GST_JACK_RING_BUFFER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_JACK_RING_BUFFER,GstJackRingBufferClass))
+#define GST_JACK_RING_BUFFER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_JACK_RING_BUFFER,GstJackRingBufferClass))
+#define GST_JACK_RING_BUFFER_CAST(obj)          ((GstJackRingBuffer *)obj)
+#define GST_IS_JACK_RING_BUFFER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_JACK_RING_BUFFER))
+#define GST_IS_JACK_RING_BUFFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_JACK_RING_BUFFER))
+
+typedef struct _GstJackRingBuffer GstJackRingBuffer;
+typedef struct _GstJackRingBufferClass GstJackRingBufferClass;
+
+struct _GstJackRingBuffer
+{
+  GstRingBuffer object;
+
+  gint sample_rate;
+  gint buffer_size;
+  gint channels;
+};
+
+struct _GstJackRingBufferClass
+{
+  GstRingBufferClass parent_class;
+};
+
+static void gst_jack_ring_buffer_class_init(GstJackRingBufferClass * klass);
+static void gst_jack_ring_buffer_init(GstJackRingBuffer * ringbuffer,
+    GstJackRingBufferClass * klass);
+static void gst_jack_ring_buffer_dispose(GObject * object);
+static void gst_jack_ring_buffer_finalize(GObject * object);
+
+static GstRingBufferClass *ring_parent_class = NULL;
+
+static gboolean gst_jack_ring_buffer_open_device(GstRingBuffer * buf);
+static gboolean gst_jack_ring_buffer_close_device(GstRingBuffer * buf);
+static gboolean gst_jack_ring_buffer_acquire(GstRingBuffer * buf,GstRingBufferSpec * spec);
+static gboolean gst_jack_ring_buffer_release(GstRingBuffer * buf);
+static gboolean gst_jack_ring_buffer_start(GstRingBuffer * buf);
+static gboolean gst_jack_ring_buffer_pause(GstRingBuffer * buf);
+static gboolean gst_jack_ring_buffer_stop(GstRingBuffer * buf);
+static guint gst_jack_ring_buffer_delay(GstRingBuffer * buf);
+
Comment 10 Tristan Matthews 2008-08-04 21:52:00 UTC
Created attachment 115858 [details] [review]
patch to gst-plugins-bad/ext/jack that adds jackaudiosrc

removed additional redundant changes to gstjackaudiosink.{c,h}
Comment 11 Stefan Sauer (gstreamer, gtkdoc dev) 2008-08-06 06:09:57 UTC
much better!

had to cd to 'ext' before appying 
cd ext/
patch --dry-run -p0 <../jacksrc-02.diff
btw. meld (meld.sf.net) is a good tool to graphicaly review the changes.

* gstjack.c
  - still changes things for GST_PLUGIN_DEFINE
* gstjackaudiosink.c
  - there's some unwanted change too:
    -gst_jack_ring_buffer_get_type (void)
    +gst_jack_ring_buffer_get_type()
  - there is a #if 0 ... #endif - if its moved elsewhere, please remove
* gstjackaudiosink.h
  - there's some unwanted change too:
    -GType gst_jack_audio_sink_get_type (void);
    +GType gst_jack_audio_sink_get_type ();
* jack/gstjackringbuffer.h
  so this is now the same api, but different implementation in src/sink?
  it would also be an option to add this stuff to gstjack.h then.
  what do you think?

I hope thats the last round. thanks for the good work on this.
Comment 12 Tristan Matthews 2008-08-06 17:27:55 UTC
Moving the contents of gstjackringbuffer.h to gstjack.h has the consequence that all .c files that include gstjack.h have to implement the static functions it declares, or the compiler warns against declared but undefined functions. gstjack.c depends on gstjackaudiosrc.h and gstjackaudiosink.h, which both include gstjack.h for certain declarations. Therefore, if gstjack.h and gstjackringbuffer.h were merged int gstjack.h, gstjack.c won't compile (if -Werror) due to warnings about unimplemented jackringbuffer static functions. the simplest solution IMHO is to just keep the gstjackringbuffer api out of gstjack.h.
Comment 13 Stefan Sauer (gstreamer, gtkdoc dev) 2008-08-06 17:44:33 UTC
Doh, your right - my mistake. Lets keep gstjackringbuffer.h then. Can you do the other small changes?
Comment 14 Tristan Matthews 2008-08-06 18:55:57 UTC
Created attachment 115999 [details] [review]
plugin to gst-plugins-bad that adds jackaudiosrc

Removes redundant changes to gstjackaudiosink.c
Comment 15 Stefan Sauer (gstreamer, gtkdoc dev) 2008-08-07 08:48:36 UTC
2008-08-07  Stefan Kost  <ensonic@users.sf.net>

	patch by: Tristan Matthews <tristan@sat.qc.ca>

	* ext/jack/Makefile.am:
	* ext/jack/gstjack.c:
	* ext/jack/gstjackaudioclient.c:
	* ext/jack/gstjackaudiosink.c:
	* ext/jack/gstjackaudiosink.h:
	* ext/jack/gstjackaudiosrc.c:
	* ext/jack/gstjackaudiosrc.h:
	* ext/jack/gstjackringbuffer.h:
	  Add a jackaudiosrc. Refactor sink slightly for better code reuse.
	  Fixes #545197.