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