[SCM] calf/master: + Big Bull: add the ability to monitor port registrations/connections (but not client registrations, yet)

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:37:38 UTC 2013


The following commit has been merged in the master branch:
commit 9f2dfb6f9d611a3d1ede5481ee8c80cd588c933b
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date:   Sat Sep 27 22:30:13 2008 +0000

    + Big Bull: add the ability to monitor port registrations/connections (but not client registrations, yet)
    
    
    git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@307 78b06b96-2940-0410-b7fc-879d825d01d8

diff --git a/bigbull/calfpytools.cpp b/bigbull/calfpytools.cpp
index bb53b0b..06a7629 100644
--- a/bigbull/calfpytools.cpp
+++ b/bigbull/calfpytools.cpp
@@ -1,6 +1,7 @@
 #include <Python.h>
 #include "ttl.h"
 #include "ttldata.h"
+#include <list>
 #include <map>
 #include <iostream>
 #include <fstream>
@@ -12,11 +13,32 @@ struct PyJackPort;
 
 typedef std::map<jack_port_t *, PyJackPort *> PortHandleMap;
 
+struct AsyncOperationInfo
+{
+    enum OpCode { INVALID_OP, PORT_REGISTERED, PORT_UNREGISTERED, PORTS_CONNECTED, PORTS_DISCONNECTED };
+    
+    OpCode opcode;
+    jack_port_id_t port, port2;
+    
+    AsyncOperationInfo() { opcode = INVALID_OP; }
+    AsyncOperationInfo(OpCode _opcode, jack_port_id_t _port, jack_port_id_t _port2 = 0)
+    : opcode(_opcode), port(_port), port2(_port2) {}
+    inline int argc() {
+        if (opcode == PORT_REGISTERED || opcode == PORT_UNREGISTERED) return 1;
+        if (opcode == PORTS_CONNECTED || opcode == PORTS_DISCONNECTED) return 2;
+        return 0;
+    }
+};
+
+typedef std::list<AsyncOperationInfo> PortOperationList;
+
 struct PyJackClient
 {
     PyObject_HEAD
     jack_client_t *client;
     PortHandleMap *port_handle_map;
+    pthread_mutex_t port_op_mutex;
+    PortOperationList *port_op_queue;
 };
 
 static PyTypeObject jackclient_type = {
@@ -40,6 +62,22 @@ static PyTypeObject jackport_type = {
     sizeof(PyJackPort),      /*tp_basicsize*/
 };
 
+static void register_cb(jack_port_id_t port, int registered, void *arg) 
+{
+    PyJackClient *self = (PyJackClient *)arg;
+    pthread_mutex_lock(&self->port_op_mutex);
+    self->port_op_queue->push_back(AsyncOperationInfo(registered ? AsyncOperationInfo::PORT_REGISTERED : AsyncOperationInfo::PORT_UNREGISTERED, port));
+    pthread_mutex_unlock(&self->port_op_mutex);
+}
+
+static void connect_cb(jack_port_id_t port1, jack_port_id_t port2, int connected, void *arg) 
+{
+    PyJackClient *self = (PyJackClient *)arg;
+    pthread_mutex_lock(&self->port_op_mutex);
+    self->port_op_queue->push_back(AsyncOperationInfo(connected ? AsyncOperationInfo::PORTS_CONNECTED : AsyncOperationInfo::PORTS_DISCONNECTED, port1, port2));
+    pthread_mutex_unlock(&self->port_op_mutex);
+}
+
 static PyObject *jackclient_open(PyJackClient *self, PyObject *args)
 {
     const char *name;
@@ -50,7 +88,16 @@ static PyObject *jackclient_open(PyJackClient *self, PyObject *args)
         return NULL;
     
     self->client = jack_client_open(name, (jack_options_t)options, &status);
-    self->port_handle_map = new PortHandleMap;
+    self->port_handle_map = new PortHandleMap;    
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+    pthread_mutex_init(&self->port_op_mutex, &attr);
+    self->port_op_queue = new PortOperationList;
+    
+    jack_set_port_registration_callback(self->client, register_cb, self);
+    jack_set_port_connect_callback(self->client, connect_cb, self);
+    jack_activate(self->client);
     
     return Py_BuildValue("i", status);
 }
@@ -184,6 +231,43 @@ static PyObject *jackclient_connect(PyJackClient *self, PyObject *args)
     }
 }
 
+static PyObject *create_jack_port_by_id(PyJackClient *self, jack_port_id_t id)
+{
+    return create_jack_port(self, jack_port_by_id(self->client, id));
+}
+
+static PyObject *jackclient_get_message(PyJackClient *self, PyObject *args)
+{
+    if (!PyArg_ParseTuple(args, ":get_message"))
+        return NULL;
+    
+    CHECK_CLIENT
+    
+    PyObject *obj = NULL;
+    AsyncOperationInfo info;
+    pthread_mutex_lock(&self->port_op_mutex);
+    if (self->port_op_queue->empty())
+    {
+        obj = Py_None;
+        Py_INCREF(Py_None);
+    }
+    else
+    {
+        info = self->port_op_queue->front();
+        self->port_op_queue->pop_front();
+    }
+    pthread_mutex_unlock(&self->port_op_mutex);
+    if (!obj)
+    {
+        if (info.argc() == 1)
+            obj = Py_BuildValue("iO", info.opcode, create_jack_port_by_id(self, info.port));
+        else
+        if (info.argc() == 2)
+            obj = Py_BuildValue("iOO", info.opcode, create_jack_port_by_id(self, info.port), create_jack_port_by_id(self, info.port2));
+    }
+    return obj;
+}
+
 static PyObject *jackclient_disconnect(PyJackClient *self, PyObject *args)
 {
     char *from_port = NULL, *to_port = NULL;
@@ -212,8 +296,12 @@ static PyObject *jackclient_close(PyJackClient *self, PyObject *args)
     
     CHECK_CLIENT
     
+    jack_deactivate(self->client);
     jack_client_close(self->client);
     self->client = NULL;
+    delete self->port_handle_map;
+    delete self->port_op_queue;
+    pthread_mutex_destroy(&self->port_op_mutex);
     
     Py_INCREF(Py_None);
     return Py_None;
@@ -226,7 +314,8 @@ static PyMethodDef jackclient_methods[] = {
     {"get_port", (PyCFunction)jackclient_get_port, METH_VARARGS, "Create port object from name of existing JACK port"},
     {"get_ports", (PyCFunction)jackclient_get_ports, METH_VARARGS, "Get a list of port names based on specified name, type and flag filters"},
     {"register_port", (PyCFunction)jackclient_register_port, METH_VARARGS, "Register a new port and return an object that represents it"},
-    {"get_cobj", (PyCFunction)jackclient_get_cobj, METH_VARARGS, "Retrieve jack_client_t pointer for the client"},
+    {"get_cobj", (PyCFunction)jackclient_get_cobj, METH_VARARGS, "Retrieve jack_client_t pointer for the client as CObject"},
+    {"get_message", (PyCFunction)jackclient_get_message, METH_VARARGS, "Retrieve next port registration/connection message from the message queue"},
     {"connect", (PyCFunction)jackclient_connect, METH_VARARGS, "Connect two ports with given names"},
     {"disconnect", (PyCFunction)jackclient_disconnect, METH_VARARGS, "Disconnect two ports with given names"},
     {NULL, NULL, 0, NULL}
@@ -268,6 +357,33 @@ static int jackport_dealloc(PyJackPort *self)
 #define CHECK_PORT_CLIENT if (!self->client || !self->client->client) { PyErr_SetString(PyExc_ValueError, "Client not opened"); return NULL; }
 #define CHECK_PORT if (!self->port) { PyErr_SetString(PyExc_ValueError, "The port is not valid"); return NULL; }
 
+static PyObject *jackport_strrepr(PyJackPort *self, int quotes)
+{
+    CHECK_PORT_CLIENT
+    CHECK_PORT
+    
+    int flags = jack_port_flags(self->port);
+    int flags_io = flags & (JackPortIsInput | JackPortIsOutput);
+    return PyString_FromFormat("<calfpytools.JackPort, name=%s%s%s, flags=%s%s%s%s>", 
+        quotes ? "\"" : "",
+        jack_port_name(self->port), 
+        quotes ? "\"" : "",
+        (flags_io == JackPortIsInput) ? "in" : (flags_io == JackPortIsOutput ? "out" : "?"),
+        flags & JackPortIsPhysical ? "|physical" : "",
+        flags & JackPortCanMonitor ? "|can_monitor" : "",
+        flags & JackPortIsTerminal ? "|terminal" : "");
+}
+
+static PyObject *jackport_str(PyJackPort *self)
+{
+    return jackport_strrepr(self, 0);
+}
+
+static PyObject *jackport_repr(PyJackPort *self)
+{
+    return jackport_strrepr(self, 1);
+}
+
 static PyObject *jackport_get_full_name(PyJackPort *self, PyObject *args)
 {
     if (!PyArg_ParseTuple(args, ":get_full_name"))
@@ -478,6 +594,8 @@ PyMODINIT_FUNC initcalfpytools()
     jackport_type.tp_methods = jackport_methods;
     jackport_type.tp_init = (initproc)jackport_init;
     jackport_type.tp_dealloc = (destructor)jackport_dealloc;
+    jackport_type.tp_str = (reprfunc)jackport_str;
+    jackport_type.tp_repr = (reprfunc)jackport_repr;
     if (PyType_Ready(&jackport_type) < 0)
         return;
     
diff --git a/bigbull/test.py b/bigbull/test.py
index dc2125f..dfb3d4c 100755
--- a/bigbull/test.py
+++ b/bigbull/test.py
@@ -44,5 +44,13 @@ print port2.get_connections()
 assert port2.get_connections() == ['system:capture_1']
 client.disconnect("system:capture_1", "system:playback_1")
 assert port2.get_connections() == []
+
+while True:
+    msg = client.get_message()
+    if msg != None:
+        print "Msg = %s" % str(msg)
+    else:
+        #time.sleep(0.1)
+        break
 client.close()
 

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list