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 | 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> | 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> | 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> | 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> | 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> | 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> | 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> | 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> | 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. | * NetJack2 code : better error checkout, method renaming. | ||||
| 2009-06-17 Stephane Letz <letz@grame.fr> | 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 "JackConstants.h" | ||||
| #include "JackDriverLoader.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 | 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: | 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; | union jackctl_parameter_value value; | ||||
| copyright(stdout); | 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); | server_ctl = jackctl_server_create(NULL, NULL); | ||||
| #endif | |||||
| if (server_ctl == NULL) { | if (server_ctl == NULL) { | ||||
| fprintf(stderr, "Failed to create server object\n"); | fprintf(stderr, "Failed to create server object\n"); | ||||
| return -1; | return -1; | ||||
| @@ -22,74 +22,107 @@ | |||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <assert.h> | #include <assert.h> | ||||
| #include <stdint.h> | |||||
| #include "reserve.h" | #include "reserve.h" | ||||
| #include "audio_reserve.h" | #include "audio_reserve.h" | ||||
| #include "JackError.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() | SERVER_EXPORT int audio_reservation_init() | ||||
| { | { | ||||
| DBusError error; | DBusError error; | ||||
| dbus_error_init(&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); | jack_error("Failed to connect to session bus for device reservation %s\n", error.message); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| jack_info("audio_reservation_init"); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| SERVER_EXPORT int audio_reservation_finish() | 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; | 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", | "Jack audio server", | ||||
| INT32_MAX, | INT32_MAX, | ||||
| NULL, | NULL, | ||||
| &error)) < 0) { | &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__ | #define __audio_reserve__ | ||||
| #include "JackCompilerDeps.h" | #include "JackCompilerDeps.h" | ||||
| #include <stdbool.h> | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| extern "C" { | extern "C" { | ||||
| @@ -28,8 +29,8 @@ extern "C" { | |||||
| SERVER_EXPORT int audio_reservation_init(); | SERVER_EXPORT int audio_reservation_init(); | ||||
| SERVER_EXPORT int audio_reservation_finish(); | 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(); | SERVER_EXPORT void audio_reserve_loop(); | ||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| @@ -280,9 +280,18 @@ jack_controller_switch_master( | |||||
| return TRUE; | 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 | static | ||||
| bool | bool | ||||
| @@ -291,13 +300,8 @@ on_device_acquire(const char * device_name) | |||||
| int ret; | int ret; | ||||
| DBusError error; | DBusError error; | ||||
| if (g_reserved_device_valid) { | |||||
| jack_error("Ignoring reservation for more than one device (acquire)"); | |||||
| return false; | |||||
| } | |||||
| ret = rd_acquire( | ret = rd_acquire( | ||||
| &g_reserved_device, | |||||
| &g_reserved_device[g_device_count].reserved_device, | |||||
| g_connection, | g_connection, | ||||
| device_name, | device_name, | ||||
| "Jack audio server", | "Jack audio server", | ||||
| @@ -310,10 +314,9 @@ on_device_acquire(const char * device_name) | |||||
| return false; | 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); | jack_info("Acquired audio card %s", device_name); | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -321,15 +324,22 @@ static | |||||
| void | void | ||||
| on_device_release(const char * device_name) | 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 * | void * | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <assert.h> | #include <assert.h> | ||||
| #include <stdint.h> | |||||
| #include "reserve.h" | #include "reserve.h" | ||||
| @@ -120,7 +121,7 @@ static DBusHandlerResult object_handler( | |||||
| dbus_error_init(&error); | dbus_error_init(&error); | ||||
| d = userdata; | |||||
| d = (rd_device*)userdata; | |||||
| assert(d->ref >= 1); | assert(d->ref >= 1); | ||||
| if (dbus_message_is_method_call( | if (dbus_message_is_method_call( | ||||
| @@ -296,7 +297,7 @@ static DBusHandlerResult filter_handler( | |||||
| dbus_error_init(&error); | dbus_error_init(&error); | ||||
| d = userdata; | |||||
| d = (rd_device*)userdata; | |||||
| if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameLost")) { | if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameLost")) { | ||||
| const char *name; | const char *name; | ||||
| @@ -352,10 +353,7 @@ oom: | |||||
| return DBUS_HANDLER_RESULT_NEED_MEMORY; | return DBUS_HANDLER_RESULT_NEED_MEMORY; | ||||
| } | } | ||||
| static const struct DBusObjectPathVTable vtable ={ | |||||
| .message_function = object_handler | |||||
| }; | |||||
| static DBusObjectPathVTable vtable; | |||||
| int rd_acquire( | int rd_acquire( | ||||
| rd_device **_d, | rd_device **_d, | ||||
| @@ -372,6 +370,8 @@ int rd_acquire( | |||||
| DBusMessage *m = NULL, *reply = NULL; | DBusMessage *m = NULL, *reply = NULL; | ||||
| dbus_bool_t good; | dbus_bool_t good; | ||||
| vtable.message_function = object_handler; | |||||
| if (!error) | if (!error) | ||||
| error = &_error; | error = &_error; | ||||
| @@ -389,7 +389,7 @@ int rd_acquire( | |||||
| if (!request_cb && priority != INT32_MAX) | if (!request_cb && priority != INT32_MAX) | ||||
| return -EINVAL; | return -EINVAL; | ||||
| if (!(d = calloc(sizeof(rd_device), 1))) | |||||
| if (!(d = (rd_device *)calloc(sizeof(rd_device), 1))) | |||||
| return -ENOMEM; | return -ENOMEM; | ||||
| d->ref = 1; | d->ref = 1; | ||||
| @@ -408,13 +408,13 @@ int rd_acquire( | |||||
| d->connection = dbus_connection_ref(connection); | d->connection = dbus_connection_ref(connection); | ||||
| d->request_cb = request_cb; | 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; | r = -ENOMEM; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name); | 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; | r = -ENOMEM; | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| @@ -28,6 +28,13 @@ | |||||
| #include <dbus/dbus.h> | #include <dbus/dbus.h> | ||||
| #include <inttypes.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; | typedef struct rd_device rd_device; | ||||
| /* Prototype for a function that is called whenever someone else wants | /* Prototype for a function that is called whenever someone else wants | ||||
| @@ -40,6 +47,10 @@ typedef int (*rd_request_cb_t)( | |||||
| rd_device *d, | 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. */ | 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 | /* 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 | * style return value on error. The DBus error might be set as well if | ||||
| * the error was caused D-Bus. */ | * the error was caused D-Bus. */ | ||||
| @@ -66,4 +77,8 @@ void rd_set_userdata(rd_device *d, void *userdata); | |||||
| * userdata was set. */ | * userdata was set. */ | ||||
| void* rd_get_userdata(rd_device *d); | void* rd_get_userdata(rd_device *d); | ||||
| #ifdef __cplusplus | |||||
| } /* extern "C" */ | |||||
| #endif | |||||
| #endif | #endif | ||||
| @@ -31,10 +31,14 @@ def build(bld): | |||||
| jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus'] | jackd.includes = ['../linux', '../posix', '../common/jack', '../common', '../dbus'] | ||||
| jackd.defines = 'HAVE_CONFIG_H' | jackd.defines = 'HAVE_CONFIG_H' | ||||
| jackd.source = ['../common/Jackdmp.cpp'] | 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.uselib_local = 'serverlib' | ||||
| jackd.target = 'jackd' | jackd.target = 'jackd' | ||||
| create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') | create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') | ||||
| alsa_driver_src = ['alsa/JackAlsaDriver.cpp', | alsa_driver_src = ['alsa/JackAlsaDriver.cpp', | ||||