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', | |||