git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2339 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
@@ -20,6 +20,10 @@ Fernando Lopez-Lezcano | |||||
Jackdmp changes log | Jackdmp changes log | ||||
--------------------------- | --------------------------- | ||||
2008-05-26 Stephane Letz <letz@grame.fr> | |||||
* Merge control branch. | |||||
2008-05-24 Stephane Letz <letz@grame.fr> | 2008-05-24 Stephane Letz <letz@grame.fr> | ||||
* Tim Blechmann RAII idiom patch for JackServer ressource initialization. | * Tim Blechmann RAII idiom patch for JackServer ressource initialization. | ||||
@@ -143,6 +147,10 @@ Fernando Lopez-Lezcano | |||||
* Synchronise transport.h with latest jackd version (Video handling). | * Synchronise transport.h with latest jackd version (Video handling). | ||||
2008-03-19 Stephane Letz <letz@grame.fr> | |||||
* Add jack_port_type_id in jack API. | |||||
2008-03-17 Stephane Letz <letz@grame.fr> | 2008-03-17 Stephane Letz <letz@grame.fr> | ||||
* New jack_server_control client to test notifications when linked to the server library. | * New jack_server_control client to test notifications when linked to the server library. | ||||
@@ -81,6 +81,7 @@ opts.AddOptions( | |||||
BoolOption('BUILD_EXAMPLES', 'Build the example clients in their directory', True), | BoolOption('BUILD_EXAMPLES', 'Build the example clients in their directory', True), | ||||
BoolOption('INSTALL_EXAMPLES', 'Install the example clients in the BINDIR directory', True), | BoolOption('INSTALL_EXAMPLES', 'Install the example clients in the BINDIR directory', True), | ||||
BoolOption('BUILD_DOXYGEN_DOCS', 'Build doxygen documentation', False), | BoolOption('BUILD_DOXYGEN_DOCS', 'Build doxygen documentation', False), | ||||
BoolOption('ENABLE_DBUS', 'Whether to use D-Bus API', False), | |||||
('cc', 'cc', False), | ('cc', 'cc', False), | ||||
('cxx', 'cxx', False), | ('cxx', 'cxx', False), | ||||
('ccflags', 'ccflags', False), | ('ccflags', 'ccflags', False), | ||||
@@ -195,6 +196,7 @@ if env['DEBUG']: | |||||
print '--> Doing a DEBUG build' | print '--> Doing a DEBUG build' | ||||
# TODO: -Werror could be added to, which would force the devs to really remove all the warnings :-) | # TODO: -Werror could be added to, which would force the devs to really remove all the warnings :-) | ||||
env.AppendUnique(CCFLAGS = ['-DDEBUG', '-Wall', '-g']) | env.AppendUnique(CCFLAGS = ['-DDEBUG', '-Wall', '-g']) | ||||
env.AppendUnique(LINKFLAGS = ['-g']) | |||||
else: | else: | ||||
env.AppendUnique(CCFLAGS = ['-O3','-DNDEBUG']) | env.AppendUnique(CCFLAGS = ['-O3','-DNDEBUG']) | ||||
@@ -234,6 +236,8 @@ pkg_config_dir = env['INSTALL_LIBDIR']+"/pkgconfig/" | |||||
env.Install(pkg_config_dir, 'jack.pc') | env.Install(pkg_config_dir, 'jack.pc') | ||||
env.Alias('install', pkg_config_dir) | env.Alias('install', pkg_config_dir) | ||||
env['BINDIR']=env.subst(env['BINDIR']) | |||||
# To have the top_srcdir as the doxygen-script is used from auto* | # To have the top_srcdir as the doxygen-script is used from auto* | ||||
env['top_srcdir'] = env.Dir('.').abspath | env['top_srcdir'] = env.Dir('.').abspath | ||||
@@ -259,6 +263,10 @@ subdirs=['common'] | |||||
if env['PLATFORM'] == 'posix': | if env['PLATFORM'] == 'posix': | ||||
subdirs.append('linux') | subdirs.append('linux') | ||||
if env['ENABLE_DBUS']: | |||||
subdirs.append('linux/dbus') | |||||
env.AppendUnique(CCFLAGS = ['-DJACK_DBUS']) | |||||
# TODO FOR Marc: make macosx/SConscript work right | # TODO FOR Marc: make macosx/SConscript work right | ||||
if env['PLATFORM'] == 'macosx': | if env['PLATFORM'] == 'macosx': | ||||
subdirs.append('macosx') | subdirs.append('macosx') | ||||
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#include "JackGlobals.h" | #include "JackGlobals.h" | ||||
#include "JackTime.h" | #include "JackTime.h" | ||||
#include "JackExports.h" | #include "JackExports.h" | ||||
#include "JackPortType.h" | |||||
#ifdef __APPLE__ | #ifdef __APPLE__ | ||||
#include "JackMachThread.h" | #include "JackMachThread.h" | ||||
@@ -47,6 +48,18 @@ extern "C" | |||||
{ | { | ||||
#endif | #endif | ||||
EXPORT | |||||
void | |||||
jack_get_version( | |||||
int *major_ptr, | |||||
int *minor_ptr, | |||||
int *micro_ptr, | |||||
int *proto_ptr); | |||||
EXPORT | |||||
const char * | |||||
jack_get_version_string(); | |||||
EXPORT jack_client_t * jack_client_open_aux (const char *client_name, | EXPORT jack_client_t * jack_client_open_aux (const char *client_name, | ||||
jack_options_t options, | jack_options_t options, | ||||
jack_status_t *status, va_list ap); | jack_status_t *status, va_list ap); | ||||
@@ -114,6 +127,7 @@ extern "C" | |||||
EXPORT const char * jack_port_short_name (const jack_port_t *port); | EXPORT const char * jack_port_short_name (const jack_port_t *port); | ||||
EXPORT int jack_port_flags (const jack_port_t *port); | EXPORT int jack_port_flags (const jack_port_t *port); | ||||
EXPORT const char * jack_port_type (const jack_port_t *port); | EXPORT const char * jack_port_type (const jack_port_t *port); | ||||
EXPORT jack_port_type_id_t jack_port_type_id (const jack_port_t *port); | |||||
EXPORT int jack_port_is_mine (const jack_client_t *, const jack_port_t *port); | EXPORT int jack_port_is_mine (const jack_client_t *, const jack_port_t *port); | ||||
EXPORT int jack_port_connected (const jack_port_t *port); | EXPORT int jack_port_connected (const jack_port_t *port); | ||||
EXPORT int jack_port_connected_to (const jack_port_t *port, | EXPORT int jack_port_connected_to (const jack_port_t *port, | ||||
@@ -359,6 +373,21 @@ EXPORT const char* jack_port_type(const jack_port_t* port) | |||||
} | } | ||||
} | } | ||||
EXPORT jack_port_type_id_t jack_port_type_id (const jack_port_t *port) | |||||
{ | |||||
#ifdef __CLIENTDEBUG__ | |||||
JackLibGlobals::CheckContext(); | |||||
#endif | |||||
jack_port_id_t myport = (jack_port_id_t)port; | |||||
if (!CheckPort(myport)) { | |||||
jack_error("jack_port_type_id called an incorrect port %ld", myport); | |||||
return 0; | |||||
} else { | |||||
JackGraphManager* manager = GetGraphManager(); | |||||
return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0); | |||||
} | |||||
} | |||||
EXPORT int jack_port_connected(const jack_port_t* port) | EXPORT int jack_port_connected(const jack_port_t* port) | ||||
{ | { | ||||
#ifdef __CLIENTDEBUG__ | #ifdef __CLIENTDEBUG__ | ||||
@@ -1686,3 +1715,25 @@ EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack | |||||
return my_status; | return my_status; | ||||
} | } | ||||
} | } | ||||
EXPORT | |||||
void | |||||
jack_get_version( | |||||
int *major_ptr, | |||||
int *minor_ptr, | |||||
int *micro_ptr, | |||||
int *proto_ptr) | |||||
{ | |||||
// FIXME: We need these comming from build system | |||||
*major_ptr = 0; | |||||
*minor_ptr = 0; | |||||
*micro_ptr = 0; | |||||
*proto_ptr = 0; | |||||
} | |||||
EXPORT | |||||
const char * | |||||
jack_get_version_string() | |||||
{ | |||||
return VERSION; | |||||
} |
@@ -21,7 +21,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#define __JackAtomicArrayState__ | #define __JackAtomicArrayState__ | ||||
#include "JackAtomic.h" | #include "JackAtomic.h" | ||||
#include "JackError.h" | |||||
#include <string.h> // for memcpy | #include <string.h> // for memcpy | ||||
namespace Jack | namespace Jack | ||||
@@ -136,7 +135,6 @@ class JackAtomicArrayState | |||||
JackAtomicArrayState() | JackAtomicArrayState() | ||||
{ | { | ||||
jack_log("JackAtomicArrayState constructor"); | |||||
Counter1(fCounter) = 0; | Counter1(fCounter) = 0; | ||||
} | } | ||||
@@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#define __JackChannel__ | #define __JackChannel__ | ||||
#include "types.h" | #include "types.h" | ||||
#include "JackError.h" | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
@@ -354,7 +354,7 @@ void JackConnectionManager::DirectDisconnect(int ref1, int ref2) | |||||
bool JackConnectionManager::IsDirectConnection(int ref1, int ref2) const | bool JackConnectionManager::IsDirectConnection(int ref1, int ref2) const | ||||
{ | { | ||||
assert(ref1 >= 0 && ref2 >= 0); | assert(ref1 >= 0 && ref2 >= 0); | ||||
return fConnectionRef.GetItemCount(ref1, ref2); | |||||
return (fConnectionRef.GetItemCount(ref1, ref2) > 0); | |||||
} | } | ||||
/*! | /*! | ||||
@@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#include "JackConstants.h" | #include "JackConstants.h" | ||||
#include "JackActivationCount.h" | #include "JackActivationCount.h" | ||||
#include "JackError.h" | |||||
#include <assert.h> | #include <assert.h> | ||||
namespace Jack | namespace Jack | ||||
@@ -48,6 +48,8 @@ namespace Jack | |||||
#define LOOPBACK_DRIVER_REFNUM 2 // Loopback driver is initialized third, it will get the refnum 2 | #define LOOPBACK_DRIVER_REFNUM 2 // Loopback driver is initialized third, it will get the refnum 2 | ||||
#define REAL_REFNUM LOOPBACK_DRIVER_REFNUM + 1 // Real clients start at LOOPBACK_DRIVER_REFNUM + 1 | #define REAL_REFNUM LOOPBACK_DRIVER_REFNUM + 1 // Real clients start at LOOPBACK_DRIVER_REFNUM + 1 | ||||
#define JACK_DEFAULT_SERVER_NAME "default" | |||||
#ifdef WIN32 | #ifdef WIN32 | ||||
#define jack_server_dir "server" | #define jack_server_dir "server" | ||||
#define jack_client_dir "client" | #define jack_client_dir "client" | ||||
@@ -36,6 +36,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#include <dirent.h> | #include <dirent.h> | ||||
#endif | #endif | ||||
#include <errno.h> | |||||
jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver_t * driver); | |||||
static void | static void | ||||
jack_print_driver_options (jack_driver_desc_t * desc, FILE *file) | jack_print_driver_options (jack_driver_desc_t * desc, FILE *file) | ||||
{ | { | ||||
@@ -222,6 +226,147 @@ jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSL | |||||
return 0; | return 0; | ||||
} | } | ||||
EXPORT int | |||||
jackctl_parse_driver_params (jackctl_driver *driver_ptr, int argc, char* argv[]) | |||||
{ | |||||
struct option * long_options; | |||||
char * options, * options_ptr; | |||||
unsigned long i; | |||||
int opt; | |||||
JSList * node_ptr; | |||||
jackctl_parameter_t * param; | |||||
union jackctl_parameter_value value; | |||||
if (argc <= 1) | |||||
return 0; | |||||
const JSList * driver_params = jackctl_driver_get_parameters(driver_ptr); | |||||
if (driver_params == NULL) | |||||
return 1; | |||||
jack_driver_desc_t * desc = jackctl_driver_get_desc(driver_ptr); | |||||
/* check for help */ | |||||
if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { | |||||
if (argc > 2) { | |||||
for (i = 0; i < desc->nparams; i++) { | |||||
if (strcmp (desc->params[i].name, argv[2]) == 0) { | |||||
jack_print_driver_param_usage (desc, i, stdout); | |||||
return 1; | |||||
} | |||||
} | |||||
fprintf (stderr, "jackd: unknown option '%s' " | |||||
"for driver '%s'\n", argv[2], | |||||
desc->name); | |||||
} | |||||
printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name); | |||||
jack_print_driver_options (desc, stdout); | |||||
return 1; | |||||
} | |||||
/* set up the stuff for getopt */ | |||||
options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char)); | |||||
long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option)); | |||||
options_ptr = options; | |||||
for (i = 0; i < desc->nparams; i++) { | |||||
sprintf (options_ptr, "%c::", desc->params[i].character); | |||||
options_ptr += 3; | |||||
long_options[i].name = desc->params[i].name; | |||||
long_options[i].flag = NULL; | |||||
long_options[i].val = desc->params[i].character; | |||||
long_options[i].has_arg = optional_argument; | |||||
} | |||||
/* create the params */ | |||||
optind = 0; | |||||
opterr = 0; | |||||
while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { | |||||
if (opt == ':' || opt == '?') { | |||||
if (opt == ':') { | |||||
fprintf (stderr, "Missing option to argument '%c'\n", optopt); | |||||
} else { | |||||
fprintf (stderr, "Unknownage with option '%c'\n", optopt); | |||||
} | |||||
fprintf (stderr, "Options for driver '%s':\n", desc->name); | |||||
jack_print_driver_options (desc, stderr); | |||||
exit (1); | |||||
} | |||||
node_ptr = (JSList *)driver_params; | |||||
while (node_ptr) { | |||||
param = (jackctl_parameter_t*)node_ptr->data; | |||||
if (opt == jackctl_parameter_get_id(param)) { | |||||
break; | |||||
} | |||||
node_ptr = node_ptr->next; | |||||
} | |||||
if (!optarg && optind < argc && | |||||
strlen(argv[optind]) && | |||||
argv[optind][0] != '-') { | |||||
optarg = argv[optind]; | |||||
} | |||||
if (optarg) { | |||||
switch (jackctl_parameter_get_type(param)) { | |||||
case JackDriverParamInt: | |||||
value.i = atoi (optarg); | |||||
jackctl_parameter_set_value(param, &value); | |||||
break; | |||||
case JackDriverParamUInt: | |||||
value.ui = strtoul (optarg, NULL, 10); | |||||
jackctl_parameter_set_value(param, &value); | |||||
break; | |||||
case JackDriverParamChar: | |||||
value.c = optarg[0]; | |||||
jackctl_parameter_set_value(param, &value); | |||||
break; | |||||
case JackDriverParamString: | |||||
strncpy (value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); | |||||
jackctl_parameter_set_value(param, &value); | |||||
break; | |||||
case JackDriverParamBool: | |||||
/* | |||||
if (strcasecmp ("false", optarg) == 0 || | |||||
strcasecmp ("off", optarg) == 0 || | |||||
strcasecmp ("no", optarg) == 0 || | |||||
strcasecmp ("0", optarg) == 0 || | |||||
strcasecmp ("(null)", optarg) == 0 ) { | |||||
*/ | |||||
// steph | |||||
if (strcmp ("false", optarg) == 0 || | |||||
strcmp ("off", optarg) == 0 || | |||||
strcmp ("no", optarg) == 0 || | |||||
strcmp ("0", optarg) == 0 || | |||||
strcmp ("(null)", optarg) == 0 ) { | |||||
value.i = false; | |||||
} else { | |||||
value.i = true; | |||||
} | |||||
jackctl_parameter_set_value(param, &value); | |||||
break; | |||||
} | |||||
} else { | |||||
if (jackctl_parameter_get_type(param) == JackParamBool) { | |||||
value.i = true; | |||||
} else { | |||||
value = jackctl_parameter_get_default_value(param); | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
} | |||||
} | |||||
free (options); | |||||
free (long_options); | |||||
return 0; | |||||
} | |||||
EXPORT jack_driver_desc_t * | EXPORT jack_driver_desc_t * | ||||
jack_find_driver_descriptor (JSList * drivers, const char * name) | jack_find_driver_descriptor (JSList * drivers, const char * name) | ||||
{ | { | ||||
@@ -21,9 +21,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#ifndef __JackDriverLoader__ | #ifndef __JackDriverLoader__ | ||||
#define __JackDriverLoader__ | #define __JackDriverLoader__ | ||||
#include "jslist.h" | |||||
#include "driver_interface.h" | #include "driver_interface.h" | ||||
#include "JackDriver.h" | #include "JackDriver.h" | ||||
#include "control_types.h" | |||||
#include "jslist.h" | |||||
#ifdef WIN32 | #ifdef WIN32 | ||||
@@ -54,14 +55,13 @@ typedef struct _jack_driver_info | |||||
jack_driver_info_t; | jack_driver_info_t; | ||||
EXPORT jack_driver_desc_t * jack_find_driver_descriptor (JSList * drivers, const char * name); | EXPORT jack_driver_desc_t * jack_find_driver_descriptor (JSList * drivers, const char * name); | ||||
jack_driver_desc_t * jack_drivers_get_descriptor (JSList * drivers, const char * sofile); | jack_driver_desc_t * jack_drivers_get_descriptor (JSList * drivers, const char * sofile); | ||||
EXPORT JSList * jack_drivers_load (JSList * drivers); | EXPORT JSList * jack_drivers_load (JSList * drivers); | ||||
jack_driver_info_t * jack_load_driver (jack_driver_desc_t * driver_desc); | jack_driver_info_t * jack_load_driver (jack_driver_desc_t * driver_desc); | ||||
EXPORT int jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr); | EXPORT int jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr); | ||||
EXPORT int jackctl_parse_driver_params (jackctl_driver *driver_ptr, int argc, char* argv[]); | |||||
#endif | #endif | ||||
@@ -34,6 +34,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#include "JackGlobals.h" | #include "JackGlobals.h" | ||||
#include "JackChannel.h" | #include "JackChannel.h" | ||||
#include "JackSyncInterface.h" | #include "JackSyncInterface.h" | ||||
#include "JackError.h" | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
@@ -76,6 +77,7 @@ int JackEngine::Close() | |||||
jack_log("JackEngine::Close"); | jack_log("JackEngine::Close"); | ||||
fChannel->Close(); | fChannel->Close(); | ||||
// Close (possibly) remaining clients (RT is stopped) | |||||
for (int i = 0; i < CLIENT_NUM; i++) { | for (int i = 0; i < CLIENT_NUM; i++) { | ||||
/* | /* | ||||
Can only delete clients that where loaded using "jack_internal_client_load" (and not properly unloaded using "jack_internal_client_unload"...) | Can only delete clients that where loaded using "jack_internal_client_load" (and not properly unloaded using "jack_internal_client_unload"...) | ||||
@@ -112,6 +114,7 @@ void JackEngine::ReleaseRefnum(int ref) | |||||
fClientTable[ref] = NULL; | fClientTable[ref] = NULL; | ||||
if (fEngineControl->fTemporary) { | if (fEngineControl->fTemporary) { | ||||
jack_log("JackEngine::ReleaseRefnum fTemporary"); | |||||
int i; | int i; | ||||
for (i = REAL_REFNUM; i < CLIENT_NUM; i++) { | for (i = REAL_REFNUM; i < CLIENT_NUM; i++) { | ||||
if (fClientTable[i]) | if (fClientTable[i]) | ||||
@@ -217,7 +220,7 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, int value1, int v | |||||
jack_log("JackEngine::NotifyClient: client not available anymore"); | jack_log("JackEngine::NotifyClient: client not available anymore"); | ||||
} else if (client->GetClientControl()->fCallback[event]) { | } else if (client->GetClientControl()->fCallback[event]) { | ||||
if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value1, value2) < 0) | if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value1, value2) < 0) | ||||
jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); | |||||
jack_error("NotifyClient fails name = %s event = %ld = val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); | |||||
} else { | } else { | ||||
jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); | jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); | ||||
} | } | ||||
@@ -680,7 +683,7 @@ int JackEngine::PortRegister(int refnum, const char* name, const char *type, uns | |||||
assert(fClientTable[refnum]); | assert(fClientTable[refnum]); | ||||
// Check if port name already exists | // Check if port name already exists | ||||
if (fGraphManager->GetPort(name) != NO_PORT) { | |||||
if (GetGraphManager()->GetPort(name) != NO_PORT) { | |||||
jack_error("port_name \"%s\" already exists", name); | jack_error("port_name \"%s\" already exists", name); | ||||
return -1; | return -1; | ||||
} | } | ||||
@@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#include "JackFrameTimer.h" | #include "JackFrameTimer.h" | ||||
#include "JackTransportEngine.h" | #include "JackTransportEngine.h" | ||||
#include "types.h" | #include "types.h" | ||||
#include <stdio.h> | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
@@ -1,92 +0,0 @@ | |||||
/* | |||||
Copyright (C) 2001 Paul Davis | |||||
Copyright (C) 2004-2008 Grame | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation; either version 2 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
*/ | |||||
#include <stdarg.h> | |||||
#include <stdio.h> | |||||
#include "JackError.h" | |||||
int jack_verbose = 0; | |||||
static | |||||
void | |||||
jack_format_and_log(const char *prefix, const char *fmt, va_list ap, void (* log_callback)(const char *)) | |||||
{ | |||||
char buffer[300]; | |||||
size_t len; | |||||
if (prefix != NULL) { | |||||
len = strlen(prefix); | |||||
memcpy(buffer, prefix, len); | |||||
} else { | |||||
len = 0; | |||||
} | |||||
vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); | |||||
log_callback(buffer); | |||||
} | |||||
EXPORT void jack_error(const char *fmt, ...) | |||||
{ | |||||
va_list ap; | |||||
va_start(ap, fmt); | |||||
jack_format_and_log(NULL, fmt, ap, jack_error_callback); | |||||
va_end(ap); | |||||
} | |||||
EXPORT void jack_info(const char *fmt, ...) | |||||
{ | |||||
va_list ap; | |||||
va_start(ap, fmt); | |||||
jack_format_and_log(NULL, fmt, ap, jack_info_callback); | |||||
va_end(ap); | |||||
} | |||||
EXPORT void jack_info_multiline(const char *fmt, ...) | |||||
{ | |||||
va_list ap; | |||||
va_start(ap, fmt); | |||||
jack_format_and_log(NULL, fmt, ap, jack_info_callback); | |||||
va_end(ap); | |||||
} | |||||
EXPORT void jack_log(const char *fmt,...) | |||||
{ | |||||
if (jack_verbose) { | |||||
va_list ap; | |||||
va_start(ap, fmt); | |||||
jack_format_and_log("Jack: ", fmt, ap, jack_info_callback); | |||||
va_end(ap); | |||||
} | |||||
} | |||||
static void default_jack_error_callback(const char *desc) | |||||
{ | |||||
fprintf(stderr, "%s\n", desc); | |||||
fflush(stderr); | |||||
} | |||||
static void default_jack_info_callback (const char *desc) | |||||
{ | |||||
fprintf(stdout, "%s\n", desc); | |||||
fflush(stdout); | |||||
} | |||||
void (*jack_error_callback)(const char *desc) = &default_jack_error_callback; | |||||
void (*jack_info_callback)(const char *desc) = &default_jack_info_callback; |
@@ -1,6 +1,7 @@ | |||||
/* | /* | ||||
Copyright (C) 2001 Paul Davis | Copyright (C) 2001 Paul Davis | ||||
Copyright (C) 2004-2008 Grame | Copyright (C) 2004-2008 Grame | ||||
Copyright (C) 2008 Nedko Arnaudov | |||||
This program is free software; you can redistribute it and/or modify | This program is free software; you can redistribute it and/or modify | ||||
it under the terms of the GNU General Public License as published by | it under the terms of the GNU General Public License as published by | ||||
@@ -19,20 +20,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
*/ | */ | ||||
#ifndef __JackError__ | |||||
#define __JackError__ | |||||
#include <string.h> | #include <string.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include "JackExports.h" | #include "JackExports.h" | ||||
#include "types.h" | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" | extern "C" | ||||
{ | { | ||||
#endif | #endif | ||||
#ifdef WIN32 | |||||
#define vsnprintf _vsnprintf | |||||
#define snprintf _snprintf | |||||
#endif | |||||
#define LOG_LEVEL_INFO 1 | |||||
#define LOG_LEVEL_ERROR 2 | |||||
EXPORT void jack_error(const char *fmt, ...); | EXPORT void jack_error(const char *fmt, ...); | ||||
@@ -41,11 +44,20 @@ extern "C" | |||||
// like jack_info() but only if verbose mode is enabled | // like jack_info() but only if verbose mode is enabled | ||||
EXPORT void jack_log(const char *fmt, ...); | EXPORT void jack_log(const char *fmt, ...); | ||||
extern int jack_verbose; | |||||
extern void (*jack_error_callback)(const char *desc); | extern void (*jack_error_callback)(const char *desc); | ||||
extern void (*jack_info_callback)(const char *desc); | extern void (*jack_info_callback)(const char *desc); | ||||
typedef void (* jack_log_function_t)(int level, const char *message); | |||||
void change_thread_log_function(jack_log_function_t log_function); | |||||
void jack_log_function(int level, const char *message); | |||||
EXPORT void set_threaded_log_function(); | |||||
extern int jack_verbose; | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
#endif |
@@ -58,6 +58,71 @@ namespace Jack | |||||
JackDriverException(const char* msg) : JackException(msg) | JackDriverException(const char* msg) : JackException(msg) | ||||
{} | {} | ||||
}; | }; | ||||
} | |||||
#endif | |||||
/* | |||||
Copyright (C) 2008 Grame | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation; either version 2 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
*/ | |||||
#ifndef __JackException__ | |||||
#define __JackException__ | |||||
#include <stdexcept> | |||||
#include <iostream> | |||||
#include <string> | |||||
#include "JackError.h" | |||||
namespace Jack | |||||
{ | |||||
class JackException : public std::runtime_error { | |||||
public: | |||||
JackException(const std::string& msg) : runtime_error(msg) | |||||
{} | |||||
JackException(const char* msg) : runtime_error(msg) | |||||
{} | |||||
std::string Message() | |||||
{ | |||||
return what(); | |||||
} | |||||
void PrintMessage() | |||||
{ | |||||
std::string str = what(); | |||||
jack_error(str.c_str()); | |||||
} | |||||
}; | |||||
class JackDriverException : public JackException { | |||||
public: | |||||
JackDriverException(const std::string& msg) : JackException(msg) | |||||
{} | |||||
JackDriverException(const char* msg) : JackException(msg) | |||||
{} | |||||
}; | |||||
} | } | ||||
#endif | #endif |
@@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#include "JackClientControl.h" | #include "JackClientControl.h" | ||||
#include "JackGlobals.h" | #include "JackGlobals.h" | ||||
#include "JackChannel.h" | #include "JackChannel.h" | ||||
#include "JackError.h" | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
@@ -18,22 +18,78 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
*/ | */ | ||||
#include "JackGlobals.h" | #include "JackGlobals.h" | ||||
#include "JackError.h" | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
JackFactoryImpl* JackGlobals::fInstance; | |||||
JackFactoryImpl* JackGlobals::fInstance; | |||||
void JackGlobals::InitServer() | |||||
{ | |||||
jack_log("JackGlobals InitServer"); | |||||
if (!fInstance) { | |||||
#ifdef __APPLE__ | |||||
fInstance = new JackFactoryOSXServer(); | |||||
#endif | |||||
#ifdef WIN32 | |||||
fInstance = new JackFactoryWindowsServer(); | |||||
#endif | |||||
#ifdef __linux__ | |||||
fInstance = new JackFactoryLinuxServer(); | |||||
#endif | |||||
} | |||||
} | |||||
void JackGlobals::InitClient() | |||||
{ | |||||
jack_log("JackGlobals InitClient"); | |||||
if (!fInstance) { | |||||
#ifdef __APPLE__ | |||||
fInstance = new JackFactoryOSXClient(); | |||||
#endif | |||||
#ifdef WIN32 | |||||
fInstance = new JackFactoryWindowsClient(); | |||||
#endif | |||||
#ifdef __linux__ | |||||
fInstance = new JackFactoryLinuxClient(); | |||||
#endif | |||||
} | |||||
} | |||||
void JackGlobals::Destroy() | |||||
{ | |||||
jack_log("JackGlobals Destroy"); | |||||
if (fInstance) { | |||||
delete fInstance; | |||||
fInstance = NULL; | |||||
} | |||||
} | |||||
} // end of namespace | } // end of namespace | ||||
static bool gKeyRealtimeInitialized = false; | static bool gKeyRealtimeInitialized = false; | ||||
static bool g_key_log_function_initialized = false; | |||||
jack_tls_key gRealTime; | jack_tls_key gRealTime; | ||||
jack_tls_key g_key_log_function; | |||||
void jack_init() | void jack_init() | ||||
{ | { | ||||
if (!gKeyRealtimeInitialized) { | if (!gKeyRealtimeInitialized) { | ||||
gKeyRealtimeInitialized = jack_tls_allocate_key(&gRealTime); | gKeyRealtimeInitialized = jack_tls_allocate_key(&gRealTime); | ||||
} | } | ||||
if (!g_key_log_function_initialized) | |||||
g_key_log_function_initialized = jack_tls_allocate_key(&g_key_log_function); | |||||
} | } | ||||
void jack_uninit() | void jack_uninit() | ||||
@@ -42,6 +98,11 @@ void jack_uninit() | |||||
jack_tls_free_key(gRealTime); | jack_tls_free_key(gRealTime); | ||||
gKeyRealtimeInitialized = false; | gKeyRealtimeInitialized = false; | ||||
} | } | ||||
if (g_key_log_function_initialized) { | |||||
jack_tls_free_key(g_key_log_function); | |||||
g_key_log_function_initialized = false; | |||||
} | |||||
} | } | ||||
// Initialisation at library load time | // Initialisation at library load time | ||||
@@ -229,55 +229,12 @@ class JackGlobals | |||||
return fInstance->MakeThread(runnable); | return fInstance->MakeThread(runnable); | ||||
} | } | ||||
static void InitServer() | |||||
{ | |||||
jack_log("JackGlobals InitServer"); | |||||
if (!fInstance) { | |||||
#ifdef __APPLE__ | |||||
fInstance = new JackFactoryOSXServer(); | |||||
#endif | |||||
#ifdef WIN32 | |||||
fInstance = new JackFactoryWindowsServer(); | |||||
#endif | |||||
#ifdef __linux__ | |||||
fInstance = new JackFactoryLinuxServer(); | |||||
#endif | |||||
} | |||||
} | |||||
static void InitClient() | |||||
{ | |||||
jack_log("JackGlobals InitClient"); | |||||
if (!fInstance) { | |||||
#ifdef __APPLE__ | |||||
fInstance = new JackFactoryOSXClient(); | |||||
#endif | |||||
#ifdef WIN32 | |||||
fInstance = new JackFactoryWindowsClient(); | |||||
#endif | |||||
#ifdef __linux__ | |||||
fInstance = new JackFactoryLinuxClient(); | |||||
#endif | |||||
} | |||||
} | |||||
static void Destroy() | |||||
{ | |||||
jack_log("JackGlobals Destroy"); | |||||
if (fInstance) { | |||||
delete fInstance; | |||||
fInstance = NULL; | |||||
} | |||||
} | |||||
static void InitServer(); | |||||
static void InitClient(); | |||||
static void Destroy(); | |||||
}; | }; | ||||
namespace detail | namespace detail | ||||
@@ -304,6 +261,7 @@ extern "C" | |||||
#endif | #endif | ||||
extern jack_tls_key gRealTime; | extern jack_tls_key gRealTime; | ||||
extern jack_tls_key g_key_log_function; | |||||
#ifdef WIN32 | #ifdef WIN32 | ||||
@@ -67,6 +67,13 @@ namespace Jack | |||||
{ | { | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
JackSynchro* JackFactoryWindowsServer::MakeSynchro() {return NULL;} | |||||
JackServerNotifyChannelInterface* JackFactoryWindowsServer::MakeServerNotifyChannel() {return NULL;} | |||||
JackClientChannelInterface* JackFactoryWindowsServer::MakeClientChannel() {return NULL;} | |||||
JackNotifyChannelInterface* JackFactoryWindowsServer::MakeNotifyChannel() {return NULL;} | |||||
JackServerChannelInterface* JackFactoryWindowsServer::MakeServerChannel() {return NULL;} | |||||
JackSyncInterface* JackFactoryWindowsServer::MakeInterProcessSync() {return NULL;} | |||||
JackThread* JackFactoryWindowsServer::MakeThread(JackRunnableInterface* runnable) {return NULL;} | |||||
JackSynchro* JackFactoryWindowsClient::MakeSynchro() | JackSynchro* JackFactoryWindowsClient::MakeSynchro() | ||||
{ | { | ||||
@@ -144,6 +151,14 @@ JackThread* JackFactoryLinuxClient::MakeThread(JackRunnableInterface* runnable) | |||||
#endif | #endif | ||||
#if defined(SOCKET_RPC_FIFO_SEMA) | #if defined(SOCKET_RPC_FIFO_SEMA) | ||||
JackSynchro* JackFactoryLinuxServer::MakeSynchro() {return NULL;} | |||||
JackServerNotifyChannelInterface* JackFactoryLinuxServer::MakeServerNotifyChannel() {return NULL;} | |||||
JackClientChannelInterface* JackFactoryLinuxServer::MakeClientChannel() {return NULL;} | |||||
JackNotifyChannelInterface* JackFactoryLinuxServer::MakeNotifyChannel() {return NULL;} | |||||
JackServerChannelInterface* JackFactoryLinuxServer::MakeServerChannel() {return NULL;} | |||||
JackSyncInterface* JackFactoryLinuxServer::MakeInterProcessSync() {return NULL;} | |||||
JackThread* JackFactoryLinuxServer::MakeThread(JackRunnableInterface* runnable) {return NULL;} | |||||
JackSynchro* JackFactoryLinuxClient::MakeSynchro() | JackSynchro* JackFactoryLinuxClient::MakeSynchro() | ||||
{ | { | ||||
return new JackFifo(); | return new JackFifo(); | ||||
@@ -223,6 +238,14 @@ JackThread* JackFactoryLinuxClient::MakeThread(JackRunnableInterface* runnable) | |||||
#if defined(MACH_RPC_MACH_SEMA) | #if defined(MACH_RPC_MACH_SEMA) | ||||
// Mach RPC + Mach Semaphore | // Mach RPC + Mach Semaphore | ||||
JackSynchro* JackFactoryOSXServer::MakeSynchro() {return NULL;} | |||||
JackServerNotifyChannelInterface* JackFactoryOSXServer::MakeServerNotifyChannel() {return NULL;} | |||||
JackClientChannelInterface* JackFactoryOSXServer::MakeClientChannel() {return NULL;} | |||||
JackNotifyChannelInterface* JackFactoryOSXServer::MakeNotifyChannel() {return NULL;} | |||||
JackServerChannelInterface* JackFactoryOSXServer::MakeServerChannel() {return NULL;} | |||||
JackSyncInterface* JackFactoryOSXServer::MakeInterProcessSync() {return NULL;} | |||||
JackThread* JackFactoryOSXServer::MakeThread(JackRunnableInterface* runnable) {return NULL;} | |||||
JackSynchro* JackFactoryOSXClient::MakeSynchro() | JackSynchro* JackFactoryOSXClient::MakeSynchro() | ||||
{ | { | ||||
return new JackMachSemaphore(); | return new JackMachSemaphore(); | ||||
@@ -338,6 +361,7 @@ JackThread* JackFactoryOSXClient::MakeThread(JackRunnableInterface* runnable) | |||||
#if defined(MACH_RPC_FIFO_SEMA) | #if defined(MACH_RPC_FIFO_SEMA) | ||||
// Mach RPC + Fifo Semaphore | // Mach RPC + Fifo Semaphore | ||||
JackSynchro* JackFactoryOSXClient::MakeSynchro() | JackSynchro* JackFactoryOSXClient::MakeSynchro() | ||||
{ | { | ||||
return new JackFifo(); | return new JackFifo(); | ||||
@@ -78,6 +78,14 @@ namespace Jack | |||||
{ | { | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
JackSynchro* JackFactoryWindowsClient::MakeSynchro() {return NULL;} | |||||
JackServerNotifyChannelInterface* JackFactoryWindowsClient::MakeServerNotifyChannel() {return NULL;} | |||||
JackClientChannelInterface* JackFactoryWindowsClient::MakeClientChannel() {return NULL;} | |||||
JackNotifyChannelInterface* JackFactoryWindowsClient::MakeNotifyChannel() {return NULL;} | |||||
JackServerChannelInterface* JackFactoryWindowsClient::MakeServerChannel() {return NULL;} | |||||
JackSyncInterface* JackFactoryWindowsClient::MakeInterProcessSync() {return NULL;} | |||||
JackThread* JackFactoryWindowsClient::MakeThread(JackRunnableInterface* runnable) {return NULL;} | |||||
JackSynchro* JackFactoryWindowsServer::MakeSynchro() | JackSynchro* JackFactoryWindowsServer::MakeSynchro() | ||||
{ | { | ||||
return new JackWinSemaphore(); | return new JackWinSemaphore(); | ||||
@@ -154,6 +162,14 @@ JackThread* JackFactoryLinuxServer::MakeThread(JackRunnableInterface* runnable) | |||||
#endif | #endif | ||||
#if defined(SOCKET_RPC_FIFO_SEMA) | #if defined(SOCKET_RPC_FIFO_SEMA) | ||||
JackSynchro* JackFactoryLinuxClient::MakeSynchro() {return NULL;} | |||||
JackServerNotifyChannelInterface* JackFactoryLinuxClient::MakeServerNotifyChannel() {return NULL;} | |||||
JackClientChannelInterface* JackFactoryLinuxClient::MakeClientChannel() {return NULL;} | |||||
JackNotifyChannelInterface* JackFactoryLinuxClient::MakeNotifyChannel() {return NULL;} | |||||
JackServerChannelInterface* JackFactoryLinuxClient::MakeServerChannel() {return NULL;} | |||||
JackSyncInterface* JackFactoryLinuxClient::MakeInterProcessSync() {return NULL;} | |||||
JackThread* JackFactoryLinuxClient::MakeThread(JackRunnableInterface* runnable) {return NULL;} | |||||
JackSynchro* JackFactoryLinuxServer::MakeSynchro() | JackSynchro* JackFactoryLinuxServer::MakeSynchro() | ||||
{ | { | ||||
return new JackFifo(); | return new JackFifo(); | ||||
@@ -233,6 +249,14 @@ JackThread* JackFactoryLinuxServer::MakeThread(JackRunnableInterface* runnable) | |||||
#if defined(MACH_RPC_MACH_SEMA) | #if defined(MACH_RPC_MACH_SEMA) | ||||
// Mach RPC + Mach Semaphore | // Mach RPC + Mach Semaphore | ||||
JackSynchro* JackFactoryOSXClient::MakeSynchro() {return NULL;} | |||||
JackServerNotifyChannelInterface* JackFactoryOSXClient::MakeServerNotifyChannel() {return NULL;} | |||||
JackClientChannelInterface* JackFactoryOSXClient::MakeClientChannel() {return NULL;} | |||||
JackNotifyChannelInterface* JackFactoryOSXClient::MakeNotifyChannel() {return NULL;} | |||||
JackServerChannelInterface* JackFactoryOSXClient::MakeServerChannel() {return NULL;} | |||||
JackSyncInterface* JackFactoryOSXClient::MakeInterProcessSync() {return NULL;} | |||||
JackThread* JackFactoryOSXClient::MakeThread(JackRunnableInterface* runnable) {return NULL;} | |||||
JackSynchro* JackFactoryOSXServer::MakeSynchro() | JackSynchro* JackFactoryOSXServer::MakeSynchro() | ||||
{ | { | ||||
return new JackMachSemaphore(); | return new JackMachSemaphore(); | ||||
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#include "JackGraphManager.h" | #include "JackGraphManager.h" | ||||
#include "JackConstants.h" | #include "JackConstants.h" | ||||
#include "JackError.h" | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <algorithm> | #include <algorithm> | ||||
@@ -27,22 +27,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
// Used for external C API (JackAPI.cpp) | // Used for external C API (JackAPI.cpp) | ||||
JackGraphManager* GetGraphManager() | JackGraphManager* GetGraphManager() | ||||
{ | { | ||||
if (JackLibGlobals::fGlobals) { | |||||
return JackLibGlobals::fGlobals->fGraphManager; | |||||
} else { | |||||
return NULL; | |||||
if (JackLibGlobals::fGlobals) { | |||||
return JackLibGlobals::fGlobals->fGraphManager; | |||||
} else { | |||||
return NULL; | |||||
} | } | ||||
} | } | ||||
JackEngineControl* GetEngineControl() | JackEngineControl* GetEngineControl() | ||||
{ | { | ||||
if (JackLibGlobals::fGlobals) { | |||||
return JackLibGlobals::fGlobals->fEngineControl; | |||||
} else { | |||||
return NULL; | |||||
if (JackLibGlobals::fGlobals) { | |||||
return JackLibGlobals::fGlobals->fEngineControl; | |||||
} else { | |||||
return NULL; | |||||
} | } | ||||
} | } | ||||
@@ -28,7 +28,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#endif | #endif | ||||
#include "JackGlobals.h" | #include "JackGlobals.h" | ||||
#include "JackGraphManager.h" | #include "JackGraphManager.h" | ||||
#include "JackMessageBuffer.h" | |||||
#include "JackTime.h" | #include "JackTime.h" | ||||
#include "JackError.h" | |||||
#include <assert.h> | #include <assert.h> | ||||
namespace Jack | namespace Jack | ||||
@@ -55,6 +57,7 @@ struct JackLibGlobals | |||||
JackLibGlobals() | JackLibGlobals() | ||||
{ | { | ||||
jack_log("JackLibGlobals"); | jack_log("JackLibGlobals"); | ||||
JackMessageBuffer::Create(); | |||||
for (int i = 0; i < CLIENT_NUM; i++) | for (int i = 0; i < CLIENT_NUM; i++) | ||||
fSynchroTable[i] = JackGlobals::MakeSynchro(); | fSynchroTable[i] = JackGlobals::MakeSynchro(); | ||||
fGraphManager = -1; | fGraphManager = -1; | ||||
@@ -68,6 +71,7 @@ struct JackLibGlobals | |||||
fSynchroTable[i]->Disconnect(); | fSynchroTable[i]->Disconnect(); | ||||
delete fSynchroTable[i]; | delete fSynchroTable[i]; | ||||
} | } | ||||
JackMessageBuffer::Destroy(); | |||||
} | } | ||||
static void Init() | static void Init() | ||||
@@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#include "JackLoopbackDriver.h" | #include "JackLoopbackDriver.h" | ||||
#include "JackEngineControl.h" | #include "JackEngineControl.h" | ||||
#include "JackGraphManager.h" | #include "JackGraphManager.h" | ||||
#include "JackError.h" | |||||
#include <iostream> | #include <iostream> | ||||
#include <assert.h> | #include <assert.h> | ||||
@@ -35,7 +35,7 @@ enum | |||||
PORT_TYPES_MAX = sizeof(port_types) / sizeof(port_types[0]) | PORT_TYPES_MAX = sizeof(port_types) / sizeof(port_types[0]) | ||||
}; | }; | ||||
int GetPortTypeId(const char* port_type) | |||||
jack_port_type_id_t GetPortTypeId(const char* port_type) | |||||
{ | { | ||||
for (int i = 0; i < PORT_TYPES_MAX; ++i) { | for (int i = 0; i < PORT_TYPES_MAX; ++i) { | ||||
const JackPortType* type = port_types[i]; | const JackPortType* type = port_types[i]; | ||||
@@ -46,7 +46,7 @@ int GetPortTypeId(const char* port_type) | |||||
return -1; | return -1; | ||||
} | } | ||||
const JackPortType* GetPortType(int type_id) | |||||
const JackPortType* GetPortType(jack_port_type_id_t type_id) | |||||
{ | { | ||||
assert(type_id >= 0 && type_id <= PORT_TYPES_MAX); | assert(type_id >= 0 && type_id <= PORT_TYPES_MAX); | ||||
const JackPortType* type = port_types[type_id]; | const JackPortType* type = port_types[type_id]; | ||||
@@ -34,11 +34,11 @@ struct JackPortType | |||||
void (*mixdown)(void *mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes); | void (*mixdown)(void *mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes); | ||||
}; | }; | ||||
extern int GetPortTypeId(const char* port_type); | |||||
extern const JackPortType* GetPortType(int port_type_id); | |||||
extern jack_port_type_id_t GetPortTypeId(const char* port_type); | |||||
extern const struct JackPortType* GetPortType(jack_port_type_id_t port_type_id); | |||||
extern const JackPortType gAudioPortType; | |||||
extern const JackPortType gMidiPortType; | |||||
extern const struct JackPortType gAudioPortType; | |||||
extern const struct JackPortType gMidiPortType; | |||||
} // namespace Jack | } // namespace Jack | ||||
@@ -67,45 +67,10 @@ class JackProcessSync : public JackSyncInterface | |||||
void Destroy() | void Destroy() | ||||
{} | {} | ||||
bool TimedWait(long usec) | |||||
{ | |||||
struct timeval T0, T1; | |||||
timespec time; | |||||
struct timeval now; | |||||
int res; | |||||
pthread_mutex_lock(&fLock); | |||||
jack_log("JackProcessSync::Wait time out = %ld", usec); | |||||
gettimeofday(&T0, 0); | |||||
static const UInt64 kNanosPerSec = 1000000000ULL; | |||||
static const UInt64 kNanosPerUsec = 1000ULL; | |||||
gettimeofday(&now, 0); | |||||
UInt64 nextDateNanos = now.tv_sec * kNanosPerSec + (now.tv_usec + usec) * kNanosPerUsec; | |||||
time.tv_sec = nextDateNanos / kNanosPerSec; | |||||
time.tv_nsec = nextDateNanos % kNanosPerSec; | |||||
res = pthread_cond_timedwait(&fCond, &fLock, &time); | |||||
if (res != 0) | |||||
jack_error("pthread_cond_timedwait error usec = %ld err = %s", usec, strerror(res)); | |||||
gettimeofday(&T1, 0); | |||||
pthread_mutex_unlock(&fLock); | |||||
jack_log("JackProcessSync::Wait finished delta = %5.1lf", | |||||
(1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); | |||||
return (res == 0); | |||||
} | |||||
void Wait() | |||||
{ | |||||
int res; | |||||
pthread_mutex_lock(&fLock); | |||||
jack_log("JackProcessSync::Wait..."); | |||||
if ((res = pthread_cond_wait(&fCond, &fLock)) != 0) | |||||
jack_error("pthread_cond_wait error err = %s", strerror(errno)); | |||||
pthread_mutex_unlock(&fLock); | |||||
jack_log("JackProcessSync::Wait finished"); | |||||
} | |||||
bool TimedWait(long usec); | |||||
void Wait(); | |||||
void SignalAll() | void SignalAll() | ||||
{ | { | ||||
//pthread_mutex_lock(&fLock); | //pthread_mutex_lock(&fLock); | ||||
@@ -150,17 +115,7 @@ class JackInterProcessSync : public JackSyncInterface | |||||
return fSynchro->Connect(name, ""); | return fSynchro->Connect(name, ""); | ||||
} | } | ||||
bool TimedWait(long usec) | |||||
{ | |||||
struct timeval T0, T1; | |||||
jack_log("JackInterProcessSync::Wait..."); | |||||
gettimeofday(&T0, 0); | |||||
bool res = fSynchro->TimedWait(usec); | |||||
gettimeofday(&T1, 0); | |||||
jack_log("JackInterProcessSync::Wait finished delta = %5.1lf", | |||||
(1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); | |||||
return res; | |||||
} | |||||
bool TimedWait(long usec); | |||||
void Wait() | void Wait() | ||||
{ | { | ||||
@@ -23,8 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#include "JackConstants.h" | #include "JackConstants.h" | ||||
#include "JackChannelTransaction.h" | #include "JackChannelTransaction.h" | ||||
#include "JackError.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
@@ -36,6 +36,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#include "JackSyncInterface.h" | #include "JackSyncInterface.h" | ||||
#include "JackGraphManager.h" | #include "JackGraphManager.h" | ||||
#include "JackInternalClient.h" | #include "JackInternalClient.h" | ||||
#include "JackError.h" | |||||
#include "JackMessageBuffer.h" | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
@@ -81,6 +83,9 @@ JackServer::~JackServer() | |||||
int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) | int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) | ||||
{ | { | ||||
// TODO: move that in reworked JackServerGlobals::Init() | |||||
JackMessageBuffer::Create(); | |||||
if (fChannel->Open(fEngineControl->fServerName, this) < 0) { | if (fChannel->Open(fEngineControl->fServerName, this) < 0) { | ||||
jack_error("Server channel open error"); | jack_error("Server channel open error"); | ||||
return -1; | return -1; | ||||
@@ -141,6 +146,8 @@ int JackServer::Close() | |||||
fFreewheelDriver->Close(); | fFreewheelDriver->Close(); | ||||
fLoopbackDriver->Close(); | fLoopbackDriver->Close(); | ||||
fEngine->Close(); | fEngine->Close(); | ||||
// TODO: move that in reworked JackServerGlobals::Destroy() | |||||
JackMessageBuffer::Destroy(); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -151,10 +158,9 @@ int JackServer::InternalClientLoad(const char* client_name, const char* so_name, | |||||
*status = 0; | *status = 0; | ||||
JackLoadableInternalClient* client = new JackLoadableInternalClient(fInstance, GetSynchroTable(), so_name, objet_data); | JackLoadableInternalClient* client = new JackLoadableInternalClient(fInstance, GetSynchroTable(), so_name, objet_data); | ||||
assert(client); | assert(client); | ||||
if (client->Open("unused", client_name, (jack_options_t)options, (jack_status_t*)status) < 0) { | |||||
int res = client->Open("unused", client_name, (jack_options_t)options, (jack_status_t*)status); | |||||
if (res < 0) { | |||||
delete client; | delete client; | ||||
int my_status1 = *status | JackFailure; | |||||
*status = (jack_status_t)my_status1; | |||||
*int_ref = 0; | *int_ref = 0; | ||||
} else { | } else { | ||||
*int_ref = client->GetClientControl()->fRefNum; | *int_ref = client->GetClientControl()->fRefNum; | ||||
@@ -164,6 +170,7 @@ int JackServer::InternalClientLoad(const char* client_name, const char* so_name, | |||||
*status = (jack_status_t)my_status1; | *status = (jack_status_t)my_status1; | ||||
*int_ref = 0; | *int_ref = 0; | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -27,17 +27,11 @@ This program is free software; you can redistribute it and/or modify | |||||
#include "JackServer.h" | #include "JackServer.h" | ||||
#include "JackDebugClient.h" | #include "JackDebugClient.h" | ||||
#include "JackServerGlobals.h" | #include "JackServerGlobals.h" | ||||
#include "JackError.h" | |||||
#include "JackServerLaunch.h" | #include "JackServerLaunch.h" | ||||
#include "JackTools.h" | #include "JackTools.h" | ||||
#include "JackExports.h" | |||||
#include "JackEngine.h" | #include "JackEngine.h" | ||||
#ifdef WIN32 | |||||
#define EXPORT __declspec(dllexport) | |||||
#else | |||||
#define EXPORT | |||||
#endif | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" | extern "C" | ||||
{ | { | ||||
@@ -58,6 +52,9 @@ extern "C" | |||||
using namespace Jack; | using namespace Jack; | ||||
// beware!!! things can go nasty if one client is started with JackNoStartServer and another without it | |||||
bool g_nostart; | |||||
EXPORT jack_client_t* jack_client_open_aux(const char* ext_client_name, jack_options_t options, jack_status_t* status, va_list ap) | EXPORT jack_client_t* jack_client_open_aux(const char* ext_client_name, jack_options_t options, jack_status_t* status, va_list ap) | ||||
{ | { | ||||
jack_varargs_t va; /* variable arguments */ | jack_varargs_t va; /* variable arguments */ | ||||
@@ -90,10 +87,13 @@ EXPORT jack_client_t* jack_client_open_aux(const char* ext_client_name, jack_opt | |||||
else | else | ||||
jack_varargs_init(&va); | jack_varargs_init(&va); | ||||
if (!JackServerGlobals::Init()) { // jack server initialisation | |||||
int my_status1 = (JackFailure | JackServerError); | |||||
*status = (jack_status_t)my_status1; | |||||
return NULL; | |||||
g_nostart = (options & JackNoStartServer) != 0; | |||||
if (!g_nostart) { | |||||
if (!JackServerGlobals::Init()) { // jack server initialisation | |||||
int my_status1 = (JackFailure | JackServerError); | |||||
*status = (jack_status_t)my_status1; | |||||
return NULL; | |||||
} | |||||
} | } | ||||
#ifndef WIN32 | #ifndef WIN32 | ||||
@@ -109,7 +109,9 @@ EXPORT jack_client_t* jack_client_open_aux(const char* ext_client_name, jack_opt | |||||
int res = client->Open(va.server_name, client_name, options, status); | int res = client->Open(va.server_name, client_name, options, status); | ||||
if (res < 0) { | if (res < 0) { | ||||
delete client; | delete client; | ||||
JackServerGlobals::Destroy(); // jack server destruction | |||||
if (!g_nostart) { | |||||
JackServerGlobals::Destroy(); // jack server destruction | |||||
} | |||||
int my_status1 = (JackFailure | JackServerError); | int my_status1 = (JackFailure | JackServerError); | ||||
*status = (jack_status_t)my_status1; | *status = (jack_status_t)my_status1; | ||||
return NULL; | return NULL; | ||||
@@ -138,7 +140,9 @@ EXPORT int jack_client_close(jack_client_t* ext_client) | |||||
int res = client->Close(); | int res = client->Close(); | ||||
delete client; | delete client; | ||||
jack_log("jack_client_close OK"); | jack_log("jack_client_close OK"); | ||||
JackServerGlobals::Destroy(); // jack server destruction | |||||
if (!g_nostart) { | |||||
JackServerGlobals::Destroy(); // jack server destruction | |||||
} | |||||
return res; | return res; | ||||
} | } | ||||
} | } | ||||
@@ -22,10 +22,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#endif | #endif | ||||
#include "JackServerGlobals.h" | #include "JackServerGlobals.h" | ||||
#include "JackError.h" | |||||
#include "JackTools.h" | #include "JackTools.h" | ||||
#include "shm.h" | #include "shm.h" | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include <stdio.h> | |||||
#include <errno.h> | |||||
static char* server_name = NULL; | static char* server_name = NULL; | ||||
@@ -277,8 +278,7 @@ bool JackServerGlobals::Init() | |||||
jack_error("no access to shm registry"); | jack_error("no access to shm registry"); | ||||
goto error; | goto error; | ||||
default: | default: | ||||
if (jack_verbose) | |||||
jack_info("server `%s' registered", server_name); | |||||
jack_info("server `%s' registered", server_name); | |||||
} | } | ||||
/* clean up shared memory and files from any previous instance of this server name */ | /* clean up shared memory and files from any previous instance of this server name */ | ||||
@@ -30,6 +30,55 @@ using namespace Jack; | |||||
#ifndef WIN32 | #ifndef WIN32 | ||||
#if defined(JACK_DBUS) | |||||
#include <dbus/dbus.h> | |||||
int start_server_dbus(const char* server_name) | |||||
{ | |||||
DBusError err; | |||||
DBusConnection *conn; | |||||
DBusMessage *msg; | |||||
// initialise the errors | |||||
dbus_error_init(&err); | |||||
// connect to the bus | |||||
conn = dbus_bus_get(DBUS_BUS_SESSION, &err); | |||||
if (dbus_error_is_set(&err)) { | |||||
fprintf(stderr, "Connection Error (%s)\n", err.message); | |||||
dbus_error_free(&err); | |||||
} | |||||
if (NULL == conn) { | |||||
return 1; | |||||
} | |||||
msg = dbus_message_new_method_call( | |||||
"org.jackaudio.service", // target for the method call | |||||
"/org/jackaudio/Controller", // object to call on | |||||
"org.jackaudio.JackControl", // interface to call on | |||||
"StartServer"); // method name | |||||
if (NULL == msg) { | |||||
fprintf(stderr, "Message Null\n"); | |||||
return 1; | |||||
} | |||||
// send message and get a handle for a reply | |||||
if (!dbus_connection_send(conn, msg, NULL)) | |||||
{ | |||||
fprintf(stderr, "Out Of Memory!\n"); | |||||
return 1; | |||||
} | |||||
dbus_message_unref(msg); | |||||
dbus_connection_flush(conn); | |||||
dbus_error_free(&err); | |||||
return 0; | |||||
} | |||||
#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_aux(const char* server_name) | static void start_server_aux(const char* server_name) | ||||
{ | { | ||||
@@ -114,12 +163,18 @@ static void start_server_aux(const char* server_name) | |||||
fprintf(stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno)); | fprintf(stderr, "exec of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno)); | ||||
} | } | ||||
#endif | |||||
int start_server(const char* server_name, jack_options_t options) | 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) | |||||
return start_server_dbus(server_name); | |||||
#else | |||||
/* The double fork() forces the server to become a child of | /* The double fork() forces the server to become a child of | ||||
* init, which will always clean up zombie process state on | * init, which will always clean up zombie process state on | ||||
* termination. This even works in cases where the server | * termination. This even works in cases where the server | ||||
@@ -146,6 +201,7 @@ int start_server(const char* server_name, jack_options_t options) | |||||
/* only the original parent process goes here */ | /* only the original parent process goes here */ | ||||
return 0; /* (probably) successful */ | return 0; /* (probably) successful */ | ||||
#endif | |||||
} | } | ||||
int server_connect(char* server_name) | int server_connect(char* server_name) | ||||
@@ -18,8 +18,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
*/ | */ | ||||
#include "JackShmMem.h" | |||||
#include "JackError.h" | #include "JackError.h" | ||||
#include "JackShmMem.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
namespace Jack | namespace Jack | ||||
@@ -82,6 +82,11 @@ void JackShmMem::operator delete(void* p, size_t size) | |||||
jack_destroy_shm(&info); | jack_destroy_shm(&info); | ||||
} | } | ||||
void JackShmMem::operator delete(void* p) | |||||
{ | |||||
JackShmMem::operator delete(p, 0); | |||||
} | |||||
void LockMemoryImp(void* ptr, size_t size) | void LockMemoryImp(void* ptr, size_t size) | ||||
{ | { | ||||
if (CHECK_MLOCK(ptr, size)) { | if (CHECK_MLOCK(ptr, size)) { | ||||
@@ -68,7 +68,7 @@ class JackMem | |||||
{ | { | ||||
free(ptr); | free(ptr); | ||||
} | } | ||||
JackMem(): fSize(gSize) | JackMem(): fSize(gSize) | ||||
{} | {} | ||||
@@ -107,6 +107,7 @@ class JackShmMem | |||||
void* operator new(size_t size); | void* operator new(size_t size); | ||||
void* operator new(size_t size, void* memory); | void* operator new(size_t size, void* memory); | ||||
void operator delete(void* p, size_t size); | void operator delete(void* p, size_t size); | ||||
void operator delete(void* p); | |||||
JackShmMem() | JackShmMem() | ||||
{ | { | ||||
@@ -62,6 +62,7 @@ class JackSocketServerChannel : public JackServerChannelInterface, public JackRu | |||||
void Close(); // Close the Server/Client connection | void Close(); // Close the Server/Client connection | ||||
// JackRunnableInterface interface | // JackRunnableInterface interface | ||||
bool Init(); | |||||
bool Execute(); | bool Execute(); | ||||
}; | }; | ||||
@@ -20,8 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#ifndef __JackSynchro__ | #ifndef __JackSynchro__ | ||||
#define __JackSynchro__ | #define __JackSynchro__ | ||||
#include "JackError.h" | |||||
#define SYNC_MAX_NAME_SIZE 256 | #define SYNC_MAX_NAME_SIZE 256 | ||||
namespace Jack | namespace Jack | ||||
@@ -1,22 +1,22 @@ | |||||
/* | /* | ||||
Copyright (C) 2001 Paul Davis | |||||
Copyright (C) 2004-2008 Grame | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser General Public License as published by | |||||
the Free Software Foundation; either version 2.1 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser General Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
*/ | |||||
Copyright (C) 2001 Paul Davis | |||||
Copyright (C) 2004-2008 Grame | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser General Public License as published by | |||||
the Free Software Foundation; either version 2.1 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser General Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
*/ | |||||
#ifndef __JackThread__ | #ifndef __JackThread__ | ||||
#define __JackThread__ | #define __JackThread__ | ||||
@@ -32,21 +32,21 @@ typedef unsigned long long UInt64; | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
/*! | /*! | ||||
\brief The base class for runnable objects, that have an <B> Init </B> and <B> Execute </B> method to be called in a thread. | |||||
*/ | |||||
\brief The base class for runnable objects, that have an <B> Init </B> and <B> Execute </B> method to be called in a thread. | |||||
*/ | |||||
class JackRunnableInterface | class JackRunnableInterface | ||||
{ | { | ||||
public: | public: | ||||
JackRunnableInterface() | JackRunnableInterface() | ||||
{} | {} | ||||
virtual ~JackRunnableInterface() | virtual ~JackRunnableInterface() | ||||
{} | {} | ||||
virtual bool Init() /*! Called once when the thread is started */ | virtual bool Init() /*! Called once when the thread is started */ | ||||
{ | { | ||||
return true; | return true; | ||||
@@ -55,37 +55,37 @@ class JackRunnableInterface | |||||
}; | }; | ||||
/*! | /*! | ||||
\brief The thread base class. | |||||
*/ | |||||
\brief The thread base class. | |||||
*/ | |||||
class JackThread | class JackThread | ||||
{ | { | ||||
public: | public: | ||||
enum kThreadState {kIdle, kStarting, kRunning}; | |||||
enum kThreadState {kIdle, kStarting, kRunning}; | |||||
protected: | protected: | ||||
JackRunnableInterface* fRunnable; | JackRunnableInterface* fRunnable; | ||||
int fPriority; | int fPriority; | ||||
bool fRealTime; | bool fRealTime; | ||||
volatile kThreadState fStatus; | volatile kThreadState fStatus; | ||||
int fCancellation; | int fCancellation; | ||||
public: | public: | ||||
JackThread(JackRunnableInterface* runnable, int priority, bool real_time, int cancellation): | JackThread(JackRunnableInterface* runnable, int priority, bool real_time, int cancellation): | ||||
fRunnable(runnable), fPriority(priority), fRealTime(real_time), fStatus(kIdle), fCancellation(cancellation) | |||||
fRunnable(runnable), fPriority(priority), fRealTime(real_time), fStatus(kIdle), fCancellation(cancellation) | |||||
{} | {} | ||||
virtual ~JackThread() | virtual ~JackThread() | ||||
{} | {} | ||||
virtual int Start() = 0; | virtual int Start() = 0; | ||||
virtual int StartSync() = 0; | virtual int StartSync() = 0; | ||||
virtual int Kill() = 0; | virtual int Kill() = 0; | ||||
virtual int Stop() = 0; | virtual int Stop() = 0; | ||||
virtual void Terminate() = 0; | virtual void Terminate() = 0; | ||||
virtual int AcquireRealTime() = 0; | virtual int AcquireRealTime() = 0; | ||||
virtual int AcquireRealTime(int priority) = 0; | virtual int AcquireRealTime(int priority) = 0; | ||||
virtual int DropRealTime() = 0; | virtual int DropRealTime() = 0; | ||||
@@ -98,14 +98,14 @@ class JackThread | |||||
{ | { | ||||
fStatus = status; | fStatus = status; | ||||
} | } | ||||
virtual void SetParams(UInt64 period, UInt64 computation, UInt64 constraint) // Empty implementation, will only make sense on OSX... | virtual void SetParams(UInt64 period, UInt64 computation, UInt64 constraint) // Empty implementation, will only make sense on OSX... | ||||
{} | {} | ||||
virtual pthread_t GetThreadID() = 0; | virtual pthread_t GetThreadID() = 0; | ||||
}; | }; | ||||
} // end of namespace | } // end of namespace | ||||
#if defined(WIN32) | #if defined(WIN32) | ||||
@@ -25,6 +25,8 @@ | |||||
#include <process.h> | #include <process.h> | ||||
#endif | #endif | ||||
#include "JackConstants.h" | |||||
namespace Jack | namespace Jack | ||||
{ | { | ||||
@@ -54,7 +56,7 @@ const char* JackTools::DefaultServerName() | |||||
{ | { | ||||
const char* server_name; | const char* server_name; | ||||
if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) | if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) | ||||
server_name = "default"; | |||||
server_name = JACK_DEFAULT_SERVER_NAME; | |||||
return server_name; | return server_name; | ||||
} | } | ||||
@@ -21,38 +21,56 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
#include <iostream> | #include <iostream> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <pwd.h> | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <dirent.h> | |||||
#include <getopt.h> | #include <getopt.h> | ||||
#include "JackServer.h" | |||||
#include <string.h> | |||||
#include "jack.h" | |||||
#include "JackConstants.h" | #include "JackConstants.h" | ||||
#include "driver_interface.h" | |||||
#include "JackDriverLoader.h" | #include "JackDriverLoader.h" | ||||
#include "jslist.h" | |||||
#include "JackError.h" | |||||
#include "JackTools.h" | |||||
#include "shm.h" | |||||
#include "jack.h" | |||||
/* | |||||
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: | |||||
- dynamically retrieve available server parameters and then prepare to parse them | |||||
- get available drivers and their possible parameters, then prepare to parse them. | |||||
*/ | |||||
#ifdef __APPLE_ | #ifdef __APPLE_ | ||||
#include <CoreFoundation/CFNotificationCenter.h> | #include <CoreFoundation/CFNotificationCenter.h> | ||||
#endif | |||||
using namespace Jack; | |||||
static void notify_server_start(const char* server_name) | |||||
{ | |||||
// Send notification to be used in the JackRouter plugin | |||||
CFStringRef ref = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); | |||||
CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), | |||||
CFSTR("com.grame.jackserver.start"), | |||||
ref, | |||||
NULL, | |||||
kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); | |||||
CFRelease(ref); | |||||
} | |||||
static void notify_server_stop(const char* server_name) | |||||
{ | |||||
// Send notification to be used in the JackRouter plugin | |||||
CFStringRef ref1 = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); | |||||
CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), | |||||
CFSTR("com.grame.jackserver.stop"), | |||||
ref1, | |||||
NULL, | |||||
kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); | |||||
CFRelease(ref1); | |||||
} | |||||
static JackServer* fServer; | |||||
static char* server_name = NULL; | |||||
static int realtime_priority = 10; | |||||
static int do_mlock = 1; | |||||
static int realtime = 0; | |||||
static int loopback = 0; | |||||
static int temporary = 0; | |||||
static int client_timeout = 0; /* msecs; if zero, use period size. */ | |||||
static int do_unlock = 0; | |||||
static JSList* drivers = NULL; | |||||
static sigset_t signals; | |||||
#else | |||||
static void notify_server_start(const char* server_name) | |||||
{} | |||||
static void notify_server_stop(const char* server_name) | |||||
{} | |||||
#endif | |||||
static void silent_jack_error_callback(const char *desc) | static void silent_jack_error_callback(const char *desc) | ||||
{} | {} | ||||
@@ -87,63 +105,56 @@ static void usage(FILE* file) | |||||
" to display options for each driver\n\n"); | " to display options for each driver\n\n"); | ||||
} | } | ||||
static void DoNothingHandler(int sig) | |||||
// To put in the control.h interface?? | |||||
static jackctl_driver_t * | |||||
jackctl_server_get_driver( | |||||
jackctl_server_t *server, | |||||
const char *driver_name) | |||||
{ | { | ||||
/* this is used by the child (active) process, but it never | |||||
gets called unless we are already shutting down after | |||||
another signal. | |||||
*/ | |||||
char buf[64]; | |||||
snprintf(buf, sizeof(buf), "received signal %d during shutdown(ignored)\n", sig); | |||||
write(1, buf, strlen(buf)); | |||||
} | |||||
const JSList * node_ptr; | |||||
static int JackStart(const char* server_name, jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, int temporary, int time_out_ms, int rt, int priority, int loopback, int verbose) | |||||
{ | |||||
jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); | |||||
fServer = new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, server_name); | |||||
int res = fServer->Open(driver_desc, driver_params); | |||||
return (res < 0) ? res : fServer->Start(); | |||||
} | |||||
node_ptr = jackctl_server_get_drivers_list(server); | |||||
static int JackStop() | |||||
{ | |||||
fServer->Stop(); | |||||
fServer->Close(); | |||||
jack_log("Jackdmp: server close"); | |||||
delete fServer; | |||||
jack_log("Jackdmp: delete server"); | |||||
return 0; | |||||
} | |||||
while (node_ptr) | |||||
{ | |||||
if (strcmp(jackctl_driver_get_name((jackctl_driver_t *)node_ptr->data), driver_name) == 0) | |||||
{ | |||||
return (jackctl_driver_t *)node_ptr->data; | |||||
} | |||||
static int JackDelete() | |||||
{ | |||||
delete fServer; | |||||
jack_log("Jackdmp: delete server"); | |||||
return 0; | |||||
node_ptr = jack_slist_next(node_ptr); | |||||
} | |||||
return NULL; | |||||
} | } | ||||
static void FilterSIGPIPE() | |||||
static jackctl_parameter_t * | |||||
jackctl_get_parameter( | |||||
const JSList * parameters_list, | |||||
const char * parameter_name) | |||||
{ | { | ||||
sigset_t set; | |||||
sigemptyset(&set); | |||||
sigaddset(&set, SIGPIPE); | |||||
//sigprocmask(SIG_BLOCK, &set, 0); | |||||
pthread_sigmask(SIG_BLOCK, &set, 0); | |||||
while (parameters_list) | |||||
{ | |||||
if (strcmp(jackctl_parameter_get_name((jackctl_parameter_t *)parameters_list->data), parameter_name) == 0) | |||||
{ | |||||
return (jackctl_parameter_t *)parameters_list->data; | |||||
} | |||||
parameters_list = jack_slist_next(parameters_list); | |||||
} | |||||
return NULL; | |||||
} | } | ||||
int main(int argc, char* argv[]) | int main(int argc, char* argv[]) | ||||
{ | { | ||||
int sig; | |||||
sigset_t allsignals; | |||||
struct sigaction action; | |||||
int waiting; | |||||
jack_driver_desc_t* driver_desc; | |||||
jackctl_server_t * server_ctl; | |||||
const JSList * server_parameters; | |||||
const char* server_name = "default"; | |||||
jackctl_driver_t * driver_ctl; | |||||
const char *options = "-ad:P:uvrshVRL:STFl:t:mn:"; | const char *options = "-ad:P:uvrshVRL:STFl:t:mn:"; | ||||
struct option long_options[] = { | struct option long_options[] = { | ||||
{ "driver", 1, 0, 'd'}, | |||||
{ "driver", 1, 0, 'd' }, | |||||
{ "verbose", 0, 0, 'v' }, | { "verbose", 0, 0, 'v' }, | ||||
{ "help", 0, 0, 'h' }, | { "help", 0, 0, 'h' }, | ||||
{ "port-max", 1, 0, 'p' }, | { "port-max", 1, 0, 'p' }, | ||||
@@ -161,17 +172,26 @@ int main(int argc, char* argv[]) | |||||
{ "sync", 0, 0, 'S' }, | { "sync", 0, 0, 'S' }, | ||||
{ 0, 0, 0, 0 } | { 0, 0, 0, 0 } | ||||
}; | }; | ||||
int opt = 0; | |||||
int i,opt = 0; | |||||
int option_index = 0; | int option_index = 0; | ||||
int seen_driver = 0; | |||||
bool seen_driver = false; | |||||
char *driver_name = NULL; | char *driver_name = NULL; | ||||
char **driver_args = NULL; | char **driver_args = NULL; | ||||
JSList* driver_params; | |||||
int driver_nargs = 1; | int driver_nargs = 1; | ||||
int show_version = 0; | |||||
int replace_registry = 0; | |||||
int sync = 0; | |||||
int rc, i; | |||||
bool show_version = false; | |||||
sigset_t signals; | |||||
jackctl_parameter_t* param; | |||||
union jackctl_parameter_value value; | |||||
copyright(stdout); | |||||
server_ctl = jackctl_server_create(); | |||||
if (server_ctl == NULL) { | |||||
fprintf(stderr, "Failed to create server object"); | |||||
return -1; | |||||
} | |||||
server_parameters = jackctl_server_get_parameters(server_ctl); | |||||
opterr = 0; | opterr = 0; | ||||
while (!seen_driver && | while (!seen_driver && | ||||
@@ -180,12 +200,16 @@ int main(int argc, char* argv[]) | |||||
switch (opt) { | switch (opt) { | ||||
case 'd': | case 'd': | ||||
seen_driver = 1; | |||||
seen_driver = true; | |||||
driver_name = optarg; | driver_name = optarg; | ||||
break; | break; | ||||
case 'v': | case 'v': | ||||
jack_verbose = 1; | |||||
param = jackctl_get_parameter(server_parameters, "verbose"); | |||||
if (param != NULL) { | |||||
value.b = true; | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 's': | case 's': | ||||
@@ -193,80 +217,98 @@ int main(int argc, char* argv[]) | |||||
break; | break; | ||||
case 'S': | case 'S': | ||||
sync = 1; | |||||
param = jackctl_get_parameter(server_parameters, "sync"); | |||||
if (param != NULL) { | |||||
value.b = true; | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 'n': | case 'n': | ||||
server_name = optarg; | server_name = optarg; | ||||
break; | |||||
case 'm': | |||||
do_mlock = 0; | |||||
param = jackctl_get_parameter(server_parameters, "name"); | |||||
if (param != NULL) { | |||||
strncpy(value.str, optarg, JACK_PARAM_STRING_MAX); | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 'P': | case 'P': | ||||
realtime_priority = atoi(optarg); | |||||
param = jackctl_get_parameter(server_parameters, "realtime-priority"); | |||||
if (param != NULL) { | |||||
value.i = atoi(optarg); | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 'r': | case 'r': | ||||
replace_registry = 1; | |||||
param = jackctl_get_parameter(server_parameters, "replace-registry"); | |||||
if (param != NULL) { | |||||
value.b = true; | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 'R': | case 'R': | ||||
realtime = 1; | |||||
param = jackctl_get_parameter(server_parameters, "realtime"); | |||||
if (param != NULL) { | |||||
value.b = true; | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 'L': | case 'L': | ||||
loopback = atoi(optarg); | |||||
param = jackctl_get_parameter(server_parameters, "loopback ports"); | |||||
if (param != NULL) { | |||||
value.ui = atoi(optarg); | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 'T': | case 'T': | ||||
temporary = 1; | |||||
param = jackctl_get_parameter(server_parameters, "temporary"); | |||||
if (param != NULL) { | |||||
value.b = true; | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 't': | case 't': | ||||
client_timeout = atoi(optarg); | |||||
break; | |||||
case 'u': | |||||
do_unlock = 1; | |||||
param = jackctl_get_parameter(server_parameters, "client-timeout"); | |||||
if (param != NULL) { | |||||
value.i = atoi(optarg); | |||||
jackctl_parameter_set_value(param, &value); | |||||
} | |||||
break; | break; | ||||
case 'V': | case 'V': | ||||
show_version = 1; | |||||
show_version = true; | |||||
break; | break; | ||||
default: | default: | ||||
fprintf(stderr, "unknown option character %c\n", | |||||
optopt); | |||||
fprintf(stderr, "unknown option character %c\n", optopt); | |||||
/*fallthru*/ | /*fallthru*/ | ||||
case 'h': | case 'h': | ||||
usage(stdout); | usage(stdout); | ||||
return -1; | |||||
goto fail_free; | |||||
} | } | ||||
} | } | ||||
if (show_version) { | |||||
printf("jackdmp version " VERSION | |||||
if (show_version) { | |||||
printf("jackdmp version" VERSION | |||||
"\n"); | "\n"); | ||||
return -1; | return -1; | ||||
} | } | ||||
if (!seen_driver) { | if (!seen_driver) { | ||||
usage(stderr); | usage(stderr); | ||||
exit(1); | |||||
} | |||||
drivers = jack_drivers_load(drivers); | |||||
if (!drivers) { | |||||
fprintf(stderr, "jackdmp: no drivers found; exiting\n"); | |||||
exit(1); | |||||
goto fail_free; | |||||
} | } | ||||
driver_desc = jack_find_driver_descriptor(drivers, driver_name); | |||||
if (!driver_desc) { | |||||
fprintf(stderr, "jackdmp: unknown driver '%s'\n", driver_name); | |||||
exit(1); | |||||
driver_ctl = jackctl_server_get_driver(server_ctl, driver_name); | |||||
if (driver_ctl == NULL) { | |||||
fprintf(stderr, "Unkown driver \"%s\"\n", driver_name); | |||||
goto fail_free; | |||||
} | } | ||||
if (optind < argc) { | if (optind < argc) { | ||||
@@ -278,7 +320,7 @@ int main(int argc, char* argv[]) | |||||
if (driver_nargs == 0) { | if (driver_nargs == 0) { | ||||
fprintf(stderr, "No driver specified ... hmm. JACK won't do" | fprintf(stderr, "No driver specified ... hmm. JACK won't do" | ||||
" anything when run like this.\n"); | " anything when run like this.\n"); | ||||
return -1; | |||||
goto fail_free; | |||||
} | } | ||||
driver_args = (char **) malloc(sizeof(char *) * driver_nargs); | driver_args = (char **) malloc(sizeof(char *) * driver_nargs); | ||||
@@ -288,132 +330,27 @@ int main(int argc, char* argv[]) | |||||
driver_args[i] = argv[optind++]; | driver_args[i] = argv[optind++]; | ||||
} | } | ||||
if (jack_parse_driver_params(driver_desc, driver_nargs, | |||||
driver_args, &driver_params)) { | |||||
exit(0); | |||||
} | |||||
if (server_name == NULL) | |||||
server_name = (char*)JackTools::DefaultServerName(); | |||||
copyright(stdout); | |||||
rc = jack_register_server(server_name, replace_registry); | |||||
switch (rc) { | |||||
case EEXIST: | |||||
fprintf(stderr, "`%s' server already active\n", server_name); | |||||
exit(1); | |||||
case ENOSPC: | |||||
fprintf(stderr, "too many servers already active\n"); | |||||
exit(2); | |||||
case ENOMEM: | |||||
fprintf(stderr, "no access to shm registry\n"); | |||||
exit(3); | |||||
default: | |||||
if (jack_verbose) | |||||
fprintf(stderr, "server `%s' registered\n", server_name); | |||||
} | |||||
/* clean up shared memory and files from any previous | |||||
* instance of this server name */ | |||||
jack_cleanup_shm(); | |||||
JackTools::CleanupFiles(server_name); | |||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); | |||||
sigemptyset(&signals); | |||||
sigaddset(&signals, SIGHUP); | |||||
sigaddset(&signals, SIGINT); | |||||
sigaddset(&signals, SIGQUIT); | |||||
sigaddset(&signals, SIGPIPE); | |||||
sigaddset(&signals, SIGTERM); | |||||
sigaddset(&signals, SIGUSR1); | |||||
sigaddset(&signals, SIGUSR2); | |||||
// all child threads will inherit this mask unless they | |||||
// explicitly reset it | |||||
FilterSIGPIPE(); | |||||
pthread_sigmask(SIG_BLOCK, &signals, 0); | |||||
if (!realtime && client_timeout == 0) | |||||
client_timeout = 500; /* 0.5 sec; usable when non realtime. */ | |||||
int res = JackStart(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, loopback, jack_verbose); | |||||
if (res < 0) { | |||||
jack_error("Cannot start server... exit"); | |||||
JackDelete(); | |||||
return 0; | |||||
} | |||||
#ifdef __APPLE__ | |||||
CFStringRef ref = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); | |||||
// Send notification to be used in the JackRouter plugin | |||||
CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), | |||||
CFSTR("com.grame.jackserver.start"), | |||||
ref, | |||||
NULL, | |||||
kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); | |||||
CFRelease(ref); | |||||
#endif | |||||
// install a do-nothing handler because otherwise pthreads | |||||
// behaviour is undefined when we enter sigwait. | |||||
sigfillset(&allsignals); | |||||
action.sa_handler = DoNothingHandler; | |||||
action.sa_mask = allsignals; | |||||
action.sa_flags = SA_RESTART | SA_RESETHAND; | |||||
for (i = 1; i < NSIG; i++) { | |||||
if (sigismember(&signals, i)) { | |||||
sigaction(i, &action, 0); | |||||
} | |||||
} | |||||
waiting = TRUE; | |||||
while (waiting) { | |||||
sigwait(&signals, &sig); | |||||
fprintf(stderr, "jack main caught signal %d\n", sig); | |||||
switch (sig) { | |||||
case SIGUSR1: | |||||
//jack_dump_configuration(engine, 1); | |||||
break; | |||||
case SIGUSR2: | |||||
// driver exit | |||||
waiting = FALSE; | |||||
break; | |||||
default: | |||||
waiting = FALSE; | |||||
break; | |||||
} | |||||
if (jackctl_parse_driver_params(driver_ctl, driver_nargs, driver_args)) { | |||||
goto fail_free; | |||||
} | } | ||||
if (sig != SIGSEGV) { | |||||
// unblock signals so we can see them during shutdown. | |||||
// this will help prod developers not to lose sight of | |||||
// bugs that cause segfaults etc. during shutdown. | |||||
sigprocmask(SIG_UNBLOCK, &signals, 0); | |||||
if (!jackctl_server_start(server_ctl, driver_ctl)) { | |||||
fprintf(stderr,"Failed to start server"); | |||||
goto fail_free; | |||||
} | } | ||||
JackStop(); | |||||
jack_cleanup_shm(); | |||||
JackTools::CleanupFiles(server_name); | |||||
jack_unregister_server(server_name); | |||||
#ifdef __APPLE__ | |||||
CFStringRef ref1 = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman); | |||||
// Send notification to be used in the JackRouter plugin | |||||
CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), | |||||
CFSTR("com.grame.jackserver.stop"), | |||||
ref1, | |||||
NULL, | |||||
kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); | |||||
CFRelease(ref1); | |||||
#endif | |||||
notify_server_start(server_name); | |||||
// Waits for signal | |||||
signals = jackctl_setup_signals(0); | |||||
jackctl_wait_signals(signals); | |||||
if (!jackctl_server_stop(server_ctl)) | |||||
fprintf(stderr,"Cannot stop server..."); | |||||
fail_free: | |||||
jackctl_server_destroy(server_ctl); | |||||
notify_server_stop(server_name); | |||||
return 1; | return 1; | ||||
} | } |
@@ -23,6 +23,31 @@ import os | |||||
import glob | import glob | ||||
from string import Template | from string import Template | ||||
def pkg_config_get_value(module, args): | |||||
return env.backtick('pkg-config ' + args + ' ' + module).strip() | |||||
def merge_pkg_config_append_string(env, envvar, module, args): | |||||
value = pkg_config_get_value(module, args) | |||||
#print value | |||||
if env._dict.has_key(envvar): | |||||
env._dict[envvar] += value | |||||
else: | |||||
env._dict[envvar] = value | |||||
def merge_pkg_config_libs(env, module): | |||||
for lib in pkg_config_get_value(module, "--libs").split(' '): | |||||
if lib[:2] == '-l': | |||||
env._dict['LIBS'].append(lib[2:]) | |||||
elif lib[:2] == '-L': | |||||
env._dict['LIBPATH'].append(lib[2:]) | |||||
def merge_pkg_config_variable(env, envvar, module, pkgvar): | |||||
merge_pkg_config_append_string(env, envvar, module, '--variable=' + pkgvar) | |||||
def merge_pkg_config_std(env, module): | |||||
merge_pkg_config_append_string(env, 'CCFLAGS', module, '--cflags') | |||||
merge_pkg_config_libs(env, module) | |||||
Import('env') | Import('env') | ||||
@@ -51,7 +76,7 @@ srcfiles_common_serverlib = [ | |||||
'JackDriver.cpp', | 'JackDriver.cpp', | ||||
'JackEngine.cpp', | 'JackEngine.cpp', | ||||
'JackEngineControl.cpp', | 'JackEngineControl.cpp', | ||||
'JackError.c', | |||||
'JackError.cpp', | |||||
'JackExternalClient.cpp', | 'JackExternalClient.cpp', | ||||
'JackFrameTimer.cpp', | 'JackFrameTimer.cpp', | ||||
'JackFreewheelDriver.cpp', | 'JackFreewheelDriver.cpp', | ||||
@@ -85,7 +110,10 @@ srcfiles_common_serverlib = [ | |||||
'JackServerLaunch.cpp', | 'JackServerLaunch.cpp', | ||||
'timestamps.c', | 'timestamps.c', | ||||
'JackTools.cpp', | 'JackTools.cpp', | ||||
'ringbuffer.c' | |||||
'ringbuffer.c', | |||||
'JackControl.cpp', | |||||
'JackMessageBuffer.cpp', | |||||
'JackProcessSync.cpp' | |||||
] | ] | ||||
srcfiles_common_clientlib = [ | srcfiles_common_clientlib = [ | ||||
@@ -95,7 +123,7 @@ srcfiles_common_clientlib = [ | |||||
'JackConnectionManager.cpp', | 'JackConnectionManager.cpp', | ||||
'ringbuffer.c', | 'ringbuffer.c', | ||||
'JackServerLaunch.cpp', | 'JackServerLaunch.cpp', | ||||
'JackError.c', | |||||
'JackError.cpp', | |||||
'JackFrameTimer.cpp', | 'JackFrameTimer.cpp', | ||||
'JackGlobalsClient.cpp', | 'JackGlobalsClient.cpp', | ||||
'JackGraphManager.cpp', | 'JackGraphManager.cpp', | ||||
@@ -119,7 +147,9 @@ srcfiles_common_clientlib = [ | |||||
'JackDebugClient.cpp', | 'JackDebugClient.cpp', | ||||
'JackTransportEngine.cpp', | 'JackTransportEngine.cpp', | ||||
'timestamps.c', | 'timestamps.c', | ||||
'JackTools.cpp' | |||||
'JackTools.cpp', | |||||
'JackMessageBuffer.cpp', | |||||
'JackProcessSync.cpp' | |||||
] | ] | ||||
jack_headers = [ | jack_headers = [ | ||||
@@ -130,7 +160,9 @@ jack_headers = [ | |||||
'statistics.h', | 'statistics.h', | ||||
'thread.h', | 'thread.h', | ||||
'transport.h', | 'transport.h', | ||||
'types.h' | |||||
'types.h', | |||||
'control.h', | |||||
'jslist.h' | |||||
] | ] | ||||
# | # | ||||
@@ -138,6 +170,10 @@ jack_headers = [ | |||||
# | # | ||||
# Libraries | # Libraries | ||||
if env['ENABLE_DBUS']: | |||||
merge_pkg_config_std(env, 'dbus-1') # actually we need this only for client lib | |||||
# Each platform should get it's own environment | # Each platform should get it's own environment | ||||
libenv = env.Copy() | libenv = env.Copy() | ||||
if env['PLATFORM'] == 'posix': | if env['PLATFORM'] == 'posix': | ||||
@@ -41,6 +41,34 @@ extern "C" | |||||
* Note: More documentation can be found in jack/types.h. | * Note: More documentation can be found in jack/types.h. | ||||
*/ | */ | ||||
/** | |||||
* Call this function to get version of the JACK, in form of several numbers | |||||
* | |||||
* @param major_ptr pointer to variable receiving major version of JACK. | |||||
* | |||||
* @param minor_ptr pointer to variable receiving minor version of JACK. | |||||
* | |||||
* @param major_ptr pointer to variable receiving micro version of JACK. | |||||
* | |||||
* @param major_ptr pointer to variable receiving protocol version of JACK. | |||||
* | |||||
*/ | |||||
void | |||||
jack_get_version( | |||||
int *major_ptr, | |||||
int *minor_ptr, | |||||
int *micro_ptr, | |||||
int *proto_ptr); | |||||
/** | |||||
* Call this function to get version of the JACK, in form of a string | |||||
* | |||||
* @return Human readable string describing JACK version being used. | |||||
* | |||||
*/ | |||||
const char * | |||||
jack_get_version_string(); | |||||
/** | /** | ||||
* Open an external client session with a JACK server. This interface | * Open an external client session with a JACK server. This interface | ||||
* is more complex but more powerful than jack_client_new(). With it, | * is more complex but more powerful than jack_client_new(). With it, | ||||
@@ -513,6 +541,11 @@ extern "C" | |||||
* including a final NULL. | * including a final NULL. | ||||
*/ | */ | ||||
const char * jack_port_type (const jack_port_t *port); | const char * jack_port_type (const jack_port_t *port); | ||||
/** | |||||
* @return the @a port type id. | |||||
*/ | |||||
jack_port_type_id_t jack_port_type_id (const jack_port_t *port); | |||||
/** | /** | ||||
* @return TRUE if the jack_port_t belongs to the jack_client_t. | * @return TRUE if the jack_port_t belongs to the jack_client_t. | ||||
@@ -19,10 +19,12 @@ | |||||
*/ | */ | ||||
#ifndef __jack_types_h__ | #ifndef __jack_types_h__ | ||||
#define __jack_types_h__ | |||||
#define __jack_types_h__ | |||||
#ifdef WIN32 | |||||
#include <windows.h> | |||||
#ifdef WIN32 | |||||
#include <windows.h> | |||||
#define vsnprintf _vsnprintf | |||||
#define snprintf _snprintf | |||||
#ifndef __MINGW32__ | #ifndef __MINGW32__ | ||||
typedef long int32_t; | typedef long int32_t; | ||||
typedef unsigned long uint32_t; | typedef unsigned long uint32_t; | ||||
@@ -97,6 +99,8 @@ typedef uint64_t jack_port_id_t; | |||||
typedef uint32_t jack_port_id_t; | typedef uint32_t jack_port_id_t; | ||||
#endif | #endif | ||||
typedef uint32_t jack_port_type_id_t; | |||||
/** | /** | ||||
* Prototype for the client supplied function that is called | * Prototype for the client supplied function that is called | ||||
* by the engine anytime there is work to be done. | * by the engine anytime there is work to be done. | ||||
@@ -1,287 +0,0 @@ | |||||
/* | |||||
Based on gslist.c from glib-1.2.9 (LGPL). | |||||
Adaption to JACK, Copyright (C) 2002 Kai Vehmanen. | |||||
- replaced use of gtypes with normal ANSI C types | |||||
- glib's memory allocation routines replaced with | |||||
malloc/free calls | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser General Public License as published by | |||||
the Free Software Foundation; either version 2.1 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser General Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
*/ | |||||
#ifndef __jack_jslist_h__ | |||||
#define __jack_jslist_h__ | |||||
#include <stdlib.h> | |||||
#ifdef WIN32 | |||||
#define __inline__ inline | |||||
#endif | |||||
typedef struct _JSList JSList; | |||||
typedef int (*JCompareFunc) (void* a, void* b); | |||||
struct _JSList | |||||
{ | |||||
void *data; | |||||
JSList *next; | |||||
}; | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_alloc (void) | |||||
{ | |||||
JSList *new_list; | |||||
new_list = (JSList*)malloc(sizeof(JSList)); | |||||
new_list->data = NULL; | |||||
new_list->next = NULL; | |||||
return new_list; | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_prepend (JSList* list, void* data) | |||||
{ | |||||
JSList *new_list; | |||||
new_list = (JSList*)malloc(sizeof(JSList)); | |||||
new_list->data = data; | |||||
new_list->next = list; | |||||
return new_list; | |||||
} | |||||
#define jack_slist_next(slist) ((slist) ? (((JSList *)(slist))->next) : NULL) | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_last (JSList *list) | |||||
{ | |||||
if (list) { | |||||
while (list->next) | |||||
list = list->next; | |||||
} | |||||
return list; | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_remove_link (JSList *list, | |||||
JSList *link) | |||||
{ | |||||
JSList *tmp; | |||||
JSList *prev; | |||||
prev = NULL; | |||||
tmp = list; | |||||
while (tmp) { | |||||
if (tmp == link) { | |||||
if (prev) | |||||
prev->next = tmp->next; | |||||
if (list == tmp) | |||||
list = list->next; | |||||
tmp->next = NULL; | |||||
break; | |||||
} | |||||
prev = tmp; | |||||
tmp = tmp->next; | |||||
} | |||||
return list; | |||||
} | |||||
static __inline__ | |||||
void | |||||
jack_slist_free (JSList *list) | |||||
{ | |||||
while (list) { | |||||
JSList *next = list->next; | |||||
free(list); | |||||
list = next; | |||||
} | |||||
} | |||||
static __inline__ | |||||
void | |||||
jack_slist_free_1 (JSList *list) | |||||
{ | |||||
if (list) { | |||||
free(list); | |||||
} | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_remove (JSList *list, | |||||
void *data) | |||||
{ | |||||
JSList *tmp; | |||||
JSList *prev; | |||||
prev = NULL; | |||||
tmp = list; | |||||
while (tmp) { | |||||
if (tmp->data == data) { | |||||
if (prev) | |||||
prev->next = tmp->next; | |||||
if (list == tmp) | |||||
list = list->next; | |||||
tmp->next = NULL; | |||||
jack_slist_free (tmp); | |||||
break; | |||||
} | |||||
prev = tmp; | |||||
tmp = tmp->next; | |||||
} | |||||
return list; | |||||
} | |||||
static __inline__ | |||||
unsigned int | |||||
jack_slist_length (JSList *list) | |||||
{ | |||||
unsigned int length; | |||||
length = 0; | |||||
while (list) { | |||||
length++; | |||||
list = list->next; | |||||
} | |||||
return length; | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_find (JSList *list, | |||||
void *data) | |||||
{ | |||||
while (list) { | |||||
if (list->data == data) | |||||
break; | |||||
list = list->next; | |||||
} | |||||
return list; | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_copy (JSList *list) | |||||
{ | |||||
JSList *new_list = NULL; | |||||
if (list) { | |||||
JSList *last; | |||||
new_list = jack_slist_alloc (); | |||||
new_list->data = list->data; | |||||
last = new_list; | |||||
list = list->next; | |||||
while (list) { | |||||
last->next = jack_slist_alloc (); | |||||
last = last->next; | |||||
last->data = list->data; | |||||
list = list->next; | |||||
} | |||||
} | |||||
return new_list; | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_append (JSList *list, | |||||
void *data) | |||||
{ | |||||
JSList *new_list; | |||||
JSList *last; | |||||
new_list = jack_slist_alloc (); | |||||
new_list->data = data; | |||||
if (list) { | |||||
last = jack_slist_last (list); | |||||
last->next = new_list; | |||||
return list; | |||||
} else | |||||
return new_list; | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_sort_merge (JSList *l1, | |||||
JSList *l2, | |||||
JCompareFunc compare_func) | |||||
{ | |||||
JSList list, *l; | |||||
l = &list; | |||||
while (l1 && l2) { | |||||
if (compare_func(l1->data, l2->data) < 0) { | |||||
l = l->next = l1; | |||||
l1 = l1->next; | |||||
} else { | |||||
l = l->next = l2; | |||||
l2 = l2->next; | |||||
} | |||||
} | |||||
l->next = l1 ? l1 : l2; | |||||
return list.next; | |||||
} | |||||
static __inline__ | |||||
JSList* | |||||
jack_slist_sort (JSList *list, | |||||
JCompareFunc compare_func) | |||||
{ | |||||
JSList *l1, *l2; | |||||
if (!list) | |||||
return NULL; | |||||
if (!list->next) | |||||
return list; | |||||
l1 = list; | |||||
l2 = list->next; | |||||
while ((l2 = l2->next) != NULL) { | |||||
if ((l2 = l2->next) == NULL) | |||||
break; | |||||
l1 = l1->next; | |||||
} | |||||
l2 = l1->next; | |||||
l1->next = NULL; | |||||
return jack_slist_sort_merge (jack_slist_sort (list, compare_func), | |||||
jack_slist_sort (l2, compare_func), | |||||
compare_func); | |||||
} | |||||
#endif /* __jack_jslist_h__ */ |
@@ -192,7 +192,7 @@ INLINE_INFO = YES | |||||
# alphabetically by member name. If set to NO the members will appear in | # alphabetically by member name. If set to NO the members will appear in | ||||
# declaration order. | # declaration order. | ||||
SORT_MEMBER_DOCS = YES | |||||
SORT_MEMBER_DOCS = NO | |||||
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC | # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC | ||||
# tag is set to YES, then doxygen will reuse the documentation of the first | # tag is set to YES, then doxygen will reuse the documentation of the first | ||||
@@ -304,7 +304,7 @@ WARN_LOGFILE = | |||||
# directories like "/usr/src/myproject". Separate the files or directories | # directories like "/usr/src/myproject". Separate the files or directories | ||||
# with spaces. | # with spaces. | ||||
INPUT = common macosx linux/alsa windows | |||||
INPUT = common macosx linux/alsa windows common/jack/control.h | |||||
# If the value of the INPUT tag contains directories, you can use the | # If the value of the INPUT tag contains directories, you can use the | ||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp | # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp | ||||
@@ -82,3 +82,6 @@ if env['BUILD_EXAMPLES']: | |||||
if clientenv['INSTALL_EXAMPLES']: | if clientenv['INSTALL_EXAMPLES']: | ||||
env.InstallAs(env['INSTALL_ADDON_DIR'] + '/' + example_lib + '.so', lib) | env.InstallAs(env['INSTALL_ADDON_DIR'] + '/' + example_lib + '.so', lib) | ||||
env.Alias('install', env['INSTALL_ADDON_DIR'] + '/' + example_lib + '.so') | env.Alias('install', env['INSTALL_ADDON_DIR'] + '/' + example_lib + '.so') | ||||
if env['ENABLE_DBUS']: | |||||
clientenv.Install(env['BINDIR'], 'jack_control') |
@@ -435,7 +435,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic | |||||
handle, hw_params, formats[format].format)) < 0) { | handle, hw_params, formats[format].format)) < 0) { | ||||
if ((sample_width == 4 | if ((sample_width == 4 | ||||
? format++ >= NUMFORMATS - 1 | |||||
? format++ >= (int)NUMFORMATS - 1 | |||||
: format-- <= 0)) { | : format-- <= 0)) { | ||||
jack_error ("Sorry. The audio interface \"%s\"" | jack_error ("Sorry. The audio interface \"%s\"" | ||||
" doesn't support any of the" | " doesn't support any of the" | ||||
@@ -450,7 +450,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic | |||||
} else { | } else { | ||||
driver->quirk_bswap = 0; | driver->quirk_bswap = 0; | ||||
} | } | ||||
jack_error ("ALSA: final selected sample format for %s: %s", stream_name, formats[format].Name); | |||||
jack_info ("ALSA: final selected sample format for %s: %s", stream_name, formats[format].Name); | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -524,7 +524,7 @@ JackAlsaDriver::alsa_driver_configure_stream (alsa_driver_t *driver, char *devic | |||||
stream_name); | stream_name); | ||||
return -1; | return -1; | ||||
} | } | ||||
jack_error ("ALSA: use %d periods for %s", *nperiodsp, stream_name); | |||||
jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name); | |||||
/* | /* | ||||
if (!jack_power_of_two(driver->frames_per_cycle)) { | if (!jack_power_of_two(driver->frames_per_cycle)) { | ||||
@@ -1782,6 +1782,11 @@ JackAlsaDriver::alsa_driver_delete (alsa_driver_t *driver) | |||||
driver->ctl_handle = 0; | driver->ctl_handle = 0; | ||||
} | } | ||||
if (driver->ctl_handle) { | |||||
snd_ctl_close (driver->ctl_handle); | |||||
driver->ctl_handle = 0; | |||||
} | |||||
if (driver->capture_handle) { | if (driver->capture_handle) { | ||||
snd_pcm_close (driver->capture_handle); | snd_pcm_close (driver->capture_handle); | ||||
driver->capture_handle = 0; | driver->capture_handle = 0; | ||||
@@ -2159,7 +2164,7 @@ int JackAlsaDriver::Attach() | |||||
// Monitor ports | // Monitor ports | ||||
if (fWithMonitorPorts) { | if (fWithMonitorPorts) { | ||||
jack_log("Create monitor port "); | jack_log("Create monitor port "); | ||||
snprintf(name, sizeof(name) - 1, "%s:monitor_%lu", fClientControl->fName, i + 1); | |||||
snprintf(name, sizeof(name) - 1, "%s:monitor_%d", fClientControl->fName, i + 1); | |||||
if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { | if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { | ||||
jack_error ("ALSA: cannot register monitor port for %s", name); | jack_error ("ALSA: cannot register monitor port for %s", name); | ||||
} else { | } else { | ||||
@@ -2713,7 +2718,6 @@ extern "C" | |||||
case 'X': | case 'X': | ||||
midi_driver = strdup(param->value.str); | midi_driver = strdup(param->value.str); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -22,6 +22,8 @@ | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" | extern "C" | ||||
{ | { | ||||
#else | |||||
#include <stdbool.h> | |||||
#endif | #endif | ||||
typedef struct alsa_midi_t alsa_midi_t; | typedef struct alsa_midi_t alsa_midi_t; | ||||
@@ -67,17 +67,15 @@ extern "C" | |||||
#if defined(STANDALONE) | #if defined(STANDALONE) | ||||
#define MESSAGE(...) fprintf(stderr, __VA_ARGS__) | #define MESSAGE(...) fprintf(stderr, __VA_ARGS__) | ||||
#elif defined(JACKMP) | |||||
#define MESSAGE(...) fprintf(stderr, __VA_ARGS__) ; fprintf(stderr, "\n") | |||||
#else | |||||
#elif !defined(JACKMP) | |||||
#include <jack/messagebuffer.h> | #include <jack/messagebuffer.h> | ||||
#endif | #endif | ||||
#define info_log(...) MESSAGE(__VA_ARGS__) | |||||
#define error_log(...) MESSAGE(__VA_ARGS__) | |||||
#define info_log(...) jack_info(__VA_ARGS__) | |||||
#define error_log(...) jack_error(__VA_ARGS__) | |||||
#ifdef DEBUG | |||||
#define debug_log(...) MESSAGE(__VA_ARGS__) | |||||
#ifdef ALSA_MIDI_DEBUG | |||||
#define debug_log(...) jack_info(__VA_ARGS__) | |||||
#else | #else | ||||
#define debug_log(...) | #define debug_log(...) | ||||
#endif | #endif | ||||
@@ -35,6 +35,7 @@ | |||||
#include "alsa_midi_impl.h" | #include "alsa_midi_impl.h" | ||||
#include "midi_pack.h" | #include "midi_pack.h" | ||||
#include "midi_unpack.h" | #include "midi_unpack.h" | ||||
#include "JackError.h" | |||||
enum { | enum { | ||||
NANOSLEEP_RESOLUTION = 7000 | NANOSLEEP_RESOLUTION = 7000 | ||||
@@ -628,6 +629,7 @@ void scan_device(scan_t *scan) | |||||
alsa_error("scan: snd_ctl_rawmidi_info on subdevice", err); | alsa_error("scan: snd_ctl_rawmidi_info on subdevice", err); | ||||
continue; | continue; | ||||
} | } | ||||
scan_port_update(scan); | scan_port_update(scan); | ||||
} | } | ||||
} | } | ||||
@@ -665,7 +667,7 @@ midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **lis | |||||
port->next = *list; | port->next = *list; | ||||
*list = port; | *list = port; | ||||
error_log("scan: added port %s %s", port->dev, port->name); | |||||
info_log("scan: added port %s %s", port->dev, port->name); | |||||
return &port->next; | return &port->next; | ||||
} | } | ||||
@@ -689,7 +691,7 @@ midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list) | |||||
port->state = PORT_ADDED_TO_JACK; | port->state = PORT_ADDED_TO_JACK; | ||||
jack_ringbuffer_write(str->jack.new_ports, (char*) &port, sizeof(port)); | jack_ringbuffer_write(str->jack.new_ports, (char*) &port, sizeof(port)); | ||||
error_log("scan: opened port %s %s", port->dev, port->name); | |||||
info_log("scan: opened port %s %s", port->dev, port->name); | |||||
return &port->next; | return &port->next; | ||||
fail_2: | fail_2: | ||||
@@ -709,7 +711,7 @@ midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list) | |||||
{ | { | ||||
midi_port_t *port = *list; | midi_port_t *port = *list; | ||||
if (port->state == PORT_REMOVED_FROM_JACK) { | if (port->state == PORT_REMOVED_FROM_JACK) { | ||||
error_log("scan: deleted port %s %s", port->dev, port->name); | |||||
info_log("scan: deleted port %s %s", port->dev, port->name); | |||||
*list = port->next; | *list = port->next; | ||||
if (port->id.id[2] ) | if (port->id.id[2] ) | ||||
(midi->out.port_close)(midi, port); | (midi->out.port_close)(midi, port); | ||||
@@ -49,6 +49,7 @@ | |||||
#include <ctype.h> | #include <ctype.h> | ||||
#include "alsa_midi_impl.h" | #include "alsa_midi_impl.h" | ||||
#include "JackError.h" | |||||
#define NSEC_PER_SEC ((int64_t)1000*1000*1000) | #define NSEC_PER_SEC ((int64_t)1000*1000*1000) | ||||
@@ -213,6 +213,8 @@ OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice, | |||||
AudioDeviceRemoveIOProc(driver->fDeviceID, MeasureCallback); | AudioDeviceRemoveIOProc(driver->fDeviceID, MeasureCallback); | ||||
jack_log("JackCoreAudioDriver::MeasureCallback called"); | jack_log("JackCoreAudioDriver::MeasureCallback called"); | ||||
JackMachThread::GetParams(&driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); | JackMachThread::GetParams(&driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); | ||||
// Setup threadded based log function | |||||
set_threaded_log_function(); | |||||
return noErr; | return noErr; | ||||
} | } | ||||
@@ -245,7 +247,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, | |||||
void* inClientData) | void* inClientData) | ||||
{ | { | ||||
JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; | JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; | ||||
switch (inPropertyID) { | switch (inPropertyID) { | ||||
case kAudioDeviceProcessorOverload: | case kAudioDeviceProcessorOverload: | ||||
@@ -33,38 +33,27 @@ env.AppendUnique(CPPPATH=['#/', '#/common']) | |||||
test_programs = { | test_programs = { | ||||
'synchroClient': [ | 'synchroClient': [ | ||||
'testSynchroClient.cpp', | |||||
'#/common/JackPosixSemaphore.cpp', | |||||
'#/common/JackPosixThread.cpp', | |||||
'#/common/JackError.c', | |||||
'#/common/JackFifo.cpp' | |||||
'testSynchroClient.cpp' | |||||
], | ], | ||||
'synchroServer': [ | 'synchroServer': [ | ||||
'testSynchroServer.cpp', | |||||
'#/common/JackPosixSemaphore.cpp', | |||||
'#/common/JackPosixThread.cpp', | |||||
'#/common/JackError.c', | |||||
'#/common/JackFifo.cpp' | |||||
'testSynchroServer.cpp' | |||||
], | ], | ||||
'synchroServerClient': [ | 'synchroServerClient': [ | ||||
'testSynchroServerClient.cpp', | |||||
'#/common/JackPosixSemaphore.cpp', | |||||
'#/common/JackPosixThread.cpp', | |||||
'#/common/JackError.c', | |||||
'#/common/JackFifo.cpp' | |||||
], | |||||
'testSynchroServerClient.cpp' | |||||
], | |||||
'testSem': [ | 'testSem': [ | ||||
'testSem.cpp', | |||||
'#/common/JackPosixSemaphore.cpp', | |||||
'#/common/JackPosixThread.cpp', | |||||
'#/common/JackError.c', | |||||
'#/common/JackFifo.cpp' | |||||
'testSem.cpp' | |||||
], | ], | ||||
'jack_test': [ | 'jack_test': [ | ||||
'jack_test.cpp' | 'jack_test.cpp' | ||||
], | ], | ||||
} | } | ||||
# Libraries to link | |||||
extra_libs = {} | |||||
for test_program in test_programs: | |||||
extra_libs[test_program] = ['jackserver'] | |||||
# | # | ||||
# Build section | # Build section | ||||
# | # | ||||
@@ -20,6 +20,7 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | |||||
#ifdef __APPLE__ | #ifdef __APPLE__ | ||||
#include "JackMachSemaphore.h" | #include "JackMachSemaphore.h" | ||||
@@ -221,6 +221,8 @@ int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, | |||||
driver->fLastWaitUst = GetMicroSeconds(); // Take callback date here | driver->fLastWaitUst = GetMicroSeconds(); // Take callback date here | ||||
driver->fInputBuffer = (float**)inputBuffer; | driver->fInputBuffer = (float**)inputBuffer; | ||||
driver->fOutputBuffer = (float**)outputBuffer; | driver->fOutputBuffer = (float**)outputBuffer; | ||||
// Setup threadded based log function | |||||
set_threaded_log_function(); | |||||
return (driver->Process() == 0) ? paContinue : paAbort; | return (driver->Process() == 0) ? paContinue : paAbort; | ||||
} | } | ||||
@@ -62,17 +62,10 @@ class JackWinProcessSync : public JackSyncInterface | |||||
void Destroy() | void Destroy() | ||||
{} | {} | ||||
bool TimedWait(long usec) | |||||
{ | |||||
DWORD res = WaitForSingleObject(fEvent, usec / 1000); | |||||
return (res == WAIT_OBJECT_0); | |||||
} | |||||
void Wait() | |||||
{ | |||||
WaitForSingleObject(fEvent, INFINITE); | |||||
} | |||||
bool TimedWait(long usec); | |||||
void Wait(); | |||||
void SignalAll() | void SignalAll() | ||||
{ | { | ||||
SetEvent(fEvent); | SetEvent(fEvent); | ||||
@@ -1,485 +0,0 @@ | |||||
/* | |||||
Copyright (C) 2001 Paul Davis | |||||
Copyright (C) 2004-2006 Grame | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation; either version 2 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
*/ | |||||
#include <iostream> | |||||
#include <assert.h> | |||||
#include <process.h> | |||||
#include <getopt.h> | |||||
#include <signal.h> | |||||
#include "JackServer.h" | |||||
#include "JackConstants.h" | |||||
#include "driver_interface.h" | |||||
#include "JackDriverLoader.h" | |||||
#include "shm.h" | |||||
using namespace Jack; | |||||
static JackServer* fServer; | |||||
static char *server_name = "default"; | |||||
static int realtime_priority = 10; | |||||
static int do_mlock = 1; | |||||
static int realtime = 0; | |||||
static int loopback = 0; | |||||
static int temporary = 0; | |||||
static int client_timeout = 0; /* msecs; if zero, use period size. */ | |||||
static int do_unlock = 0; | |||||
static JSList* drivers = NULL; | |||||
static int sync = 0; | |||||
static int xverbose = 0; | |||||
#define DEFAULT_TMP_DIR "/tmp" | |||||
char *jack_tmpdir = DEFAULT_TMP_DIR; | |||||
HANDLE waitEvent; | |||||
void jack_print_driver_options (jack_driver_desc_t * desc, FILE *file); | |||||
void jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file); | |||||
int jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr); | |||||
static void silent_jack_error_callback (const char *desc) | |||||
{} | |||||
static void copyright(FILE* file) | |||||
{ | |||||
fprintf (file, "jackdmp " VERSION "\n" | |||||
"Copyright 2001-2005 Paul Davis and others.\n" | |||||
"Copyright 2004-2008 Grame.\n" | |||||
"jackdmp comes with ABSOLUTELY NO WARRANTY\n" | |||||
"This is free software, and you are welcome to redistribute it\n" | |||||
"under certain conditions; see the file COPYING for details\n"); | |||||
} | |||||
static void usage (FILE *file) | |||||
{ | |||||
copyright (file); | |||||
fprintf (file, "\n" | |||||
"usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" | |||||
" [ --name OR -n server-name ]\n" | |||||
" [ --timeout OR -t client-timeout-in-msecs ]\n" | |||||
" [ --loopback OR -L loopback-port-number ]\n" | |||||
" [ --verbose OR -v ]\n" | |||||
" [ --replace-registry OR -r ]\n" | |||||
" [ --silent OR -s ]\n" | |||||
" [ --sync OR -S ]\n" | |||||
" [ --version OR -V ]\n" | |||||
" -d driver [ ... driver args ... ]\n" | |||||
" where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n" | |||||
" jackdmp -d driver --help\n" | |||||
" to display options for each driver\n\n"); | |||||
} | |||||
static int JackStart(jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, int time_out_ms, int rt, int priority, int loopback, int verbose, const char* server_name) | |||||
{ | |||||
printf("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync, time_out_ms, rt, priority, verbose); | |||||
fServer = new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, server_name); | |||||
int res = fServer->Open(driver_desc, driver_params); | |||||
return (res < 0) ? res : fServer->Start(); | |||||
} | |||||
static int JackStop() | |||||
{ | |||||
fServer->Stop(); | |||||
fServer->Close(); | |||||
printf("Jackdmp: server close\n"); | |||||
delete fServer; | |||||
printf("Jackdmp: delete server\n"); | |||||
return 0; | |||||
} | |||||
static int JackDelete() | |||||
{ | |||||
delete fServer; | |||||
printf("Jackdmp: delete server\n"); | |||||
return 0; | |||||
} | |||||
static void intrpt(int signum) | |||||
{ | |||||
printf("jack main caught signal %d\n", signum); | |||||
(void) signal(SIGINT, SIG_DFL); | |||||
SetEvent(waitEvent); | |||||
} | |||||
/* | |||||
static char* jack_default_server_name(void) | |||||
{ | |||||
char *server_name; | |||||
if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) | |||||
server_name = "default"; | |||||
return server_name; | |||||
} | |||||
// returns the name of the per-user subdirectory of jack_tmpdir | |||||
static char* jack_user_dir(void) | |||||
{ | |||||
static char user_dir[PATH_MAX] = ""; | |||||
// format the path name on the first call | |||||
if (user_dir[0] == '\0') { | |||||
snprintf (user_dir, sizeof (user_dir), "%s/jack-%d", | |||||
jack_tmpdir, _getuid ()); | |||||
} | |||||
return user_dir; | |||||
} | |||||
// returns the name of the per-server subdirectory of jack_user_dir() | |||||
static char* get_jack_server_dir(const char * toto) | |||||
{ | |||||
static char server_dir[PATH_MAX] = ""; | |||||
// format the path name on the first call | |||||
if (server_dir[0] == '\0') { | |||||
snprintf (server_dir, sizeof (server_dir), "%s/%s", | |||||
jack_user_dir (), server_name); | |||||
} | |||||
return server_dir; | |||||
} | |||||
static void jack_cleanup_files (const char *server_name) | |||||
{ | |||||
DIR *dir; | |||||
struct dirent *dirent; | |||||
char *dir_name = get_jack_server_dir (server_name); | |||||
// nothing to do if the server directory does not exist | |||||
if ((dir = opendir (dir_name)) == NULL) { | |||||
return; | |||||
} | |||||
// unlink all the files in this directory, they are mine | |||||
while ((dirent = readdir (dir)) != NULL) { | |||||
char fullpath[PATH_MAX]; | |||||
if ((strcmp (dirent->d_name, ".") == 0) | |||||
|| (strcmp (dirent->d_name, "..") == 0)) { | |||||
continue; | |||||
} | |||||
snprintf (fullpath, sizeof (fullpath), "%s/%s", | |||||
dir_name, dirent->d_name); | |||||
if (unlink (fullpath)) { | |||||
jack_error ("cannot unlink `%s' (%s)", fullpath, | |||||
strerror (errno)); | |||||
} | |||||
} | |||||
closedir (dir); | |||||
// now, delete the per-server subdirectory, itself | |||||
if (rmdir (dir_name)) { | |||||
jack_error ("cannot remove `%s' (%s)", dir_name, | |||||
strerror (errno)); | |||||
} | |||||
// finally, delete the per-user subdirectory, if empty | |||||
if (rmdir (jack_user_dir ())) { | |||||
if (errno != ENOTEMPTY) { | |||||
jack_error ("cannot remove `%s' (%s)", | |||||
jack_user_dir (), strerror (errno)); | |||||
} | |||||
} | |||||
} | |||||
*/ | |||||
/* | |||||
BOOL CtrlHandler( DWORD fdwCtrlType ) | |||||
{ | |||||
switch( fdwCtrlType ) | |||||
{ | |||||
// Handle the CTRL-C signal. | |||||
case CTRL_C_EVENT: | |||||
printf( "Ctrl-C event\n\n" ); | |||||
Beep( 750, 300 ); | |||||
SetEvent(waitEvent); | |||||
return( TRUE ); | |||||
// CTRL-CLOSE: confirm that the user wants to exit. | |||||
case CTRL_CLOSE_EVENT: | |||||
Beep( 600, 200 ); | |||||
printf( "Ctrl-Close event\n\n" ); | |||||
SetEvent(waitEvent); | |||||
return( TRUE ); | |||||
// Pass other signals to the next handler. | |||||
case CTRL_BREAK_EVENT: | |||||
Beep( 900, 200 ); | |||||
printf( "Ctrl-Break event\n\n" ); | |||||
return FALSE; | |||||
case CTRL_LOGOFF_EVENT: | |||||
Beep( 1000, 200 ); | |||||
printf( "Ctrl-Logoff event\n\n" ); | |||||
return FALSE; | |||||
case CTRL_SHUTDOWN_EVENT: | |||||
Beep( 750, 500 ); | |||||
printf( "Ctrl-Shutdown event\n\n" ); | |||||
return FALSE; | |||||
default: | |||||
return FALSE; | |||||
} | |||||
} | |||||
*/ | |||||
int main(int argc, char* argv[]) | |||||
{ | |||||
jack_driver_desc_t * driver_desc; | |||||
const char *options = "-ad:P:uvshVRL:STFl:t:mn:"; | |||||
struct option long_options[] = { | |||||
{ "driver", 1, 0, 'd'}, | |||||
{ "verbose", 0, 0, 'v' }, | |||||
{ "help", 0, 0, 'h' }, | |||||
{ "port-max", 1, 0, 'p' }, | |||||
{ "no-mlock", 0, 0, 'm' }, | |||||
{ "name", 0, 0, 'n' }, | |||||
{ "unlock", 0, 0, 'u' }, | |||||
{ "realtime", 0, 0, 'R' }, | |||||
{ "replace-registry", 0, 0, 'r' }, | |||||
{ "loopback", 0, 0, 'L' }, | |||||
{ "realtime-priority", 1, 0, 'P' }, | |||||
{ "timeout", 1, 0, 't' }, | |||||
{ "temporary", 0, 0, 'T' }, | |||||
{ "version", 0, 0, 'V' }, | |||||
{ "silent", 0, 0, 's' }, | |||||
{ "sync", 0, 0, 'S' }, | |||||
{ 0, 0, 0, 0 } | |||||
}; | |||||
int opt = 0; | |||||
int option_index = 0; | |||||
int seen_driver = 0; | |||||
char *driver_name = NULL; | |||||
char **driver_args = NULL; | |||||
JSList * driver_params; | |||||
int driver_nargs = 1; | |||||
int show_version = 0; | |||||
int replace_registry = 0; | |||||
int sync = 0; | |||||
int i; | |||||
int rc; | |||||
char c; | |||||
// Creates wait event | |||||
if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { | |||||
printf("CreateEvent fails err = %ld\n", GetLastError()); | |||||
return 0; | |||||
} | |||||
opterr = 0; | |||||
while (!seen_driver && | |||||
(opt = getopt_long(argc, argv, options, | |||||
long_options, &option_index)) != EOF) { | |||||
switch (opt) { | |||||
case 'd': | |||||
seen_driver = 1; | |||||
driver_name = optarg; | |||||
break; | |||||
case 'v': | |||||
xverbose = 1; | |||||
break; | |||||
case 's': | |||||
// steph | |||||
//jack_set_error_function(silent_jack_error_callback); | |||||
break; | |||||
case 'S': | |||||
sync = 1; | |||||
break; | |||||
case 'n': | |||||
server_name = optarg; | |||||
break; | |||||
case 'm': | |||||
do_mlock = 0; | |||||
break; | |||||
case 'P': | |||||
realtime_priority = atoi(optarg); | |||||
break; | |||||
case 'r': | |||||
replace_registry = 1; | |||||
break; | |||||
case 'R': | |||||
realtime = 1; | |||||
break; | |||||
case 'L': | |||||
loopback = atoi(optarg); | |||||
break; | |||||
case 'T': | |||||
temporary = 1; | |||||
break; | |||||
case 't': | |||||
client_timeout = atoi(optarg); | |||||
break; | |||||
case 'u': | |||||
do_unlock = 1; | |||||
break; | |||||
case 'V': | |||||
show_version = 1; | |||||
break; | |||||
default: | |||||
fprintf(stderr, "unknown option character %c\n", | |||||
optopt); | |||||
/*fallthru*/ | |||||
case 'h': | |||||
usage(stdout); | |||||
return -1; | |||||
} | |||||
} | |||||
if (!seen_driver) { | |||||
usage (stderr); | |||||
//exit (1); | |||||
return 0; | |||||
} | |||||
drivers = jack_drivers_load (drivers); | |||||
if (!drivers) { | |||||
fprintf (stderr, "jackdmp: no drivers found; exiting\n"); | |||||
//exit (1); | |||||
return 0; | |||||
} | |||||
driver_desc = jack_find_driver_descriptor (drivers, driver_name); | |||||
if (!driver_desc) { | |||||
fprintf (stderr, "jackdmp: unknown driver '%s'\n", driver_name); | |||||
//exit (1); | |||||
return 0; | |||||
} | |||||
if (optind < argc) { | |||||
driver_nargs = 1 + argc - optind; | |||||
} else { | |||||
driver_nargs = 1; | |||||
} | |||||
if (driver_nargs == 0) { | |||||
fprintf (stderr, "No driver specified ... hmm. JACK won't do" | |||||
" anything when run like this.\n"); | |||||
return -1; | |||||
} | |||||
driver_args = (char **) malloc (sizeof (char *) * driver_nargs); | |||||
driver_args[0] = driver_name; | |||||
for (i = 1; i < driver_nargs; i++) { | |||||
driver_args[i] = argv[optind++]; | |||||
} | |||||
if (jack_parse_driver_params (driver_desc, driver_nargs, | |||||
driver_args, &driver_params)) { | |||||
// exit (0); | |||||
return 0; | |||||
} | |||||
//if (server_name == NULL) | |||||
// server_name = jack_default_server_name (); | |||||
copyright (stdout); | |||||
rc = jack_register_server (server_name, replace_registry); | |||||
switch (rc) { | |||||
case EEXIST: | |||||
fprintf (stderr, "`%s' server already active\n", server_name); | |||||
//exit (1); | |||||
return 0; | |||||
case ENOSPC: | |||||
fprintf (stderr, "too many servers already active\n"); | |||||
//exit (2); | |||||
return 0; | |||||
case ENOMEM: | |||||
fprintf (stderr, "no access to shm registry\n"); | |||||
//exit (3); | |||||
return 0; | |||||
default: | |||||
if (xverbose) | |||||
fprintf (stderr, "server `%s' registered\n", | |||||
server_name); | |||||
} | |||||
/* clean up shared memory and files from any previous | |||||
* instance of this server name */ | |||||
jack_cleanup_shm(); | |||||
// jack_cleanup_files(server_name); | |||||
if (!realtime && client_timeout == 0) | |||||
client_timeout = 500; /* 0.5 sec; usable when non realtime. */ | |||||
int res = JackStart(driver_desc, driver_params, sync, client_timeout, realtime, realtime_priority, loopback, xverbose, server_name); | |||||
if (res < 0) { | |||||
printf("Cannot start server... exit\n"); | |||||
JackDelete(); | |||||
return 0; | |||||
} | |||||
/* | |||||
if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) ) | |||||
{ | |||||
printf( "\nThe Control Handler is installed.\n" ); | |||||
} else { | |||||
printf( "\nERROR: Could not set control handler"); | |||||
} | |||||
*/ | |||||
(void) signal(SIGINT, intrpt); | |||||
(void) signal(SIGABRT, intrpt); | |||||
(void) signal(SIGTERM, intrpt); | |||||
if ((res = WaitForSingleObject(waitEvent, INFINITE)) != WAIT_OBJECT_0) { | |||||
printf("WaitForSingleObject fails err = %ld\n", GetLastError()); | |||||
} | |||||
/* | |||||
printf("Type 'q' to quit\n"); | |||||
while ((c = getchar()) != 'q') {} | |||||
*/ | |||||
JackStop(); | |||||
jack_cleanup_shm(); | |||||
// jack_cleanup_files(server_name); | |||||
jack_unregister_server(server_name); | |||||
CloseHandle(waitEvent); | |||||
return 1; | |||||
} | |||||
@@ -65,7 +65,7 @@ LINK32=link.exe | |||||
# PROP Ignore_Export_Lib 0 | # PROP Ignore_Export_Lib 0 | ||||
# PROP Target_Dir "" | # PROP Target_Dir "" | ||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c | ||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I "../common/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c | |||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /I "../common/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c | |||||
# ADD BASE RSC /l 0x40c /d "_DEBUG" | # ADD BASE RSC /l 0x40c /d "_DEBUG" | ||||
# ADD RSC /l 0x40c /d "_DEBUG" | # ADD RSC /l 0x40c /d "_DEBUG" | ||||
BSC32=bscmake.exe | BSC32=bscmake.exe | ||||
@@ -41,7 +41,7 @@ RSC=rc.exe | |||||
# PROP Intermediate_Dir "Release" | # PROP Intermediate_Dir "Release" | ||||
# PROP Target_Dir "" | # PROP Target_Dir "" | ||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | ||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "../common/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c | |||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "../common/" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c | |||||
# ADD BASE RSC /l 0x40c /d "NDEBUG" | # ADD BASE RSC /l 0x40c /d "NDEBUG" | ||||
# ADD RSC /l 0x40c /d "NDEBUG" | # ADD RSC /l 0x40c /d "NDEBUG" | ||||
BSC32=bscmake.exe | BSC32=bscmake.exe | ||||
@@ -95,7 +95,7 @@ SOURCE=.\getopt1.c | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=.\JackdmpWIN32.cpp | |||||
SOURCE=..\common\Jackdmp.cpp | |||||
# End Source File | # End Source File | ||||
# End Group | # End Group | ||||
# Begin Group "Header Files" | # Begin Group "Header Files" | ||||
@@ -115,7 +115,7 @@ SOURCE=..\common\JackEngineControl.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=..\common\JackError.c | |||||
SOURCE=..\common\JackError.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
@@ -143,6 +143,10 @@ SOURCE=..\common\JackLibClient.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=..\common\JackMessageBuffer.cpp | |||||
# End Source File | |||||
# Begin Source File | |||||
SOURCE=..\common\JackMidiAPI.cpp | SOURCE=..\common\JackMidiAPI.cpp | ||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
@@ -183,6 +187,10 @@ SOURCE=.\JackWinNamedPipeClientChannel.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=.\JackWinProcessSync.cpp | |||||
# End Source File | |||||
# Begin Source File | |||||
SOURCE=.\JackWinSemaphore.cpp | SOURCE=.\JackWinSemaphore.cpp | ||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
@@ -124,6 +124,10 @@ SOURCE=..\common\JackConnectionManager.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=..\common\JackControl.cpp | |||||
# End Source File | |||||
# Begin Source File | |||||
SOURCE=..\common\JackDriver.cpp | SOURCE=..\common\JackDriver.cpp | ||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
@@ -140,7 +144,7 @@ SOURCE=..\common\JackEngineControl.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=..\common\JackError.c | |||||
SOURCE=..\common\JackError.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
@@ -176,6 +180,10 @@ SOURCE=..\common\JackLoopbackDriver.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=..\common\JackMessageBuffer.cpp | |||||
# End Source File | |||||
# Begin Source File | |||||
SOURCE=..\common\JackMidiAPI.cpp | SOURCE=..\common\JackMidiAPI.cpp | ||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
@@ -244,6 +252,10 @@ SOURCE=.\JackWinNamedPipeServerNotifyChannel.cpp | |||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||
SOURCE=.\JackWinProcessSync.cpp | |||||
# End Source File | |||||
# Begin Source File | |||||
SOURCE=.\JackWinSemaphore.cpp | SOURCE=.\JackWinSemaphore.cpp | ||||
# End Source File | # End Source File | ||||
# Begin Source File | # Begin Source File | ||||