Conflicts: common/JackControlAPI.cpptags/v1.9.10
@@ -25,6 +25,14 @@ Paul Davis | |||||
Jackdmp changes log | Jackdmp changes log | ||||
--------------------------- | --------------------------- | ||||
2009-07-07 Stephane Letz <letz@grame.fr> | |||||
* 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. | |||||
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. | ||||
@@ -43,6 +43,7 @@ | |||||
#include "JackLockedEngine.h" | #include "JackLockedEngine.h" | ||||
#include "JackConstants.h" | #include "JackConstants.h" | ||||
#include "JackDriverLoader.h" | #include "JackDriverLoader.h" | ||||
#include "JackServerGlobals.h" | |||||
using namespace Jack; | using namespace Jack; | ||||
@@ -631,7 +632,9 @@ get_realtime_priority_constraint() | |||||
return constraint_ptr; | return constraint_ptr; | ||||
} | } | ||||
EXPORT jackctl_server_t * jackctl_server_create() | |||||
EXPORT jackctl_server_t * jackctl_server_create( | |||||
bool (* on_device_acquire)(const char * device_name), | |||||
void (* on_device_release)(const char * device_name)) | |||||
{ | { | ||||
struct jackctl_server * server_ptr; | struct jackctl_server * server_ptr; | ||||
union jackctl_parameter_value value; | union jackctl_parameter_value value; | ||||
@@ -809,6 +812,9 @@ EXPORT jackctl_server_t * jackctl_server_create() | |||||
goto fail_free_parameters; | goto fail_free_parameters; | ||||
} | } | ||||
JackServerGlobals::on_device_acquire = on_device_acquire; | |||||
JackServerGlobals::on_device_release = on_device_release; | |||||
if (!jackctl_drivers_load(server_ptr)) | if (!jackctl_drivers_load(server_ptr)) | ||||
{ | { | ||||
goto fail_free_parameters; | goto fail_free_parameters; | ||||
@@ -88,7 +88,9 @@ jackctl_wait_signals( | |||||
sigset_t signals); | sigset_t signals); | ||||
EXPORT jackctl_server_t * | EXPORT jackctl_server_t * | ||||
jackctl_server_create(); | |||||
jackctl_server_create( | |||||
bool (* on_device_acquire)(const char * device_name), | |||||
void (* on_device_release)(const char * device_name)); | |||||
EXPORT void | EXPORT void | ||||
jackctl_server_destroy( | jackctl_server_destroy( | ||||
@@ -44,8 +44,8 @@ class SERVER_EXPORT JackTimer | |||||
jack_time_t fCurrentCallback; | jack_time_t fCurrentCallback; | ||||
jack_time_t fNextWakeUp; | jack_time_t fNextWakeUp; | ||||
float fSecondOrderIntegrator; | float fSecondOrderIntegrator; | ||||
bool fInitialized; | |||||
float fFilterCoefficient; /* set once, never altered */ | float fFilterCoefficient; /* set once, never altered */ | ||||
bool fInitialized; | |||||
public: | public: | ||||
@@ -67,7 +67,7 @@ class SERVER_EXPORT JackTimer | |||||
return fCurrentWakeup; | return fCurrentWakeup; | ||||
} | } | ||||
}; | |||||
} POST_PACKED_STRUCTURE; | |||||
/*! | /*! | ||||
\brief A class using the JackAtomicState to manage jack time. | \brief A class using the JackAtomicState to manage jack time. | ||||
@@ -30,6 +30,8 @@ namespace Jack | |||||
JackServer* JackServerGlobals::fInstance; | JackServer* JackServerGlobals::fInstance; | ||||
unsigned int JackServerGlobals::fUserCount; | unsigned int JackServerGlobals::fUserCount; | ||||
bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; | |||||
void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; | |||||
int JackServerGlobals::Start(const char* server_name, | int JackServerGlobals::Start(const char* server_name, | ||||
jack_driver_desc_t* driver_desc, | jack_driver_desc_t* driver_desc, | ||||
@@ -38,6 +38,8 @@ struct SERVER_EXPORT JackServerGlobals | |||||
{ | { | ||||
static JackServer* fInstance; | static JackServer* fInstance; | ||||
static unsigned int fUserCount; | static unsigned int fUserCount; | ||||
static bool (* on_device_acquire)(const char * device_name); | |||||
static void (* on_device_release)(const char * device_name); | |||||
JackServerGlobals(); | JackServerGlobals(); | ||||
~JackServerGlobals(); | ~JackServerGlobals(); | ||||
@@ -208,7 +208,7 @@ int main(int argc, char* argv[]) | |||||
copyright(stdout); | copyright(stdout); | ||||
server_ctl = jackctl_server_create(); | |||||
server_ctl = jackctl_server_create(NULL, NULL); | |||||
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; | ||||
@@ -109,12 +109,17 @@ jackctl_wait_signals( | |||||
/** | /** | ||||
* Call this function to create server object. | * Call this function to create server object. | ||||
* | * | ||||
* @param on_device_acquire - Optional callback to be called before device is acquired. If false is returned, device usage will fail | |||||
* @param on_device_release - Optional callback to be called after device is released. | |||||
* | |||||
* @return server object handle, NULL if creation of server object | * @return server object handle, NULL if creation of server object | ||||
* failed. Successfully created server object must be destroyed with | * failed. Successfully created server object must be destroyed with | ||||
* paired call to ::jackctl_server_destroy | * paired call to ::jackctl_server_destroy | ||||
*/ | */ | ||||
jackctl_server_t * | jackctl_server_t * | ||||
jackctl_server_create(); | |||||
jackctl_server_create( | |||||
bool (* on_device_acquire)(const char * device_name), | |||||
void (* on_device_release)(const char * device_name)); | |||||
/** | /** | ||||
* Call this function to destroy server object. | * Call this function to destroy server object. | ||||
@@ -164,6 +164,32 @@ | |||||
} | } | ||||
#if defined (__SSE2__) && !defined (__sun__) | |||||
/* generates same as _mm_set_ps(1.f, 1.f, 1f., 1f) but faster */ | |||||
static inline __m128 gen_one(void) | |||||
{ | |||||
volatile __m128i x; | |||||
__m128i ones = _mm_cmpeq_epi32(x, x); | |||||
return (__m128)_mm_slli_epi32 (_mm_srli_epi32(ones, 25), 23); | |||||
} | |||||
static inline __m128 clip(__m128 s, __m128 min, __m128 max) | |||||
{ | |||||
return _mm_min_ps(max, _mm_max_ps(s, min)); | |||||
} | |||||
static inline __m128i float_24_sse(__m128 s) | |||||
{ | |||||
const __m128 upper_bound = gen_one(); /* NORMALIZED_FLOAT_MAX */ | |||||
const __m128 lower_bound = _mm_sub_ps(_mm_setzero_ps(), upper_bound); | |||||
__m128 clipped = clip(s, lower_bound, upper_bound); | |||||
__m128 scaled = _mm_mul_ps(clipped, _mm_set1_ps(SAMPLE_24BIT_SCALING)); | |||||
return _mm_cvtps_epi32(scaled); | |||||
} | |||||
#endif | |||||
/* Linear Congruential noise generator. From the music-dsp list | /* Linear Congruential noise generator. From the music-dsp list | ||||
* less random than rand(), but good enough and 10x faster | * less random than rand(), but good enough and 10x faster | ||||
*/ | */ | ||||
@@ -254,7 +280,7 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne | |||||
while (unrolled--) { | while (unrolled--) { | ||||
__m128 in = _mm_load_ps(src); | __m128 in = _mm_load_ps(src); | ||||
__m128 scaled = _mm_mul_ps(in, factor); | __m128 scaled = _mm_mul_ps(in, factor); | ||||
__m128 clipped = _mm_min_ps(int_max, _mm_max_ps(scaled, int_min)); | |||||
__m128 clipped = clip(scaled, int_min, int_max); | |||||
__m128i y = _mm_cvttps_epi32(clipped); | __m128i y = _mm_cvttps_epi32(clipped); | ||||
__m128i shifted = _mm_slli_epi32(y, 8); | __m128i shifted = _mm_slli_epi32(y, 8); | ||||
@@ -264,13 +290,11 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne | |||||
__m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); | __m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); | ||||
_mm_store_ss((float*)dst, (__m128)shifted); | _mm_store_ss((float*)dst, (__m128)shifted); | ||||
dst += dst_skip; | |||||
_mm_store_ss((float*)dst, (__m128)shuffled1); | |||||
dst += dst_skip; | |||||
_mm_store_ss((float*)dst, (__m128)shuffled2); | |||||
dst += dst_skip; | |||||
_mm_store_ss((float*)dst, (__m128)shuffled3); | |||||
dst += dst_skip; | |||||
_mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1); | |||||
_mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2); | |||||
_mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3); | |||||
dst += 4*dst_skip; | |||||
src+= 4; | src+= 4; | ||||
} | } | ||||
@@ -389,8 +413,38 @@ void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned | |||||
void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state) | ||||
{ | { | ||||
int32_t z; | |||||
#if defined (__SSE2__) && !defined (__sun__) | |||||
_MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); | |||||
while (nsamples >= 4) { | |||||
int i; | |||||
int32_t z[4]; | |||||
__m128 samples = _mm_loadu_ps(src); | |||||
__m128i converted = float_24_sse(samples); | |||||
__m128i shuffled1 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(0, 3, 2, 1)); | |||||
__m128i shuffled2 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(1, 0, 3, 2)); | |||||
__m128i shuffled3 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(2, 1, 0, 3)); | |||||
_mm_store_ss((float*)z, (__m128)converted); | |||||
_mm_store_ss((float*)z+1, (__m128)shuffled1); | |||||
_mm_store_ss((float*)z+2, (__m128)shuffled2); | |||||
_mm_store_ss((float*)z+3, (__m128)shuffled3); | |||||
for (i = 0; i != 4; ++i) { | |||||
#if __BYTE_ORDER == __LITTLE_ENDIAN | |||||
memcpy (dst, z+i, 3); | |||||
#elif __BYTE_ORDER == __BIG_ENDIAN | |||||
memcpy (dst, (float*)((char *)&z + 1)+i, 3); | |||||
#endif | |||||
dst += dst_skip; | |||||
} | |||||
nsamples -= 4; | |||||
src += 4; | |||||
} | |||||
#endif | |||||
int32_t z; | |||||
while (nsamples--) { | while (nsamples--) { | ||||
float_24 (*src, z); | float_24 (*src, z); | ||||
#if __BYTE_ORDER == __LITTLE_ENDIAN | #if __BYTE_ORDER == __LITTLE_ENDIAN | ||||
@@ -401,7 +455,7 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l | |||||
dst += dst_skip; | dst += dst_skip; | ||||
src++; | src++; | ||||
} | } | ||||
} | |||||
} | |||||
void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip) | ||||
{ | { | ||||
@@ -443,7 +497,7 @@ void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned l | |||||
#if defined (__SSE2__) && !defined (__sun__) | #if defined (__SSE2__) && !defined (__sun__) | ||||
const __m128 scaling_block = _mm_set_ps1(scaling); | const __m128 scaling_block = _mm_set_ps1(scaling); | ||||
while (nsamples > 4) { | |||||
while (nsamples >= 4) { | |||||
int x0, x1, x2, x3; | int x0, x1, x2, x3; | ||||
#if __BYTE_ORDER == __LITTLE_ENDIAN | #if __BYTE_ORDER == __LITTLE_ENDIAN | ||||
@@ -180,7 +180,7 @@ def build(bld): | |||||
clientlib.defines = 'HAVE_CONFIG_H' | clientlib.defines = 'HAVE_CONFIG_H' | ||||
clientlib.uselib = uselib | clientlib.uselib = uselib | ||||
clientlib.install_path = '${LIBDIR}' | clientlib.install_path = '${LIBDIR}' | ||||
if bld.env['BUILD_JACKDBUS'] == True: | |||||
if bld.env['BUILD_JACKDBUS'] == True and bld.env['BUILD_JACKD'] == False: | |||||
clientlib.uselib.append('DBUS-1') | clientlib.uselib.append('DBUS-1') | ||||
clientlib.includes = includes | clientlib.includes = includes | ||||
clientlib.name = 'clientlib' | clientlib.name = 'clientlib' | ||||
@@ -29,6 +29,7 @@ | |||||
#include "controller.h" | #include "controller.h" | ||||
#include "controller_internal.h" | #include "controller_internal.h" | ||||
#include "xml.h" | #include "xml.h" | ||||
#include "reserve.h" | |||||
struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] = | struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[] = | ||||
{ | { | ||||
@@ -279,6 +280,58 @@ 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; | |||||
static | |||||
bool | |||||
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_connection, | |||||
device_name, | |||||
"Jack audio server", | |||||
INT32_MAX, | |||||
NULL, | |||||
&error); | |||||
if (ret < 0) | |||||
{ | |||||
jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret))); | |||||
return false; | |||||
} | |||||
g_reserved_device_valid = true; | |||||
jack_info("Acquired audio card %s", device_name); | |||||
return true; | |||||
} | |||||
static | |||||
void | |||||
on_device_release(const char * device_name) | |||||
{ | |||||
if (!g_reserved_device_valid) { | |||||
jack_error("Ignoring reservation for more than one device(release)"); | |||||
} | |||||
rd_release(g_reserved_device); | |||||
g_reserved_device_valid = false; | |||||
jack_info("Released audio card %s", device_name); | |||||
} | |||||
void * | void * | ||||
jack_controller_create( | jack_controller_create( | ||||
DBusConnection *connection) | DBusConnection *connection) | ||||
@@ -303,7 +356,7 @@ jack_controller_create( | |||||
goto fail; | goto fail; | ||||
} | } | ||||
controller_ptr->server = jackctl_server_create(); | |||||
controller_ptr->server = jackctl_server_create(on_device_acquire, on_device_release); | |||||
if (controller_ptr->server == NULL) | if (controller_ptr->server == NULL) | ||||
{ | { | ||||
jack_error("Failed to create server object"); | jack_error("Failed to create server object"); | ||||
@@ -312,5 +312,6 @@ jack_dbus_send_signal( | |||||
#define JACK_CONTROLLER_OBJECT_PATH "/org/jackaudio/Controller" | #define JACK_CONTROLLER_OBJECT_PATH "/org/jackaudio/Controller" | ||||
extern struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[]; | extern struct jack_dbus_interface_descriptor * g_jackcontroller_interfaces[]; | ||||
extern DBusConnection * g_connection; | |||||
#endif /* #ifndef DBUS_H__3DB2458F_44B2_43EA_882A_9F888DF71A88__INCLUDED */ | #endif /* #ifndef DBUS_H__3DB2458F_44B2_43EA_882A_9F888DF71A88__INCLUDED */ |
@@ -59,6 +59,7 @@ def build(bld): | |||||
#'xml_nop.c', | #'xml_nop.c', | ||||
'xml_write_raw.c', | 'xml_write_raw.c', | ||||
'sigsegv.c', | 'sigsegv.c', | ||||
'reserve.c', | |||||
] | ] | ||||
if bld.env['IS_LINUX']: | if bld.env['IS_LINUX']: | ||||
obj.uselib = 'PTHREAD DL RT DBUS-1 EXPAT' | obj.uselib = 'PTHREAD DL RT DBUS-1 EXPAT' | ||||
@@ -167,7 +167,7 @@ int main(int argc, char *argv[]) | |||||
} | } | ||||
} | } | ||||
server = jackctl_server_create(); | |||||
server = jackctl_server_create(NULL, NULL); | |||||
parameters = jackctl_server_get_parameters(server); | parameters = jackctl_server_get_parameters(server); | ||||
/* | /* | ||||
@@ -48,8 +48,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#include "usx2y.h" | #include "usx2y.h" | ||||
#include "generic.h" | #include "generic.h" | ||||
#include "memops.h" | #include "memops.h" | ||||
#include "JackServerGlobals.h" | |||||
#include "audio_reserve.h" | |||||
//#define DEBUG_WAKEUP 1 | //#define DEBUG_WAKEUP 1 | ||||
@@ -104,31 +104,48 @@ JackAlsaDriver::alsa_driver_check_capabilities (alsa_driver_t *driver) | |||||
return 0; | return 0; | ||||
} | } | ||||
int | |||||
JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) | |||||
static | |||||
char * | |||||
get_control_device_name (const char * device_name) | |||||
{ | { | ||||
int err; | |||||
snd_ctl_card_info_t *card_info; | |||||
char * ctl_name; | char * ctl_name; | ||||
regex_t expression; | regex_t expression; | ||||
snd_ctl_card_info_alloca (&card_info); | |||||
regcomp(&expression, "(plug)?hw:[0-9](,[0-9])?", REG_ICASE | REG_EXTENDED); | regcomp(&expression, "(plug)?hw:[0-9](,[0-9])?", REG_ICASE | REG_EXTENDED); | ||||
if (!regexec(&expression, driver->alsa_name_playback, 0, NULL, 0)) { | |||||
if (!regexec(&expression, device_name, 0, NULL, 0)) { | |||||
/* the user wants a hw or plughw device, the ctl name | /* the user wants a hw or plughw device, the ctl name | ||||
* should be hw:x where x is the card number */ | * should be hw:x where x is the card number */ | ||||
char tmp[5]; | char tmp[5]; | ||||
strncpy(tmp, strstr(driver->alsa_name_playback, "hw"), 4); | |||||
strncpy(tmp, strstr(device_name, "hw"), 4); | |||||
tmp[4] = '\0'; | tmp[4] = '\0'; | ||||
jack_log("control device %s", tmp); | |||||
//jack_log("control device %s", tmp); | |||||
ctl_name = strdup(tmp); | ctl_name = strdup(tmp); | ||||
} else { | } else { | ||||
ctl_name = strdup(driver->alsa_name_playback); | |||||
ctl_name = strdup(device_name); | |||||
} | } | ||||
regfree(&expression); | |||||
if (ctl_name == NULL) { | |||||
jack_error("strdup(\"%s\") failed.", ctl_name); | |||||
} | |||||
return ctl_name; | |||||
} | |||||
int | |||||
JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) | |||||
{ | |||||
int err; | |||||
snd_ctl_card_info_t *card_info; | |||||
char * ctl_name; | |||||
snd_ctl_card_info_alloca (&card_info); | |||||
ctl_name = get_control_device_name(driver->alsa_name_playback); | |||||
// XXX: I don't know the "right" way to do this. Which to use | // XXX: I don't know the "right" way to do this. Which to use | ||||
// driver->alsa_name_playback or driver->alsa_name_capture. | // driver->alsa_name_playback or driver->alsa_name_capture. | ||||
if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) { | if ((err = snd_ctl_open (&driver->ctl_handle, ctl_name, 0)) < 0) { | ||||
@@ -145,9 +162,8 @@ JackAlsaDriver::alsa_driver_check_card_type (alsa_driver_t *driver) | |||||
} | } | ||||
driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); | driver->alsa_driver = strdup(snd_ctl_card_info_get_driver (card_info)); | ||||
jack_info("Using ALSA driver %s running on %s", driver->alsa_driver, snd_ctl_card_info_get_longname(card_info)); | |||||
jack_info("Using ALSA driver %s running on card %i - %s", driver->alsa_driver, snd_ctl_card_info_get_card(card_info), snd_ctl_card_info_get_longname(card_info)); | |||||
regfree(&expression); | |||||
free(ctl_name); | free(ctl_name); | ||||
return alsa_driver_check_capabilities (driver); | return alsa_driver_check_capabilities (driver); | ||||
@@ -2143,22 +2159,45 @@ int JackAlsaDriver::Detach() | |||||
return JackAudioDriver::Detach(); | return JackAudioDriver::Detach(); | ||||
} | } | ||||
#if defined(JACK_DBUS) | |||||
static int card_to_num(const char* device) | static int card_to_num(const char* device) | ||||
{ | { | ||||
const char* t; | |||||
int i; | |||||
int err; | |||||
char* ctl_name; | |||||
snd_ctl_card_info_t *card_info; | |||||
snd_ctl_t* ctl_handle; | |||||
int i = -1; | |||||
if ((t = strchr(device, ':'))) | |||||
device = t + 1; | |||||
snd_ctl_card_info_alloca (&card_info); | |||||
if ((i = snd_card_get_index(device)) < 0) { | |||||
i = atoi(device); | |||||
ctl_name = get_control_device_name(device); | |||||
if (ctl_name == NULL) { | |||||
jack_error("get_control_device_name() failed."); | |||||
goto fail; | |||||
} | } | ||||
if ((err = snd_ctl_open (&ctl_handle, ctl_name, 0)) < 0) { | |||||
jack_error ("control open \"%s\" (%s)", ctl_name, | |||||
snd_strerror(err)); | |||||
goto free; | |||||
} | |||||
if ((err = snd_ctl_card_info(ctl_handle, card_info)) < 0) { | |||||
jack_error ("control hardware info \"%s\" (%s)", | |||||
device, snd_strerror (err)); | |||||
goto close; | |||||
} | |||||
i = snd_ctl_card_info_get_card(card_info); | |||||
close: | |||||
snd_ctl_close(ctl_handle); | |||||
free: | |||||
free(ctl_name); | |||||
fail: | |||||
return i; | return i; | ||||
} | } | ||||
#endif | |||||
int JackAlsaDriver::Open(jack_nframes_t nframes, | int JackAlsaDriver::Open(jack_nframes_t nframes, | ||||
jack_nframes_t user_nperiods, | jack_nframes_t user_nperiods, | ||||
@@ -2192,25 +2231,24 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, | |||||
else if (strcmp(midi_driver_name, "raw") == 0) | else if (strcmp(midi_driver_name, "raw") == 0) | ||||
midi = alsa_rawmidi_new((jack_client_t*)this); | midi = alsa_rawmidi_new((jack_client_t*)this); | ||||
#if defined(JACK_DBUS) | |||||
if (audio_reservation_init() < 0) { | |||||
jack_error("Audio device reservation service not available...."); | |||||
} else if (strcmp(capture_driver_name, playback_driver_name) == 0) { // Same device for input and output | |||||
fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); | |||||
if (fReservedCaptureDevice == NULL) { | |||||
jack_error("Error audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); | |||||
} | |||||
} else { | |||||
fReservedCaptureDevice = audio_acquire(card_to_num(capture_driver_name)); | |||||
if (fReservedCaptureDevice == NULL) { | |||||
jack_error("Error capture audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); | |||||
} | |||||
fReservedPlaybackDevice = audio_acquire(card_to_num(playback_driver_name)); | |||||
if (fReservedPlaybackDevice == NULL) { | |||||
jack_error("Error playback audio device %s cannot be acquired, trying to open it anyway...", playback_driver_name); | |||||
} | |||||
if (JackServerGlobals::on_device_acquire != NULL) | |||||
{ | |||||
int capture_card = card_to_num(capture_driver_name); | |||||
int playback_card = card_to_num(playback_driver_name); | |||||
char audio_name[32]; | |||||
snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", capture_card); | |||||
if (!JackServerGlobals::on_device_acquire(audio_name)) { | |||||
jack_error("Audio device %s cannot be acquired, trying to open it anyway...", capture_driver_name); | |||||
} | |||||
if (playback_card != capture_card) { | |||||
snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", playback_card); | |||||
if (!JackServerGlobals::on_device_acquire(audio_name)) { | |||||
jack_error("Audio device %s cannot be acquired, trying to open it anyway...", playback_driver_name); | |||||
} | |||||
} | |||||
} | } | ||||
#endif | |||||
fDriver = alsa_driver_new ("alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name, | fDriver = alsa_driver_new ("alsa_pcm", (char*)playback_driver_name, (char*)capture_driver_name, | ||||
NULL, | NULL, | ||||
@@ -2245,11 +2283,23 @@ int JackAlsaDriver::Close() | |||||
{ | { | ||||
JackAudioDriver::Close(); | JackAudioDriver::Close(); | ||||
alsa_driver_delete((alsa_driver_t*)fDriver); | alsa_driver_delete((alsa_driver_t*)fDriver); | ||||
#if defined(JACK_DBUS) | |||||
audio_release(fReservedCaptureDevice); | |||||
audio_release(fReservedPlaybackDevice); | |||||
audio_reservation_finish(); | |||||
#endif | |||||
if (JackServerGlobals::on_device_release != NULL) | |||||
{ | |||||
char audio_name[32]; | |||||
int capture_card = card_to_num(fCaptureDriverName); | |||||
if (capture_card >= 0) { | |||||
snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", capture_card); | |||||
JackServerGlobals::on_device_release(audio_name); | |||||
} | |||||
int playback_card = card_to_num(fPlaybackDriverName); | |||||
if (playback_card >= 0 && playback_card != capture_card) { | |||||
snprintf(audio_name, sizeof(audio_name) - 1, "Audio%d", playback_card); | |||||
JackServerGlobals::on_device_release(audio_name); | |||||
} | |||||
} | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -40,8 +40,8 @@ class JackAlsaDriver : public JackAudioDriver | |||||
private: | private: | ||||
jack_driver_t* fDriver; | jack_driver_t* fDriver; | ||||
void* fReservedCaptureDevice; | |||||
void* fReservedPlaybackDevice; | |||||
int fReservedCaptureDevice; | |||||
int fReservedPlaybackDevice; | |||||
void alsa_driver_release_channel_dependent_memory(alsa_driver_t *driver); | void alsa_driver_release_channel_dependent_memory(alsa_driver_t *driver); | ||||
int alsa_driver_check_capabilities(alsa_driver_t *driver); | int alsa_driver_check_capabilities(alsa_driver_t *driver); | ||||
@@ -121,8 +121,8 @@ class JackAlsaDriver : public JackAudioDriver | |||||
JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | JackAlsaDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | ||||
: JackAudioDriver(name, alias, engine, table) | : JackAudioDriver(name, alias, engine, table) | ||||
,fDriver(NULL) | ,fDriver(NULL) | ||||
,fReservedCaptureDevice(NULL) | |||||
,fReservedPlaybackDevice(NULL) | |||||
,fReservedCaptureDevice(-1) | |||||
,fReservedPlaybackDevice(-1) | |||||
{} | {} | ||||
virtual ~JackAlsaDriver() | virtual ~JackAlsaDriver() | ||||
{} | {} | ||||
@@ -47,10 +47,6 @@ def build(bld): | |||||
'alsa/hammerfall.c', | 'alsa/hammerfall.c', | ||||
'alsa/ice1712.c' | 'alsa/ice1712.c' | ||||
] | ] | ||||
if bld.env['BUILD_JACKDBUS']: | |||||
alsa_driver_src += ['../dbus/reserve.c', '../dbus/audio_reserve.c'] | |||||
if bld.env['BUILD_DRIVER_ALSA'] == True: | if bld.env['BUILD_DRIVER_ALSA'] == True: | ||||
create_jack_driver_obj(bld, 'alsa', alsa_driver_src, "ALSA") | create_jack_driver_obj(bld, 'alsa', alsa_driver_src, "ALSA") | ||||
@@ -34,7 +34,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#if (__GNUC__< 4) /* Does not seem to work with GCC 3.XX serie */ | #if (__GNUC__< 4) /* Does not seem to work with GCC 3.XX serie */ | ||||
#define POST_PACKED_STRUCTURE | #define POST_PACKED_STRUCTURE | ||||
#elif defined(JACK_32_64) | #elif defined(JACK_32_64) | ||||
#define POST_PACKED_STRUCTURE __attribute__((__packed__)) | |||||
//#define POST_PACKED_STRUCTURE __attribute__((__packed__)) | |||||
#define POST_PACKED_STRUCTURE __attribute__((__aligned__(32))) | |||||
#else | #else | ||||
#define POST_PACKED_STRUCTURE | #define POST_PACKED_STRUCTURE | ||||
#endif | #endif | ||||
@@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
using namespace Jack; | using namespace Jack; | ||||
#if defined(JACK_DBUS) | |||||
#if defined(USE_LIBDBUS_AUTOLAUNCH) | |||||
#include <dbus/dbus.h> | #include <dbus/dbus.h> | ||||
@@ -73,7 +73,7 @@ static int start_server_dbus(const char* server_name) | |||||
return 0; | return 0; | ||||
} | } | ||||
#endif | |||||
#else | |||||
/* Exec the JACK server in this process. Does not return. */ | /* Exec the JACK server in this process. Does not return. */ | ||||
static void start_server_classic_aux(const char* server_name) | static void start_server_classic_aux(const char* server_name) | ||||
@@ -189,13 +189,15 @@ static int start_server_classic(const char* server_name) | |||||
return 0; /* (probably) successful */ | return 0; /* (probably) successful */ | ||||
} | } | ||||
#endif | |||||
static int start_server(const char* server_name, jack_options_t options) | static int start_server(const char* server_name, jack_options_t options) | ||||
{ | { | ||||
if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { | if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { | ||||
return 1; | return 1; | ||||
} | } | ||||
#if defined(JACK_DBUS) | |||||
#if defined(USE_LIBDBUS_AUTOLAUNCH) | |||||
return start_server_dbus(server_name); | return start_server_dbus(server_name); | ||||
#else | #else | ||||
return start_server_classic(server_name); | return start_server_classic(server_name); | ||||
@@ -143,6 +143,8 @@ def configure(conf): | |||||
conf.define('JACKMP', 1) | conf.define('JACKMP', 1) | ||||
if conf.env['BUILD_JACKDBUS'] == True: | if conf.env['BUILD_JACKDBUS'] == True: | ||||
conf.define('JACK_DBUS', 1) | conf.define('JACK_DBUS', 1) | ||||
if conf.env['BUILD_JACKD'] == False: | |||||
conf.define('USE_LIBDBUS_AUTOLAUNCH', 1) | |||||
if conf.env['BUILD_WITH_PROFILE'] == True: | if conf.env['BUILD_WITH_PROFILE'] == True: | ||||
conf.define('JACK_MONITOR', 1) | conf.define('JACK_MONITOR', 1) | ||||
if conf.env['BUILD_WITH_32_64'] == True: | if conf.env['BUILD_WITH_32_64'] == True: | ||||