From 56f4d13ecb2b1cd9f8fd5786b769c9788c2b1b7f Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 16 Jul 2009 10:32:15 +0000 Subject: [PATCH] In combined --dbus and --classic compilation ode, use PulseAudio acquire/release code. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3603 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 44 ++++++++++---------- common/Jackdmp.cpp | 10 ++++- dbus/audio_reserve.c | 95 +++++++++++++++++++++++++++++--------------- dbus/audio_reserve.h | 5 ++- dbus/controller.c | 48 +++++++++++++--------- dbus/reserve.c | 18 ++++----- dbus/reserve.h | 15 +++++++ linux/wscript | 8 +++- 8 files changed, 159 insertions(+), 84 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5bcf2031..721bd42f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,43 +23,47 @@ Paul Davis --------------------------- Jackdmp changes log ---------------------------- - +--------------------------- + +2009-07-17 Stephane Letz + + * In combined --dbus and --classic compilation ode, use PulseAudio acquire/release code. + 2009-07-16 Stephane Letz - * Rename JackDriver::Init method to JackDriver::Initialize (to avoid confusion with JackThread::Init method). - * Update Solaris boomer driver. - * Report some cleanup and documentation improvements done on JACK1 timing functions. - + * Rename JackDriver::Init method to JackDriver::Initialize (to avoid confusion with JackThread::Init method). + * Update Solaris boomer driver. + * Report some cleanup and documentation improvements done on JACK1 timing functions. + 2009-07-11 Stephane Letz - * Raise drivers time out used in synchronous mode. - + * Raise drivers time out used in synchronous mode. + 2009-07-09 Stephane Letz - * Use __attribute__((__packed__)) again, more fixes for 64/32 mixed mode. - * Torben Hohn changes for 64/32 mixed mode in wscripts. - * Add compile time option for maximum ports per application. - + * Use __attribute__((__packed__)) again, more fixes for 64/32 mixed mode. + * Torben Hohn changes for 64/32 mixed mode in wscripts. + * Add compile time option for maximum ports per application. + 2009-07-07 Stephane Letz - * Use __attribute__((__aligned__(32))) instead of __attribute__((__packed__)) for 64/32 mixed mode. - + * Use __attribute__((__aligned__(32))) instead of __attribute__((__packed__)) for 64/32 mixed mode. + 2009-07-03 Stephane Letz - * Another Tim Bechmann memops.c optimization patch. - + * Another Tim Bechmann memops.c optimization patch. + 2009-07-01 Stephane Letz - * Tim Bechmann memops.c optimization patch. - + * Tim Bechmann memops.c optimization patch. + 2009-06-30 Stephane Letz - * Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. + * Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. 2009-06-19 Stephane Letz - * Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. + * Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. * NetJack2 code : better error checkout, method renaming. 2009-06-17 Stephane Letz diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index a73878c5..7b7859b1 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -32,6 +32,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackConstants.h" #include "JackDriverLoader.h" +#if defined(JACK_DBUS) && defined(__linux__) +#include +#include "audio_reserve.h" +#endif + /* This is a simple port of the old jackdmp.cpp file to use the new Jack 2.0 control API. Available options for the server are "hard-coded" in the source. A much better approach would be to use the control API to: @@ -206,8 +211,11 @@ int main(int argc, char* argv[]) union jackctl_parameter_value value; copyright(stdout); - +#if defined(JACK_DBUS) && defined(__linux__) + server_ctl = jackctl_server_create(audio_acquire, audio_release); +#else server_ctl = jackctl_server_create(NULL, NULL); +#endif if (server_ctl == NULL) { fprintf(stderr, "Failed to create server object\n"); return -1; diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c index 00412130..120db64f 100644 --- a/dbus/audio_reserve.c +++ b/dbus/audio_reserve.c @@ -22,74 +22,107 @@ #include #include #include +#include #include "reserve.h" #include "audio_reserve.h" #include "JackError.h" -static DBusConnection* connection = NULL; +#define DEVICE_MAX 2 + +typedef struct reserved_audio_device { + + char device_name[64]; + rd_device * reserved_device; + +} reserved_audio_device; + +static DBusConnection* gConnection = NULL; +static reserved_audio_device gReservedDevice[DEVICE_MAX]; +static int gReserveCount = 0; SERVER_EXPORT int audio_reservation_init() { DBusError error; - dbus_error_init(&error); - if (!(connection = dbus_bus_get(DBUS_BUS_SESSION, &error))) { + if (!(gConnection = dbus_bus_get(DBUS_BUS_SESSION, &error))) { jack_error("Failed to connect to session bus for device reservation %s\n", error.message); return -1; } + jack_info("audio_reservation_init"); return 0; } SERVER_EXPORT int audio_reservation_finish() { - if (connection) - dbus_connection_unref(connection); + if (gConnection) { + dbus_connection_unref(gConnection); + gConnection = NULL; + jack_info("audio_reservation_finish"); + } return 0; } -SERVER_EXPORT void* audio_acquire(int num) +SERVER_EXPORT bool audio_acquire(const char * device_name) { - DBusError error; - rd_device* device; - char audio_name[32]; - int e; + DBusError error; + int ret; - snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", num); - if ((e = rd_acquire( - &device, - connection, - audio_name, + // Open DBus connection first time + if (gReserveCount == 0) + audio_reservation_init(); + + assert(gReserveCount < DEVICE_MAX); + + if ((ret= rd_acquire( + &gReservedDevice[gReserveCount].reserved_device, + gConnection, + device_name, "Jack audio server", INT32_MAX, NULL, &error)) < 0) { - jack_error("Failed to acquire device name : %s error : %s", audio_name, (error.message ? error.message : strerror(-e))); - return NULL; + jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret))); + return false; } - jack_info("Acquire audio card %s", audio_name); - return (void*)device; + strcpy(gReservedDevice[gReserveCount].device_name, device_name); + gReserveCount++; + jack_info("Acquire audio card %s", device_name); + return true; +} + +SERVER_EXPORT void audio_release(const char * device_name) +{ + int i; + + // Look for corresponding reserved device + for (i = 0; i < DEVICE_MAX; i++) { + if (strcmp(gReservedDevice[i].device_name, device_name) == 0) + break; + } + + if (i < DEVICE_MAX) { + jack_info("Released audio card %s", device_name); + rd_release(gReservedDevice[i].reserved_device); + } else { + jack_error("Audio card %s not found!!", device_name); + } + + // Close DBus connection last time + gReserveCount--; + if (gReserveCount == 0) + audio_reservation_finish(); } SERVER_EXPORT void audio_reserve_loop() { - if (connection) { - while (dbus_connection_read_write_dispatch (connection, -1)) + if (gConnection != NULL) { + while (dbus_connection_read_write_dispatch (gConnection, -1)) ; // empty loop body } } -SERVER_EXPORT void audio_release(void* dev) -{ - rd_device* device = (rd_device*)dev; - if (device) { - jack_info("Release audio card"); - rd_release(device); - } else { - jack_info("No audio card to release..."); - } -} diff --git a/dbus/audio_reserve.h b/dbus/audio_reserve.h index 9a5c34c5..db01f1ab 100644 --- a/dbus/audio_reserve.h +++ b/dbus/audio_reserve.h @@ -20,6 +20,7 @@ #define __audio_reserve__ #include "JackCompilerDeps.h" +#include #ifdef __cplusplus extern "C" { @@ -28,8 +29,8 @@ extern "C" { SERVER_EXPORT int audio_reservation_init(); SERVER_EXPORT int audio_reservation_finish(); -SERVER_EXPORT void* audio_acquire(int num); -SERVER_EXPORT void audio_release(void* dev); +SERVER_EXPORT bool audio_acquire(const char * device_name); +SERVER_EXPORT void audio_release(const char * device_name); SERVER_EXPORT void audio_reserve_loop(); #ifdef __cplusplus diff --git a/dbus/controller.c b/dbus/controller.c index 2a4bea77..17b51fdf 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -280,9 +280,18 @@ jack_controller_switch_master( return TRUE; } -/* TODO: use contianer with unique entries (dict) */ -bool g_reserved_device_valid = false; -static rd_device * g_reserved_device; +#define DEVICE_MAX 2 + +typedef struct reserved_audio_device { + + char device_name[64]; + rd_device * reserved_device; + +} reserved_audio_device; + + +int g_device_count = 0; +static reserved_audio_device g_reserved_device[DEVICE_MAX]; static bool @@ -291,13 +300,8 @@ on_device_acquire(const char * device_name) int ret; DBusError error; - if (g_reserved_device_valid) { - jack_error("Ignoring reservation for more than one device (acquire)"); - return false; - } - ret = rd_acquire( - &g_reserved_device, + &g_reserved_device[g_device_count].reserved_device, g_connection, device_name, "Jack audio server", @@ -310,10 +314,9 @@ on_device_acquire(const char * device_name) return false; } - g_reserved_device_valid = true; - + strcpy(g_reserved_device[g_device_count].device_name, device_name); + g_device_count++; jack_info("Acquired audio card %s", device_name); - return true; } @@ -321,15 +324,22 @@ static void on_device_release(const char * device_name) { - if (!g_reserved_device_valid) { - jack_error("Ignoring reservation for more than one device(release)"); + int i; + + // Look for corresponding reserved device + for (i = 0; i < DEVICE_MAX; i++) { + if (strcmp(g_reserved_device[i].device_name, device_name) == 0) + break; + } + + if (i < DEVICE_MAX) { + jack_info("Released audio card %s", device_name); + rd_release(g_reserved_device[i].reserved_device); + } else { + jack_error("Audio card %s not found!!", device_name); } - rd_release(g_reserved_device); - - g_reserved_device_valid = false; - - jack_info("Released audio card %s", device_name); + g_device_count--; } void * diff --git a/dbus/reserve.c b/dbus/reserve.c index 9a9591d2..bc698a6a 100644 --- a/dbus/reserve.c +++ b/dbus/reserve.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "reserve.h" @@ -120,7 +121,7 @@ static DBusHandlerResult object_handler( dbus_error_init(&error); - d = userdata; + d = (rd_device*)userdata; assert(d->ref >= 1); if (dbus_message_is_method_call( @@ -296,7 +297,7 @@ static DBusHandlerResult filter_handler( dbus_error_init(&error); - d = userdata; + d = (rd_device*)userdata; if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameLost")) { const char *name; @@ -352,10 +353,7 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } - -static const struct DBusObjectPathVTable vtable ={ - .message_function = object_handler -}; +static DBusObjectPathVTable vtable; int rd_acquire( rd_device **_d, @@ -372,6 +370,8 @@ int rd_acquire( DBusMessage *m = NULL, *reply = NULL; dbus_bool_t good; + vtable.message_function = object_handler; + if (!error) error = &_error; @@ -389,7 +389,7 @@ int rd_acquire( if (!request_cb && priority != INT32_MAX) return -EINVAL; - if (!(d = calloc(sizeof(rd_device), 1))) + if (!(d = (rd_device *)calloc(sizeof(rd_device), 1))) return -ENOMEM; d->ref = 1; @@ -408,13 +408,13 @@ int rd_acquire( d->connection = dbus_connection_ref(connection); d->request_cb = request_cb; - if (!(d->service_name = malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) { + if (!(d->service_name = (char*)malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) { r = -ENOMEM; goto fail; } sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name); - if (!(d->object_path = malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) { + if (!(d->object_path = (char*)malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) { r = -ENOMEM; goto fail; } diff --git a/dbus/reserve.h b/dbus/reserve.h index b315a08c..6e16a07d 100644 --- a/dbus/reserve.h +++ b/dbus/reserve.h @@ -28,6 +28,13 @@ #include #include +# ifndef INT32_MIN +# define INT32_MIN (-2147483647-1) +# endif +# ifndef INT32_MAX +# define INT32_MAX (2147483647) +# endif + typedef struct rd_device rd_device; /* Prototype for a function that is called whenever someone else wants @@ -40,6 +47,10 @@ typedef int (*rd_request_cb_t)( rd_device *d, int forced); /* Non-zero if an application forcibly took the lock away without asking. If this is the case then the return value of this call is ignored. */ +#ifdef __cplusplus +extern "C" { +#endif + /* Try to lock the device. Returns 0 on success, a negative errno * style return value on error. The DBus error might be set as well if * the error was caused D-Bus. */ @@ -66,4 +77,8 @@ void rd_set_userdata(rd_device *d, void *userdata); * userdata was set. */ void* rd_get_userdata(rd_device *d); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif diff --git a/linux/wscript b/linux/wscript index 087a3165..a181c223 100644 --- a/linux/wscript +++ b/linux/wscript @@ -31,10 +31,14 @@ def build(bld): jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus'] jackd.defines = 'HAVE_CONFIG_H' jackd.source = ['../common/Jackdmp.cpp'] - jackd.uselib = 'PTHREAD DL RT' + if bld.env['IS_LINUX'] and bld.env['BUILD_JACKDBUS']: + jackd.source += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] + jackd.uselib = 'PTHREAD DL RT DBUS-1' + else: + jackd.uselib = 'PTHREAD DL RT' jackd.uselib_local = 'serverlib' jackd.target = 'jackd' - + create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') alsa_driver_src = ['alsa/JackAlsaDriver.cpp',