git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3603 0c269be4-1314-0410-8aa9-9f06e86f4224tags/v1.9.3
| @@ -23,43 +23,47 @@ Paul Davis | |||
| --------------------------- | |||
| Jackdmp changes log | |||
| --------------------------- | |||
| --------------------------- | |||
| 2009-07-17 Stephane Letz <letz@grame.fr> | |||
| * In combined --dbus and --classic compilation ode, use PulseAudio acquire/release code. | |||
| 2009-07-16 Stephane Letz <letz@grame.fr> | |||
| * 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 <letz@grame.fr> | |||
| * Raise drivers time out used in synchronous mode. | |||
| * Raise drivers time out used in synchronous mode. | |||
| 2009-07-09 Stephane Letz <letz@grame.fr> | |||
| * 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 <letz@grame.fr> | |||
| * 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 <letz@grame.fr> | |||
| * Another Tim Bechmann memops.c optimization patch. | |||
| * Another Tim Bechmann memops.c optimization patch. | |||
| 2009-07-01 Stephane Letz <letz@grame.fr> | |||
| * Tim Bechmann memops.c optimization patch. | |||
| * Tim Bechmann memops.c optimization patch. | |||
| 2009-06-30 Stephane Letz <letz@grame.fr> | |||
| * 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 <letz@grame.fr> | |||
| * 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 <letz@grame.fr> | |||
| @@ -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 <dbus/dbus.h> | |||
| #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; | |||
| @@ -22,74 +22,107 @@ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <stdint.h> | |||
| #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; | |||
| snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", num); | |||
| if ((e = rd_acquire( | |||
| &device, | |||
| connection, | |||
| audio_name, | |||
| DBusError error; | |||
| int ret; | |||
| // 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_reserve_loop() | |||
| SERVER_EXPORT void audio_release(const char * device_name) | |||
| { | |||
| if (connection) { | |||
| while (dbus_connection_read_write_dispatch (connection, -1)) | |||
| ; // empty loop body | |||
| 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_release(void* dev) | |||
| SERVER_EXPORT void audio_reserve_loop() | |||
| { | |||
| rd_device* device = (rd_device*)dev; | |||
| if (device) { | |||
| jack_info("Release audio card"); | |||
| rd_release(device); | |||
| } else { | |||
| jack_info("No audio card to release..."); | |||
| } | |||
| if (gConnection != NULL) { | |||
| while (dbus_connection_read_write_dispatch (gConnection, -1)) | |||
| ; // empty loop body | |||
| } | |||
| } | |||
| @@ -20,6 +20,7 @@ | |||
| #define __audio_reserve__ | |||
| #include "JackCompilerDeps.h" | |||
| #include <stdbool.h> | |||
| #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 | |||
| @@ -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; | |||
| rd_release(g_reserved_device); | |||
| g_reserved_device_valid = false; | |||
| // 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); | |||
| } | |||
| jack_info("Released audio card %s", device_name); | |||
| g_device_count--; | |||
| } | |||
| void * | |||
| @@ -28,6 +28,7 @@ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <assert.h> | |||
| #include <stdint.h> | |||
| #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; | |||
| } | |||
| @@ -28,6 +28,13 @@ | |||
| #include <dbus/dbus.h> | |||
| #include <inttypes.h> | |||
| # 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 | |||
| @@ -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', | |||