git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4184 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.7
| @@ -34,6 +34,10 @@ Valerio Pilo | |||||
| Jackdmp changes log | Jackdmp changes log | ||||
| --------------------------- | --------------------------- | ||||
| 2011-03-13 Stephane Letz <letz@grame.fr> | |||||
| * Correct JackNetMaster::SetBufferSize. | |||||
| 2011-03-11 Stephane Letz <letz@grame.fr> | 2011-03-11 Stephane Letz <letz@grame.fr> | ||||
| * Correct JackNetMaster::SetBufferSize. | * Correct JackNetMaster::SetBufferSize. | ||||
| @@ -78,15 +78,15 @@ struct jackctl_server | |||||
| /* int32_t, msecs; if zero, use period size. */ | /* int32_t, msecs; if zero, use period size. */ | ||||
| union jackctl_parameter_value client_timeout; | union jackctl_parameter_value client_timeout; | ||||
| union jackctl_parameter_value default_client_timeout; | union jackctl_parameter_value default_client_timeout; | ||||
| /* uint32_t, clock source type */ | /* uint32_t, clock source type */ | ||||
| union jackctl_parameter_value clock_source; | union jackctl_parameter_value clock_source; | ||||
| union jackctl_parameter_value default_clock_source; | union jackctl_parameter_value default_clock_source; | ||||
| /* uint32_t, max port number */ | /* uint32_t, max port number */ | ||||
| union jackctl_parameter_value port_max; | union jackctl_parameter_value port_max; | ||||
| union jackctl_parameter_value default_port_max; | union jackctl_parameter_value default_port_max; | ||||
| /* bool */ | /* bool */ | ||||
| union jackctl_parameter_value replace_registry; | union jackctl_parameter_value replace_registry; | ||||
| union jackctl_parameter_value default_replace_registry; | union jackctl_parameter_value default_replace_registry; | ||||
| @@ -366,7 +366,7 @@ jackctl_internals_load( | |||||
| } | } | ||||
| while (descriptor_node_ptr != NULL) | while (descriptor_node_ptr != NULL) | ||||
| { | |||||
| { | |||||
| internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal)); | internal_ptr = (struct jackctl_internal *)malloc(sizeof(struct jackctl_internal)); | ||||
| if (internal_ptr == NULL) | if (internal_ptr == NULL) | ||||
| { | { | ||||
| @@ -745,7 +745,7 @@ EXPORT jackctl_server_t * jackctl_server_create( | |||||
| { | { | ||||
| goto fail_free_parameters; | goto fail_free_parameters; | ||||
| } | } | ||||
| value.ui = PORT_NUM; | value.ui = PORT_NUM; | ||||
| if (jackctl_add_parameter( | if (jackctl_add_parameter( | ||||
| &server_ptr->parameters, | &server_ptr->parameters, | ||||
| @@ -795,7 +795,7 @@ EXPORT jackctl_server_t * jackctl_server_create( | |||||
| { | { | ||||
| goto fail_free_parameters; | goto fail_free_parameters; | ||||
| } | } | ||||
| /* Allowed to fail */ | /* Allowed to fail */ | ||||
| jackctl_internals_load(server_ptr); | jackctl_internals_load(server_ptr); | ||||
| @@ -882,7 +882,7 @@ jackctl_server_start( | |||||
| if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) | if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) | ||||
| server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ | server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ | ||||
| /* check port max value before allocating server */ | /* check port max value before allocating server */ | ||||
| if (server_ptr->port_max.ui > PORT_NUM_MAX) { | if (server_ptr->port_max.ui > PORT_NUM_MAX) { | ||||
| jack_error("JACK server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); | jack_error("JACK server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); | ||||
| @@ -896,7 +896,7 @@ jackctl_server_start( | |||||
| server_ptr->client_timeout.i, | server_ptr->client_timeout.i, | ||||
| server_ptr->realtime.b, | server_ptr->realtime.b, | ||||
| server_ptr->realtime_priority.i, | server_ptr->realtime_priority.i, | ||||
| server_ptr->port_max.ui, | |||||
| server_ptr->port_max.ui, | |||||
| server_ptr->verbose.b, | server_ptr->verbose.b, | ||||
| (jack_timer_type_t)server_ptr->clock_source.ui, | (jack_timer_type_t)server_ptr->clock_source.ui, | ||||
| server_ptr->name.str); | server_ptr->name.str); | ||||
| @@ -1179,7 +1179,7 @@ EXPORT bool jackctl_server_load_internal( | |||||
| { | { | ||||
| int status; | int status; | ||||
| if (server_ptr->engine != NULL) { | if (server_ptr->engine != NULL) { | ||||
| server_ptr->engine->InternalClientLoad(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status); | |||||
| server_ptr->engine->InternalClientLoad2(internal->desc_ptr->name, internal->desc_ptr->name, internal->set_parameters, JackNullOption, &internal->refnum, -1, &status); | |||||
| return (internal->refnum > 0); | return (internal->refnum > 0); | ||||
| } else { | } else { | ||||
| return false; | return false; | ||||
| @@ -1192,6 +1192,7 @@ EXPORT bool jackctl_server_unload_internal( | |||||
| { | { | ||||
| int status; | int status; | ||||
| if (server_ptr->engine != NULL && internal->refnum > 0) { | if (server_ptr->engine != NULL && internal->refnum > 0) { | ||||
| // Client object is internally kept in JackEngine, and will be desallocated in InternalClientUnload | |||||
| return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0); | return ((server_ptr->engine->GetEngine()->InternalClientUnload(internal->refnum, &status)) == 0); | ||||
| } else { | } else { | ||||
| return false; | return false; | ||||
| @@ -446,7 +446,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) | |||||
| free(filename); | free(filename); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if ((descriptor = so_get_descriptor ()) == NULL) { | if ((descriptor = so_get_descriptor ()) == NULL) { | ||||
| jack_error("driver from '%s' returned NULL descriptor", filename); | jack_error("driver from '%s' returned NULL descriptor", filename); | ||||
| UnloadDriverModule(dlhandle); | UnloadDriverModule(dlhandle); | ||||
| @@ -467,7 +467,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) | |||||
| /* check it doesn't exist already */ | /* check it doesn't exist already */ | ||||
| for (node = drivers; node; node = jack_slist_next (node)) { | for (node = drivers; node; node = jack_slist_next (node)) { | ||||
| other_descriptor = (jack_driver_desc_t *) node->data; | other_descriptor = (jack_driver_desc_t *) node->data; | ||||
| if (strcmp(descriptor->name, other_descriptor->name) == 0) { | if (strcmp(descriptor->name, other_descriptor->name) == 0) { | ||||
| jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first", | jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first", | ||||
| other_descriptor->file, filename, other_descriptor->name); | other_descriptor->file, filename, other_descriptor->name); | ||||
| @@ -603,7 +603,7 @@ jack_drivers_load (JSList * drivers) { | |||||
| } | } | ||||
| while ((dir_entry = readdir(dir_stream))) { | while ((dir_entry = readdir(dir_stream))) { | ||||
| /* check the filename is of the right format */ | /* check the filename is of the right format */ | ||||
| if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { | if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { | ||||
| continue; | continue; | ||||
| @@ -619,7 +619,7 @@ jack_drivers_load (JSList * drivers) { | |||||
| } | } | ||||
| desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor"); | desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor"); | ||||
| if (desc) { | if (desc) { | ||||
| driver_list = jack_slist_append (driver_list, desc); | driver_list = jack_slist_append (driver_list, desc); | ||||
| } else { | } else { | ||||
| @@ -771,9 +771,9 @@ jack_internals_load (JSList * internals) { | |||||
| #endif | #endif | ||||
| Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc, | |||||
| Jack::JackLockedEngine* engine, | |||||
| Jack::JackSynchro* synchro, | |||||
| Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc, | |||||
| Jack::JackLockedEngine* engine, | |||||
| Jack::JackSynchro* synchro, | |||||
| const JSList* params) | const JSList* params) | ||||
| { | { | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| @@ -783,7 +783,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver | |||||
| #endif | #endif | ||||
| fHandle = LoadDriverModule (driver_desc->file); | fHandle = LoadDriverModule (driver_desc->file); | ||||
| if (fHandle == NULL) { | if (fHandle == NULL) { | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| if ((errstr = GetLastError ()) != 0) { | if ((errstr = GetLastError ()) != 0) { | ||||
| @@ -809,8 +809,14 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver | |||||
| jack_error("no initialize function in shared object %s\n", driver_desc->file); | jack_error("no initialize function in shared object %s\n", driver_desc->file); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| fBackend = fInitialize(engine, synchro, params); | fBackend = fInitialize(engine, synchro, params); | ||||
| return fBackend; | return fBackend; | ||||
| } | } | ||||
| JackDriverInfo::~JackDriverInfo() | |||||
| { | |||||
| delete fBackend; | |||||
| if (fHandle) | |||||
| UnloadDriverModule(fHandle); | |||||
| } | |||||
| @@ -24,14 +24,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "driver_interface.h" | #include "driver_interface.h" | ||||
| #include "JackControlAPI.h" | #include "JackControlAPI.h" | ||||
| #include "JackPlatformPlug.h" | #include "JackPlatformPlug.h" | ||||
| #include "JackDriver.h" | |||||
| #include "JackSystemDeps.h" | #include "JackSystemDeps.h" | ||||
| namespace Jack | |||||
| { | |||||
| class JackDriverClientInterface; | |||||
| class JackLockedEngine; | |||||
| }; | |||||
| typedef jack_driver_desc_t * (*JackDriverDescFunction) (); | typedef jack_driver_desc_t * (*JackDriverDescFunction) (); | ||||
| typedef Jack::JackDriverClientInterface* (*driverInitialize) (Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); | typedef Jack::JackDriverClientInterface* (*driverInitialize) (Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); | ||||
| @@ -39,34 +34,30 @@ class JackDriverInfo | |||||
| { | { | ||||
| private: | private: | ||||
| driverInitialize fInitialize; | driverInitialize fInitialize; | ||||
| DRIVER_HANDLE fHandle; | DRIVER_HANDLE fHandle; | ||||
| Jack::JackDriverClientInterface* fBackend; | Jack::JackDriverClientInterface* fBackend; | ||||
| public: | public: | ||||
| JackDriverInfo():fInitialize(NULL),fHandle(NULL) | |||||
| JackDriverInfo():fInitialize(NULL),fHandle(NULL),fBackend(NULL) | |||||
| {} | {} | ||||
| ~JackDriverInfo() | |||||
| { | |||||
| if (fHandle) | |||||
| UnloadDriverModule(fHandle); | |||||
| } | |||||
| ~JackDriverInfo(); | |||||
| Jack::JackDriverClientInterface* Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); | Jack::JackDriverClientInterface* Open(jack_driver_desc_t* driver_desc, Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); | ||||
| Jack::JackDriverClientInterface* GetBackend() | Jack::JackDriverClientInterface* GetBackend() | ||||
| { | { | ||||
| return fBackend; | return fBackend; | ||||
| } | } | ||||
| }; | }; | ||||
| jack_driver_desc_t * jack_find_driver_descriptor (JSList * drivers, const char * name); | |||||
| jack_driver_desc_t * jack_find_driver_descriptor(JSList * drivers, const char * name); | |||||
| JSList * jack_drivers_load (JSList * drivers); | |||||
| JSList * jack_internals_load (JSList * internals); | |||||
| JSList * jack_drivers_load(JSList * drivers); | |||||
| JSList * jack_internals_load(JSList * internals); | |||||
| EXPORT int jackctl_parse_driver_params (jackctl_driver * driver_ptr, int argc, char* argv[]); | EXPORT int jackctl_parse_driver_params (jackctl_driver * driver_ptr, int argc, char* argv[]); | ||||
| EXPORT void jack_free_driver_params(JSList * param_ptr); | EXPORT void jack_free_driver_params(JSList * param_ptr); | ||||
| @@ -136,7 +136,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface | |||||
| void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) | void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result) | ||||
| { | { | ||||
| *result = fServer->InternalClientLoad(client_name, so_name, objet_data, options, int_ref, uuid, status); | |||||
| *result = fServer->InternalClientLoad1(client_name, so_name, objet_data, options, int_ref, uuid, status); | |||||
| } | } | ||||
| void InternalClientUnload(int refnum, int int_ref, int* status, int* result) | void InternalClientUnload(int refnum, int int_ref, int* status, int* result) | ||||
| @@ -61,7 +61,6 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio | |||||
| JackServer::~JackServer() | JackServer::~JackServer() | ||||
| { | { | ||||
| JackGraphManager::Destroy(fGraphManager); | JackGraphManager::Destroy(fGraphManager); | ||||
| delete fAudioDriver; | |||||
| delete fDriverInfo; | delete fDriverInfo; | ||||
| delete fFreewheelDriver; | delete fFreewheelDriver; | ||||
| delete fEngine; | delete fEngine; | ||||
| @@ -136,14 +135,14 @@ int JackServer::Close() | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status) | |||||
| int JackServer::InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status) | |||||
| { | { | ||||
| JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data); | JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data); | ||||
| assert(client); | assert(client); | ||||
| return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); | return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); | ||||
| } | } | ||||
| int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status) | |||||
| int JackServer::InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status) | |||||
| { | { | ||||
| JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters); | JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters); | ||||
| assert(client); | assert(client); | ||||
| @@ -154,6 +153,8 @@ int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const | |||||
| { | { | ||||
| // Clear status | // Clear status | ||||
| *status = 0; | *status = 0; | ||||
| // Client object is internally kept in JackEngine | |||||
| if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) { | if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) { | ||||
| delete client; | delete client; | ||||
| int my_status1 = *status | JackFailure; | int my_status1 = *status | JackFailure; | ||||
| @@ -338,7 +339,6 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par | |||||
| } | } | ||||
| // Delete old master | // Delete old master | ||||
| delete fAudioDriver; | |||||
| delete fDriverInfo; | delete fDriverInfo; | ||||
| // Activate master | // Activate master | ||||
| @@ -57,7 +57,7 @@ class SERVER_EXPORT JackServer | |||||
| JackConnectionManager fConnectionState; | JackConnectionManager fConnectionState; | ||||
| JackSynchro fSynchroTable[CLIENT_NUM]; | JackSynchro fSynchroTable[CLIENT_NUM]; | ||||
| bool fFreewheel; | bool fFreewheel; | ||||
| int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status); | int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status); | ||||
| public: | public: | ||||
| @@ -77,19 +77,19 @@ class SERVER_EXPORT JackServer | |||||
| // Command thread : API | // Command thread : API | ||||
| int SetBufferSize(jack_nframes_t buffer_size); | int SetBufferSize(jack_nframes_t buffer_size); | ||||
| int SetFreewheel(bool onoff); | int SetFreewheel(bool onoff); | ||||
| int InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status); | |||||
| int InternalClientLoad(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status); | |||||
| int InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status); | |||||
| int InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status); | |||||
| void ClientKill(int refnum); | void ClientKill(int refnum); | ||||
| // Transport management | // Transport management | ||||
| int ReleaseTimebase(int refnum); | int ReleaseTimebase(int refnum); | ||||
| int SetTimebaseCallback(int refnum, int conditional); | int SetTimebaseCallback(int refnum, int conditional); | ||||
| // Backend management | // Backend management | ||||
| JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params); | JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params); | ||||
| void RemoveSlave(JackDriverInfo* info); | void RemoveSlave(JackDriverInfo* info); | ||||
| int SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params); | int SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params); | ||||
| // Object access | // Object access | ||||
| JackLockedEngine* GetEngine(); | JackLockedEngine* GetEngine(); | ||||
| JackEngineControl* GetEngineControl(); | JackEngineControl* GetEngineControl(); | ||||
| @@ -63,7 +63,7 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio | |||||
| } | } | ||||
| jack_log("jack_client_new %s", client_name); | jack_log("jack_client_new %s", client_name); | ||||
| if (status == NULL) /* no status from caller? */ | if (status == NULL) /* no status from caller? */ | ||||
| status = &my_status; /* use local status word */ | status = &my_status; /* use local status word */ | ||||
| *status = (jack_status_t)0; | *status = (jack_status_t)0; | ||||
| @@ -77,13 +77,13 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio | |||||
| /* parse variable arguments */ | /* parse variable arguments */ | ||||
| jack_varargs_init(&va); | jack_varargs_init(&va); | ||||
| if (!JackServerGlobals::Init()) { // jack server initialisation | if (!JackServerGlobals::Init()) { // jack server initialisation | ||||
| 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; | ||||
| } | } | ||||
| if (JACK_DEBUG) { | if (JACK_DEBUG) { | ||||
| client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode | client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode | ||||
| } else { | } else { | ||||
| @@ -114,7 +114,7 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti | |||||
| } | } | ||||
| jack_log("jack_client_open %s", client_name); | jack_log("jack_client_open %s", client_name); | ||||
| if (status == NULL) /* no status from caller? */ | if (status == NULL) /* no status from caller? */ | ||||
| status = &my_status; /* use local status word */ | status = &my_status; /* use local status word */ | ||||
| *status = (jack_status_t)0; | *status = (jack_status_t)0; | ||||
| @@ -128,13 +128,13 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti | |||||
| /* parse variable arguments */ | /* parse variable arguments */ | ||||
| jack_varargs_parse(options, ap, &va); | jack_varargs_parse(options, ap, &va); | ||||
| if (!JackServerGlobals::Init()) { // jack server initialisation | if (!JackServerGlobals::Init()) { // jack server initialisation | ||||
| 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; | ||||
| } | } | ||||
| if (JACK_DEBUG) { | if (JACK_DEBUG) { | ||||
| client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode | client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode | ||||
| } else { | } else { | ||||
| @@ -180,7 +180,7 @@ EXPORT int jack_client_close(jack_client_t* ext_client) | |||||
| { | { | ||||
| #ifdef __CLIENTDEBUG__ | #ifdef __CLIENTDEBUG__ | ||||
| JackGlobals::CheckContext("jack_client_close"); | JackGlobals::CheckContext("jack_client_close"); | ||||
| #endif | |||||
| #endif | |||||
| assert(JackGlobals::fOpenMutex); | assert(JackGlobals::fOpenMutex); | ||||
| JackGlobals::fOpenMutex->Lock(); | JackGlobals::fOpenMutex->Lock(); | ||||
| int res = -1; | int res = -1; | ||||
| @@ -200,7 +200,7 @@ EXPORT int jack_client_close(jack_client_t* ext_client) | |||||
| EXPORT int jack_get_client_pid(const char *name) | EXPORT int jack_get_client_pid(const char *name) | ||||
| { | { | ||||
| return (JackServerGlobals::fInstance != NULL) | |||||
| return (JackServerGlobals::fInstance != NULL) | |||||
| ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name) | ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name) | ||||
| : 0; | : 0; | ||||
| } | } | ||||
| @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| */ | */ | ||||
| #include "JackServerGlobals.h" | #include "JackServerGlobals.h" | ||||
| #include "JackLockedEngine.h" | |||||
| #include "JackTools.h" | #include "JackTools.h" | ||||
| #include "shm.h" | #include "shm.h" | ||||
| #include <getopt.h> | #include <getopt.h> | ||||
| @@ -31,6 +32,8 @@ namespace Jack | |||||
| JackServer* JackServerGlobals::fInstance; | JackServer* JackServerGlobals::fInstance; | ||||
| unsigned int JackServerGlobals::fUserCount; | unsigned int JackServerGlobals::fUserCount; | ||||
| int JackServerGlobals::fRTNotificationSocket; | int JackServerGlobals::fRTNotificationSocket; | ||||
| std::map<std::string, JackDriverInfo*> JackServerGlobals::fSlavesList; | |||||
| std::map<std::string, int> JackServerGlobals::fInternalsList; | |||||
| bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; | bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL; | ||||
| void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; | void (* JackServerGlobals::on_device_release)(const char * device_name) = NULL; | ||||
| @@ -63,6 +66,30 @@ void JackServerGlobals::Stop() | |||||
| void JackServerGlobals::Delete() | void JackServerGlobals::Delete() | ||||
| { | { | ||||
| jack_log("Jackdmp: delete server"); | jack_log("Jackdmp: delete server"); | ||||
| // Slave drivers | |||||
| std::map<std::string, JackDriverInfo*>::iterator it1; | |||||
| for (it1 = fSlavesList.begin(); it1 != fSlavesList.end(); it1++) { | |||||
| JackDriverInfo* info = (*it1).second; | |||||
| if (info) { | |||||
| fInstance->RemoveSlave((info)); | |||||
| delete (info); | |||||
| } | |||||
| } | |||||
| fSlavesList.clear(); | |||||
| // Internal clients | |||||
| std::map<std::string, int> ::iterator it2; | |||||
| for (it2 = fInternalsList.begin(); it2 != fInternalsList.end(); it2++) { | |||||
| int status; | |||||
| int refnum = (*it2).second; | |||||
| if (refnum > 0) { | |||||
| // Client object is internally kept in JackEngine, and will be desallocated in InternalClientUnload | |||||
| fInstance->GetEngine()->InternalClientUnload(refnum, &status); | |||||
| } | |||||
| } | |||||
| fInternalsList.clear(); | |||||
| delete fInstance; | delete fInstance; | ||||
| fInstance = NULL; | fInstance = NULL; | ||||
| } | } | ||||
| @@ -80,49 +107,62 @@ bool JackServerGlobals::Init() | |||||
| int opt = 0; | int opt = 0; | ||||
| int option_index = 0; | int option_index = 0; | ||||
| int seen_driver = 0; | |||||
| char *driver_name = NULL; | |||||
| char **driver_args = NULL; | |||||
| JSList* driver_params = NULL; | |||||
| char *master_driver_name = NULL; | |||||
| char **master_driver_args = NULL; | |||||
| JSList* master_driver_params = NULL; | |||||
| jack_driver_desc_t* driver_desc; | |||||
| jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK; | |||||
| int driver_nargs = 1; | int driver_nargs = 1; | ||||
| JSList* drivers = NULL; | JSList* drivers = NULL; | ||||
| int show_version = 0; | |||||
| int loopback = 0; | |||||
| int sync = 0; | int sync = 0; | ||||
| int rc, i; | int rc, i; | ||||
| int ret; | int ret; | ||||
| int replace_registry = 0; | |||||
| FILE* fp = 0; | FILE* fp = 0; | ||||
| char filename[255]; | char filename[255]; | ||||
| char buffer[255]; | char buffer[255]; | ||||
| int argc = 0; | int argc = 0; | ||||
| char* argv[32]; | char* argv[32]; | ||||
| jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK; | |||||
| // First user starts the server | // First user starts the server | ||||
| if (fUserCount++ == 0) { | if (fUserCount++ == 0) { | ||||
| jack_log("JackServerGlobals Init"); | jack_log("JackServerGlobals Init"); | ||||
| jack_driver_desc_t* driver_desc; | |||||
| const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:c:"; | |||||
| static struct option long_options[] = { | |||||
| { "clock-source", 1, 0, 'c' }, | |||||
| { "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' }, | |||||
| { "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 } | |||||
| }; | |||||
| const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" | |||||
| #ifdef __linux__ | |||||
| "c:" | |||||
| #endif | |||||
| ; | |||||
| struct option long_options[] = { | |||||
| #ifdef __linux__ | |||||
| { "clock-source", 1, 0, 'c' }, | |||||
| #endif | |||||
| { "loopback-driver", 1, 0, 'L' }, | |||||
| { "audio-driver", 1, 0, 'd' }, | |||||
| { "midi-driver", 1, 0, 'X' }, | |||||
| { "internal-client", 1, 0, 'I' }, | |||||
| { "verbose", 0, 0, 'v' }, | |||||
| { "help", 0, 0, 'h' }, | |||||
| { "port-max", 1, 0, 'p' }, | |||||
| { "no-mlock", 0, 0, 'm' }, | |||||
| { "name", 1, 0, 'n' }, | |||||
| { "unlock", 0, 0, 'u' }, | |||||
| { "realtime", 0, 0, 'R' }, | |||||
| { "no-realtime", 0, 0, 'r' }, | |||||
| { "replace-registry", 0, &replace_registry, 0 }, | |||||
| { "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 } | |||||
| }; | |||||
| snprintf(filename, 255, "%s/.jackdrc", getenv("HOME")); | snprintf(filename, 255, "%s/.jackdrc", getenv("HOME")); | ||||
| fp = fopen(filename, "r"); | fp = fopen(filename, "r"); | ||||
| @@ -156,7 +196,7 @@ bool JackServerGlobals::Init() | |||||
| opterr = 0; | opterr = 0; | ||||
| optind = 1; // Important : to reset argv parsing | optind = 1; // Important : to reset argv parsing | ||||
| while (!seen_driver && | |||||
| while (!master_driver_name && | |||||
| (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { | (opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) { | ||||
| switch (opt) { | switch (opt) { | ||||
| @@ -174,34 +214,53 @@ bool JackServerGlobals::Init() | |||||
| break; | break; | ||||
| case 'd': | case 'd': | ||||
| seen_driver = 1; | |||||
| driver_name = optarg; | |||||
| master_driver_name = optarg; | |||||
| break; | break; | ||||
| case 'v': | |||||
| verbose_aux = 1; | |||||
| case 'L': | |||||
| loopback = atoi(optarg); | |||||
| break; | break; | ||||
| case 'S': | |||||
| sync = 1; | |||||
| case 'X': | |||||
| fSlavesList[optarg] = NULL; | |||||
| break; | break; | ||||
| case 'n': | |||||
| server_name = optarg; | |||||
| case 'I': | |||||
| fInternalsList[optarg] = -1; | |||||
| break; | |||||
| case 'p': | |||||
| port_max = (unsigned int)atol(optarg); | |||||
| break; | break; | ||||
| case 'm': | case 'm': | ||||
| do_mlock = 0; | do_mlock = 0; | ||||
| break; | break; | ||||
| case 'p': | |||||
| port_max = (unsigned int)atol(optarg); | |||||
| case 'u': | |||||
| do_unlock = 1; | |||||
| break; | |||||
| case 'v': | |||||
| verbose_aux = 1; | |||||
| break; | |||||
| case 'S': | |||||
| sync = 1; | |||||
| break; | |||||
| case 'n': | |||||
| server_name = optarg; | |||||
| break; | break; | ||||
| case 'P': | case 'P': | ||||
| realtime_priority = atoi(optarg); | realtime_priority = atoi(optarg); | ||||
| break; | break; | ||||
| case 'r': | |||||
| realtime = 0; | |||||
| break; | |||||
| case 'R': | case 'R': | ||||
| realtime = 1; | realtime = 1; | ||||
| break; | break; | ||||
| @@ -214,14 +273,6 @@ bool JackServerGlobals::Init() | |||||
| client_timeout = atoi(optarg); | client_timeout = atoi(optarg); | ||||
| break; | break; | ||||
| case 'u': | |||||
| do_unlock = 1; | |||||
| break; | |||||
| case 'V': | |||||
| show_version = 1; | |||||
| break; | |||||
| default: | default: | ||||
| jack_error("unknown option character %c", optopt); | jack_error("unknown option character %c", optopt); | ||||
| break; | break; | ||||
| @@ -234,9 +285,9 @@ bool JackServerGlobals::Init() | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| driver_desc = jack_find_driver_descriptor(drivers, driver_name); | |||||
| driver_desc = jack_find_driver_descriptor(drivers, master_driver_name); | |||||
| if (!driver_desc) { | if (!driver_desc) { | ||||
| jack_error("jackdmp: unknown driver '%s'", driver_name); | |||||
| jack_error("jackdmp: unknown master driver '%s'", master_driver_name); | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| @@ -252,14 +303,14 @@ bool JackServerGlobals::Init() | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| driver_args = (char**)malloc(sizeof(char*) * driver_nargs); | |||||
| driver_args[0] = driver_name; | |||||
| master_driver_args = (char**)malloc(sizeof(char*) * driver_nargs); | |||||
| master_driver_args[0] = master_driver_name; | |||||
| for (i = 1; i < driver_nargs; i++) { | for (i = 1; i < driver_nargs; i++) { | ||||
| driver_args[i] = argv[optind++]; | |||||
| master_driver_args[i] = argv[optind++]; | |||||
| } | } | ||||
| if (jack_parse_driver_params(driver_desc, driver_nargs, driver_args, &driver_params)) { | |||||
| if (jack_parse_driver_params(driver_desc, driver_nargs, master_driver_args, &master_driver_params)) { | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| @@ -294,7 +345,7 @@ bool JackServerGlobals::Init() | |||||
| free(argv[i]); | free(argv[i]); | ||||
| } | } | ||||
| int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source); | |||||
| int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source); | |||||
| if (res < 0) { | if (res < 0) { | ||||
| jack_error("Cannot start server... exit"); | jack_error("Cannot start server... exit"); | ||||
| Delete(); | Delete(); | ||||
| @@ -303,21 +354,57 @@ bool JackServerGlobals::Init() | |||||
| jack_unregister_server(server_name); | jack_unregister_server(server_name); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // Slave drivers | |||||
| std::map<std::string, JackDriverInfo*>::iterator it1; | |||||
| for (it1 = fSlavesList.begin(); it1 != fSlavesList.end(); it1++) { | |||||
| const char* name = ((*it1).first).c_str(); | |||||
| driver_desc = jack_find_driver_descriptor(drivers, name); | |||||
| if (!driver_desc) { | |||||
| jack_error("jackdmp: unknown slave driver '%s'", name); | |||||
| } else { | |||||
| JackDriverInfo* info = fInstance->AddSlave(driver_desc, NULL); | |||||
| (*it1).second = info; | |||||
| } | |||||
| } | |||||
| // Loopback driver | |||||
| if (loopback > 0) { | |||||
| driver_desc = jack_find_driver_descriptor(drivers, "loopback"); | |||||
| if (!driver_desc) { | |||||
| jack_error("jackdmp: unknown driver '%s'", "loopback"); | |||||
| } else { | |||||
| fInstance->AddSlave(driver_desc, NULL); | |||||
| } | |||||
| } | |||||
| // Internal clients | |||||
| std::map<std::string, int>::iterator it2; | |||||
| for (it2 = fInternalsList.begin(); it2 != fInternalsList.end(); it2++) { | |||||
| int status, refnum; | |||||
| const char* name = ((*it2).first).c_str(); | |||||
| fInstance->InternalClientLoad2(name, name, NULL, JackNullOption, &refnum, -1, &status); | |||||
| (*it2).second = refnum; | |||||
| } | |||||
| } | } | ||||
| if (driver_params) | |||||
| jack_free_driver_params(driver_params); | |||||
| if (master_driver_params) | |||||
| jack_free_driver_params(master_driver_params); | |||||
| return true; | return true; | ||||
| error: | error: | ||||
| if (driver_params) | |||||
| jack_free_driver_params(driver_params); | |||||
| fUserCount--; | |||||
| jack_log("JackServerGlobals Init error"); | |||||
| if (master_driver_params) | |||||
| jack_free_driver_params(master_driver_params); | |||||
| //fUserCount--; | |||||
| Destroy(); | |||||
| return false; | return false; | ||||
| } | } | ||||
| void JackServerGlobals::Destroy() | void JackServerGlobals::Destroy() | ||||
| { | { | ||||
| printf("JackServerGlobals Destroy %d\n", fUserCount); | |||||
| if (--fUserCount == 0) { | if (--fUserCount == 0) { | ||||
| jack_log("JackServerGlobals Destroy"); | jack_log("JackServerGlobals Destroy"); | ||||
| Stop(); | Stop(); | ||||
| @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "JackDriverLoader.h" | #include "JackDriverLoader.h" | ||||
| #include "JackCompilerDeps.h" | #include "JackCompilerDeps.h" | ||||
| #include "JackServer.h" | #include "JackServer.h" | ||||
| #include <map> | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| @@ -39,6 +40,9 @@ struct SERVER_EXPORT JackServerGlobals | |||||
| static JackServer* fInstance; | static JackServer* fInstance; | ||||
| static unsigned int fUserCount; | static unsigned int fUserCount; | ||||
| static int fRTNotificationSocket; // For debugging purpose | static int fRTNotificationSocket; // For debugging purpose | ||||
| static std::map<std::string, JackDriverInfo*> fSlavesList; | |||||
| static std::map<std::string, int> fInternalsList; | |||||
| static bool (* on_device_acquire)(const char* device_name); | static bool (* on_device_acquire)(const char* device_name); | ||||
| static void (* on_device_release)(const char* device_name); | static void (* on_device_release)(const char* device_name); | ||||
| @@ -229,8 +229,8 @@ int main(int argc, char* argv[]) | |||||
| int i,opt = 0; | int i,opt = 0; | ||||
| int option_index = 0; | int option_index = 0; | ||||
| char *master_driver_name = NULL; | |||||
| char **master_driver_args = NULL; | |||||
| char* master_driver_name = NULL; | |||||
| char** master_driver_args = NULL; | |||||
| int master_driver_nargs = 1; | int master_driver_nargs = 1; | ||||
| int do_mlock = 1; | int do_mlock = 1; | ||||
| int do_unlock = 0; | int do_unlock = 0; | ||||
| @@ -426,7 +426,7 @@ int main(int argc, char* argv[]) | |||||
| goto fail_free1; | goto fail_free1; | ||||
| } | } | ||||
| // Audio driver | |||||
| // Master driver | |||||
| master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name); | master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name); | ||||
| if (master_driver_ctl == NULL) { | if (master_driver_ctl == NULL) { | ||||
| fprintf(stderr, "Unknown driver \"%s\"\n", master_driver_name); | fprintf(stderr, "Unknown driver \"%s\"\n", master_driver_name); | ||||
| @@ -464,7 +464,7 @@ int main(int argc, char* argv[]) | |||||
| goto fail_free1; | goto fail_free1; | ||||
| } | } | ||||
| // Slave driver | |||||
| // Slave drivers | |||||
| for (it = slaves_list.begin(); it != slaves_list.end(); it++) { | for (it = slaves_list.begin(); it != slaves_list.end(); it++) { | ||||
| jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it); | jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it); | ||||
| if (slave_driver_ctl == NULL) { | if (slave_driver_ctl == NULL) { | ||||
| @@ -488,7 +488,7 @@ int main(int argc, char* argv[]) | |||||
| } | } | ||||
| } | } | ||||
| // Load internal clients | |||||
| // Internal clients | |||||
| for (it = internals_list.begin(); it != internals_list.end(); it++) { | for (it = internals_list.begin(); it != internals_list.end(); it++) { | ||||
| jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); | jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); | ||||
| if (internal_driver_ctl == NULL) { | if (internal_driver_ctl == NULL) { | ||||
| @@ -2291,7 +2291,9 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, | |||||
| int JackAlsaDriver::Close() | int JackAlsaDriver::Close() | ||||
| { | { | ||||
| JackAudioDriver::Close(); | |||||
| // Generic audio driver close | |||||
| int res = JackAudioDriver::Close(); | |||||
| alsa_driver_delete((alsa_driver_t*)fDriver); | alsa_driver_delete((alsa_driver_t*)fDriver); | ||||
| if (JackServerGlobals::on_device_release != NULL) | if (JackServerGlobals::on_device_release != NULL) | ||||
| @@ -2310,7 +2312,7 @@ int JackAlsaDriver::Close() | |||||
| } | } | ||||
| } | } | ||||
| return 0; | |||||
| return res; | |||||
| } | } | ||||
| int JackAlsaDriver::Start() | int JackAlsaDriver::Start() | ||||
| @@ -644,9 +644,11 @@ int JackFFADODriver::Open(ffado_jack_settings_t *params) | |||||
| int JackFFADODriver::Close() | int JackFFADODriver::Close() | ||||
| { | { | ||||
| JackAudioDriver::Close(); | |||||
| // Generic audio driver close | |||||
| int res = JackAudioDriver::Close(); | |||||
| ffado_driver_delete((ffado_driver_t*)fDriver); | ffado_driver_delete((ffado_driver_t*)fDriver); | ||||
| return 0; | |||||
| return res; | |||||
| } | } | ||||
| int JackFFADODriver::Start() | int JackFFADODriver::Start() | ||||
| @@ -832,9 +832,11 @@ int JackFreebobDriver::Open(freebob_jack_settings_t *params) | |||||
| int JackFreebobDriver::Close() | int JackFreebobDriver::Close() | ||||
| { | { | ||||
| JackAudioDriver::Close(); | |||||
| // Generic audio driver close | |||||
| int res = JackAudioDriver::Close(); | |||||
| freebob_driver_delete((freebob_driver_t*)fDriver); | freebob_driver_delete((freebob_driver_t*)fDriver); | ||||
| return 0; | |||||
| return res; | |||||
| } | } | ||||
| int JackFreebobDriver::Start() | int JackFreebobDriver::Start() | ||||
| @@ -1551,12 +1551,15 @@ int JackCoreAudioDriver::Close() | |||||
| { | { | ||||
| jack_log("JackCoreAudioDriver::Close"); | jack_log("JackCoreAudioDriver::Close"); | ||||
| Stop(); | Stop(); | ||||
| JackAudioDriver::Close(); | |||||
| // Generic audio driver close | |||||
| int res = JackAudioDriver::Close(); | |||||
| RemoveListeners(); | RemoveListeners(); | ||||
| DisposeBuffers(); | DisposeBuffers(); | ||||
| CloseAUHAL(); | CloseAUHAL(); | ||||
| DestroyAggregateDevice(); | DestroyAggregateDevice(); | ||||
| return 0; | |||||
| return res; | |||||
| } | } | ||||
| int JackCoreAudioDriver::Attach() | int JackCoreAudioDriver::Attach() | ||||
| @@ -45,15 +45,15 @@ void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuf | |||||
| jack_error("ReadProc : ring buffer is full, skip events..."); | jack_error("ReadProc : ring buffer is full, skip events..."); | ||||
| return; | return; | ||||
| } | } | ||||
| jack_ringbuffer_write(ringbuffer, (char*)&pktlist->numPackets, sizeof(UInt32)); | jack_ringbuffer_write(ringbuffer, (char*)&pktlist->numPackets, sizeof(UInt32)); | ||||
| for (unsigned int i = 0; i < pktlist->numPackets; ++i) { | for (unsigned int i = 0; i < pktlist->numPackets; ++i) { | ||||
| MIDIPacket *packet = (MIDIPacket *)pktlist->packet; | MIDIPacket *packet = (MIDIPacket *)pktlist->packet; | ||||
| // TODO : use timestamp | // TODO : use timestamp | ||||
| // Check available size first.. | // Check available size first.. | ||||
| size = jack_ringbuffer_write_space(ringbuffer); | size = jack_ringbuffer_write_space(ringbuffer); | ||||
| if (size < (sizeof(UInt16) + packet->length)) { | if (size < (sizeof(UInt16) + packet->length)) { | ||||
| @@ -64,7 +64,7 @@ void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuf | |||||
| jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); | jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); | ||||
| // Write event actual data | // Write event actual data | ||||
| jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); | jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); | ||||
| packet = MIDIPacketNext(packet); | packet = MIDIPacketNext(packet); | ||||
| } | } | ||||
| } | } | ||||
| @@ -83,7 +83,7 @@ void JackCoreMidiDriver::ReadVirtualProc(const MIDIPacketList *pktlist, void *re | |||||
| void JackCoreMidiDriver::NotifyProc(const MIDINotification *message, void *refCon) | void JackCoreMidiDriver::NotifyProc(const MIDINotification *message, void *refCon) | ||||
| { | { | ||||
| jack_info("NotifyProc %d", message->messageID); | |||||
| jack_log("NotifyProc %d", message->messageID); | |||||
| } | } | ||||
| JackCoreMidiDriver::JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | JackCoreMidiDriver::JackCoreMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) | ||||
| @@ -106,15 +106,15 @@ int JackCoreMidiDriver::Open(bool capturing, | |||||
| OSStatus err; | OSStatus err; | ||||
| CFStringRef coutputStr; | CFStringRef coutputStr; | ||||
| std::string str; | std::string str; | ||||
| // Get real input/output number | // Get real input/output number | ||||
| fRealCaptureChannels = MIDIGetNumberOfSources(); | fRealCaptureChannels = MIDIGetNumberOfSources(); | ||||
| fRealPlaybackChannels = MIDIGetNumberOfDestinations(); | fRealPlaybackChannels = MIDIGetNumberOfDestinations(); | ||||
| // Generic JackMidiDriver Open | // Generic JackMidiDriver Open | ||||
| if (JackMidiDriver::Open(capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) | if (JackMidiDriver::Open(capturing, playing, inchannels + fRealCaptureChannels, outchannels + fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) | ||||
| return -1; | return -1; | ||||
| coutputStr = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding()); | coutputStr = CFStringCreateWithCString(0, "JackMidi", CFStringGetSystemEncoding()); | ||||
| err = MIDIClientCreate(coutputStr, NotifyProc, this, &fMidiClient); | err = MIDIClientCreate(coutputStr, NotifyProc, this, &fMidiClient); | ||||
| CFRelease(coutputStr); | CFRelease(coutputStr); | ||||
| @@ -122,7 +122,7 @@ int JackCoreMidiDriver::Open(bool capturing, | |||||
| jack_error("Cannot create CoreMidi client"); | jack_error("Cannot create CoreMidi client"); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| err = MIDIInputPortCreate(fMidiClient, CFSTR("Input port"), ReadProc, this, &fInputPort); | err = MIDIInputPortCreate(fMidiClient, CFSTR("Input port"), ReadProc, this, &fInputPort); | ||||
| if (!fInputPort) { | if (!fInputPort) { | ||||
| jack_error("Cannot open CoreMidi in port\n"); | jack_error("Cannot open CoreMidi in port\n"); | ||||
| @@ -134,10 +134,10 @@ int JackCoreMidiDriver::Open(bool capturing, | |||||
| jack_error("Cannot open CoreMidi out port\n"); | jack_error("Cannot open CoreMidi out port\n"); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| fMidiDestination = new MIDIEndpointRef[inchannels + fRealCaptureChannels]; | fMidiDestination = new MIDIEndpointRef[inchannels + fRealCaptureChannels]; | ||||
| assert(fMidiDestination); | assert(fMidiDestination); | ||||
| // Virtual input | // Virtual input | ||||
| for (int i = 0; i < inchannels; i++) { | for (int i = 0; i < inchannels; i++) { | ||||
| std::stringstream num; | std::stringstream num; | ||||
| @@ -151,13 +151,13 @@ int JackCoreMidiDriver::Open(bool capturing, | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| } | } | ||||
| // Real input | // Real input | ||||
| for (int i = 0; i < fRealCaptureChannels; i++) { | for (int i = 0; i < fRealCaptureChannels; i++) { | ||||
| fMidiDestination[i + inchannels] = MIDIGetSource(i); | fMidiDestination[i + inchannels] = MIDIGetSource(i); | ||||
| MIDIPortConnectSource(fInputPort, fMidiDestination[i + inchannels], fRingBuffer[i + inchannels]); | MIDIPortConnectSource(fInputPort, fMidiDestination[i + inchannels], fRingBuffer[i + inchannels]); | ||||
| } | } | ||||
| fMidiSource = new MIDIEndpointRef[outchannels + fRealPlaybackChannels]; | fMidiSource = new MIDIEndpointRef[outchannels + fRealPlaybackChannels]; | ||||
| assert(fMidiSource); | assert(fMidiSource); | ||||
| @@ -172,47 +172,50 @@ int JackCoreMidiDriver::Open(bool capturing, | |||||
| if (!fMidiSource[i]) { | if (!fMidiSource[i]) { | ||||
| jack_error("Cannot create CoreMidi source"); | jack_error("Cannot create CoreMidi source"); | ||||
| goto error; | goto error; | ||||
| } | |||||
| } | |||||
| } | } | ||||
| // Real output | // Real output | ||||
| for (int i = 0; i < fRealPlaybackChannels; i++) { | for (int i = 0; i < fRealPlaybackChannels; i++) { | ||||
| fMidiSource[i + outchannels] = MIDIGetDestination(i); | fMidiSource[i + outchannels] = MIDIGetDestination(i); | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| error: | error: | ||||
| Close(); | Close(); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| int JackCoreMidiDriver::Close() | int JackCoreMidiDriver::Close() | ||||
| { | { | ||||
| // Generic midi driver close | |||||
| int res = JackMidiDriver::Close(); | |||||
| if (fInputPort) | if (fInputPort) | ||||
| MIDIPortDispose(fInputPort); | MIDIPortDispose(fInputPort); | ||||
| if (fOutputPort) | |||||
| if (fOutputPort) | |||||
| MIDIPortDispose(fOutputPort); | MIDIPortDispose(fOutputPort); | ||||
| // Only dispose "virtual" endpoints | // Only dispose "virtual" endpoints | ||||
| for (int i = 0; i < fCaptureChannels - fRealCaptureChannels; i++) { | for (int i = 0; i < fCaptureChannels - fRealCaptureChannels; i++) { | ||||
| if (fMidiDestination) | |||||
| if (fMidiDestination) | |||||
| MIDIEndpointDispose(fMidiDestination[i]); | MIDIEndpointDispose(fMidiDestination[i]); | ||||
| } | } | ||||
| delete[] fMidiDestination; | delete[] fMidiDestination; | ||||
| // Only dispose "virtual" endpoints | // Only dispose "virtual" endpoints | ||||
| for (int i = 0; i < fPlaybackChannels - fRealPlaybackChannels; i++) { | for (int i = 0; i < fPlaybackChannels - fRealPlaybackChannels; i++) { | ||||
| if (fMidiSource[i]) | |||||
| if (fMidiSource[i]) | |||||
| MIDIEndpointDispose(fMidiSource[i]); | MIDIEndpointDispose(fMidiSource[i]); | ||||
| } | } | ||||
| delete[] fMidiSource; | delete[] fMidiSource; | ||||
| if (fMidiClient) | |||||
| if (fMidiClient) | |||||
| MIDIClientDispose(fMidiClient); | MIDIClientDispose(fMidiClient); | ||||
| return 0; | |||||
| return res; | |||||
| } | } | ||||
| int JackCoreMidiDriver::Attach() | int JackCoreMidiDriver::Attach() | ||||
| @@ -229,7 +232,7 @@ int JackCoreMidiDriver::Attach() | |||||
| jack_log("JackCoreMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); | jack_log("JackCoreMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); | ||||
| for (i = 0; i < fCaptureChannels; i++) { | for (i = 0; i < fCaptureChannels; i++) { | ||||
| err = MIDIObjectGetStringProperty(fMidiDestination[i], kMIDIPropertyName, &pname); | err = MIDIObjectGetStringProperty(fMidiDestination[i], kMIDIPropertyName, &pname); | ||||
| if (err == noErr) { | if (err == noErr) { | ||||
| CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); | CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); | ||||
| @@ -238,7 +241,7 @@ int JackCoreMidiDriver::Attach() | |||||
| } else { | } else { | ||||
| snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); | snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); | ||||
| } | } | ||||
| snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); | snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); | ||||
| if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { | if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { | ||||
| jack_error("driver: cannot register port for %s", name); | jack_error("driver: cannot register port for %s", name); | ||||
| @@ -251,7 +254,7 @@ int JackCoreMidiDriver::Attach() | |||||
| } | } | ||||
| for (i = 0; i < fPlaybackChannels; i++) { | for (i = 0; i < fPlaybackChannels; i++) { | ||||
| err = MIDIObjectGetStringProperty(fMidiSource[i], kMIDIPropertyName, &pname); | err = MIDIObjectGetStringProperty(fMidiSource[i], kMIDIPropertyName, &pname); | ||||
| if (err == noErr) { | if (err == noErr) { | ||||
| CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); | CFStringGetCString(pname, endpoint_name, sizeof(endpoint_name), 0); | ||||
| @@ -260,7 +263,7 @@ int JackCoreMidiDriver::Attach() | |||||
| } else { | } else { | ||||
| snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); | snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); | ||||
| } | } | ||||
| snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); | snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); | ||||
| if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { | if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { | ||||
| jack_error("driver: cannot register port for %s", name); | jack_error("driver: cannot register port for %s", name); | ||||
| @@ -277,23 +280,23 @@ int JackCoreMidiDriver::Attach() | |||||
| int JackCoreMidiDriver::Read() | int JackCoreMidiDriver::Read() | ||||
| { | { | ||||
| for (int chan = 0; chan < fCaptureChannels; chan++) { | for (int chan = 0; chan < fCaptureChannels; chan++) { | ||||
| if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { | if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { | ||||
| // Get JACK port | // Get JACK port | ||||
| JackMidiBuffer* midi_buffer = GetInputBuffer(chan); | JackMidiBuffer* midi_buffer = GetInputBuffer(chan); | ||||
| if (jack_ringbuffer_read_space(fRingBuffer[chan]) == 0) { | if (jack_ringbuffer_read_space(fRingBuffer[chan]) == 0) { | ||||
| // Reset buffer | // Reset buffer | ||||
| midi_buffer->Reset(midi_buffer->nframes); | midi_buffer->Reset(midi_buffer->nframes); | ||||
| } else { | } else { | ||||
| while (jack_ringbuffer_read_space(fRingBuffer[chan]) > 0) { | while (jack_ringbuffer_read_space(fRingBuffer[chan]) > 0) { | ||||
| // Read event number | // Read event number | ||||
| int ev_count = 0; | int ev_count = 0; | ||||
| jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); | jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); | ||||
| for (int j = 0; j < ev_count; j++) { | for (int j = 0; j < ev_count; j++) { | ||||
| // Read event length | // Read event length | ||||
| UInt16 event_len; | UInt16 event_len; | ||||
| @@ -304,7 +307,7 @@ int JackCoreMidiDriver::Read() | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } else { | } else { | ||||
| // Consume ring buffer | // Consume ring buffer | ||||
| jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); | jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); | ||||
| @@ -316,35 +319,35 @@ int JackCoreMidiDriver::Read() | |||||
| int JackCoreMidiDriver::Write() | int JackCoreMidiDriver::Write() | ||||
| { | { | ||||
| MIDIPacketList* pktlist = (MIDIPacketList*)fMIDIBuffer; | MIDIPacketList* pktlist = (MIDIPacketList*)fMIDIBuffer; | ||||
| for (int chan = 0; chan < fPlaybackChannels; chan++) { | for (int chan = 0; chan < fPlaybackChannels; chan++) { | ||||
| if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { | if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { | ||||
| MIDIPacket* packet = MIDIPacketListInit(pktlist); | MIDIPacket* packet = MIDIPacketListInit(pktlist); | ||||
| JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); | JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); | ||||
| // TODO : use timestamp | // TODO : use timestamp | ||||
| for (unsigned int j = 0; j < midi_buffer->event_count; j++) { | for (unsigned int j = 0; j < midi_buffer->event_count; j++) { | ||||
| JackMidiEvent* ev = &midi_buffer->events[j]; | JackMidiEvent* ev = &midi_buffer->events[j]; | ||||
| packet = MIDIPacketListAdd(pktlist, sizeof(fMIDIBuffer), packet, MIDIGetCurrentHostTime(), ev->size, ev->GetData(midi_buffer)); | packet = MIDIPacketListAdd(pktlist, sizeof(fMIDIBuffer), packet, MIDIGetCurrentHostTime(), ev->size, ev->GetData(midi_buffer)); | ||||
| } | } | ||||
| if (packet) { | if (packet) { | ||||
| if (chan < fPlaybackChannels - fRealPlaybackChannels) { | if (chan < fPlaybackChannels - fRealPlaybackChannels) { | ||||
| OSStatus err = MIDIReceived(fMidiSource[chan], pktlist); | OSStatus err = MIDIReceived(fMidiSource[chan], pktlist); | ||||
| if (err != noErr) | |||||
| if (err != noErr) | |||||
| jack_error("MIDIReceived error"); | jack_error("MIDIReceived error"); | ||||
| } else { | } else { | ||||
| OSStatus err = MIDISend(fOutputPort, fMidiSource[chan], pktlist); | OSStatus err = MIDISend(fOutputPort, fMidiSource[chan], pktlist); | ||||
| if (err != noErr) | |||||
| if (err != noErr) | |||||
| jack_error("MIDISend error"); | jack_error("MIDISend error"); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -355,7 +358,7 @@ extern "C" | |||||
| { | { | ||||
| #endif | #endif | ||||
| SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() | |||||
| SERVER_EXPORT jack_driver_desc_t * driver_get_descriptor() | |||||
| { | { | ||||
| jack_driver_desc_t * desc; | jack_driver_desc_t * desc; | ||||
| unsigned int i; | unsigned int i; | ||||
| @@ -366,7 +369,7 @@ extern "C" | |||||
| desc->nparams = 2; | desc->nparams = 2; | ||||
| desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); | desc->params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); | ||||
| i = 0; | i = 0; | ||||
| strcpy(desc->params[i].name, "inchannels"); | strcpy(desc->params[i].name, "inchannels"); | ||||
| desc->params[i].character = 'i'; | desc->params[i].character = 'i'; | ||||
| @@ -386,7 +389,7 @@ extern "C" | |||||
| return desc; | return desc; | ||||
| } | } | ||||
| SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) | |||||
| SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) | |||||
| { | { | ||||
| const JSList * node; | const JSList * node; | ||||
| const jack_driver_param_t * param; | const jack_driver_param_t * param; | ||||
| @@ -407,7 +410,7 @@ extern "C" | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| Jack::JackDriverClientInterface* driver = new Jack::JackCoreMidiDriver("system_midi", "coremidi", engine, table); | Jack::JackDriverClientInterface* driver = new Jack::JackCoreMidiDriver("system_midi", "coremidi", engine, table); | ||||
| if (driver->Open(1, 1, virtual_in, virtual_out, false, "in", "out", 0, 0) == 0) { | if (driver->Open(1, 1, virtual_in, virtual_out, false, "in", "out", 0, 0) == 0) { | ||||
| return driver; | return driver; | ||||
| @@ -392,7 +392,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) | |||||
| JackInternalClientLoadRequest req; | JackInternalClientLoadRequest req; | ||||
| JackInternalClientLoadResult res; | JackInternalClientLoadResult res; | ||||
| if (req.Read(socket) == 0) | if (req.Read(socket) == 0) | ||||
| res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); | |||||
| res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); | |||||
| if (res.Write(socket) < 0) | if (res.Write(socket) < 0) | ||||
| jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName); | jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName); | ||||
| break; | break; | ||||
| @@ -180,7 +180,9 @@ error: | |||||
| int JackPortAudioDriver::Close() | int JackPortAudioDriver::Close() | ||||
| { | { | ||||
| // Generic audio driver close | |||||
| int res = JackAudioDriver::Close(); | int res = JackAudioDriver::Close(); | ||||
| jack_log("JackPortAudioDriver::Close"); | jack_log("JackPortAudioDriver::Close"); | ||||
| Pa_CloseStream(fStream); | Pa_CloseStream(fStream); | ||||
| return res; | return res; | ||||
| @@ -264,6 +264,9 @@ int JackWinMMEDriver::Close() | |||||
| { | { | ||||
| jack_log("JackWinMMEDriver::Close"); | jack_log("JackWinMMEDriver::Close"); | ||||
| // Generic midi driver close | |||||
| int res = JackMidiDriver::Close(); | |||||
| // Close input | // Close input | ||||
| if (fMidiDestination) { | if (fMidiDestination) { | ||||
| for (int i = 0; i < fRealCaptureChannels; i++) { | for (int i = 0; i < fRealCaptureChannels; i++) { | ||||
| @@ -280,7 +283,7 @@ int JackWinMMEDriver::Close() | |||||
| delete[] fMidiSource; | delete[] fMidiSource; | ||||
| } | } | ||||
| return 0; | |||||
| return res; | |||||
| } | } | ||||
| int JackWinMMEDriver::Attach() | int JackWinMMEDriver::Attach() | ||||