Example #1
0
int JackEngine::Close()
{
    jack_log("JackEngine::Close");
    fChannel.Close();

    // Close remaining clients (RT is stopped)
    for (int i = fEngineControl->fDriverNum; i < CLIENT_NUM; i++) {
        if (JackLoadableInternalClient* loadable_client = dynamic_cast<JackLoadableInternalClient*>(fClientTable[i])) {
            jack_log("JackEngine::Close loadable client = %s", loadable_client->GetClientControl()->fName);
            loadable_client->Close();
            fClientTable[i] = NULL;
            delete loadable_client;
        } else if (JackExternalClient* external_client = dynamic_cast<JackExternalClient*>(fClientTable[i])) {
            jack_log("JackEngine::Close external client = %s", external_client->GetClientControl()->fName);
            external_client->Close();
            fClientTable[i] = NULL;
            delete external_client;
        }
    }

    return 0;
}
void JackSocketServerChannel::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum)
{
    JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
    assert(socket);
    int fd = GetFd(socket);
    assert(fd >= 0);

    jack_log("JackSocketServerChannel::ClientRemove ref = %d fd = %d", refnum, fd);
    fSocketTable.erase(fd);
    socket->Close();
    delete socket;
    fRebuild = true;
}
void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res)
{
    int refnum = -1;
    res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &refnum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph);
    if (res->fResult == 0) {
        JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
        assert(socket);
        int fd = GetFd(socket);
        assert(fd >= 0);
        fSocketTable[fd].first = refnum;
        fRebuild = true;
        jack_log("JackSocketServerChannel::ClientAdd ref = %d fd = %d", refnum, fd);
    #ifdef __APPLE__
        int on = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
            jack_log("JackSocketServerChannel::ClientAdd : setsockopt SO_NOSIGPIPE fd = %ld err = %s", fd, strerror(errno));
        }
    #endif
    } else {
        jack_error("Cannot create new client");
    }
}
Example #4
0
int JackServer::Close()
{
    jack_log("JackServer::Close");
    fRequestChannel.Close();
    fAudioDriver->Detach();
    fAudioDriver->Close();
    fFreewheelDriver->Close();
    fEngine->Close();
    // TODO: move that in reworked JackServerGlobals::Destroy()
    JackMessageBuffer::Destroy();
    EndTime();
    return 0;
}
Example #5
0
int JackMidiDriver::Attach()
{
    JackPort* port;
    jack_port_id_t port_index;
    char name[REAL_JACK_PORT_NAME_SIZE];
    char alias[REAL_JACK_PORT_NAME_SIZE];
    int i;

    jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);

    for (i = 0; i < fCaptureChannels; i++) {
        snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1);
        snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1);
        if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
            jack_error("driver: cannot register port for %s", name);
            return -1;
        }
        port = fGraphManager->GetPort(port_index);
        port->SetAlias(alias);
        fCapturePortList[i] = port_index;
        jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index);
    }

    for (i = 0; i < fPlaybackChannels; i++) {
        snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1);
        snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1);
        if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
            jack_error("driver: cannot register port for %s", name);
            return -1;
        }
        port = fGraphManager->GetPort(port_index);
        port->SetAlias(alias);
        fPlaybackPortList[i] = port_index;
        jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index);
    }

    UpdateLatencies();
    return 0;
}
Example #6
0
/* create a new SHM registry segment
 *
 * sets up global registry pointers, if successful
 *
 * returns: 0 if registry created successfully
 *          nonzero error code if unable to allocate a new registry
 */
static int
jack_create_registry (jack_shm_info_t *ri)
{
	/* registry must be locked */
	int shm_fd;

	strncpy (registry_id, "/jack-shm-registry", sizeof (registry_id));

	if ((shm_fd = shm_open (registry_id, O_RDWR|O_CREAT, 0666)) < 0) {
		int rc = errno;
		jack_error ("Cannot create shm registry segment (%s)",
			    strerror (errno));
		return rc;
	}

    /* Previous shm_open result depends of the actual value of umask, force correct file permisssion here */
    if (fchmod(shm_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) {
	    jack_log("Cannot chmod jack-shm-registry (%s) %d %d", strerror (errno));
    }

	/* Set the desired segment size.  NOTE: the non-conformant Mac
	 * OS X POSIX shm only allows ftruncate() on segment creation.
	 */
	if (ftruncate (shm_fd, JACK_SHM_REGISTRY_SIZE) < 0) {
		int rc = errno;
		jack_error ("Cannot set registry size (%s)", strerror (errno));
		jack_remove_shm (&registry_id);
		close (shm_fd);
		return rc;
	}

	if ((ri->ptr.attached_at = mmap (0, JACK_SHM_REGISTRY_SIZE,
				     PROT_READ|PROT_WRITE,
				     MAP_SHARED, shm_fd, 0)) == MAP_FAILED) {
		jack_error ("Cannot mmap shm registry segment (%s)",
			    strerror (errno));
		jack_remove_shm (&registry_id);
		close (shm_fd);
		return EINVAL;
	}

	/* set up global pointers */
	ri->index = JACK_SHM_REGISTRY_INDEX;
	jack_shm_header = ri->ptr.attached_at;
	jack_shm_registry = (jack_shm_registry_t *) (jack_shm_header + 1);

	/* initialize registry contents */
	jack_shm_init_registry ();
	close (shm_fd); 
	return 0;
}
int JackInternalClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
{
    int result;
    char name_res[JACK_CLIENT_NAME_SIZE + 1];
    jack_log("JackInternalClient::Open name = %s", name);

    strncpy(fServerName, server_name, sizeof(fServerName));

    fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
    if (result < 0) {
        int status1 = *status;
        if (status1 & JackVersionError)
            jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
        else
            jack_error("Client name = %s conflits with another running client", name);
        goto error;
    }

    strcpy(fClientControl.fName, name_res);

    // Require new client
    fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result);
    if (result < 0) {
        jack_error("Cannot open client name = %s", name_res);
        goto error;
    }

    SetupDriverSync(false);
    JackGlobals::fClientTable[fClientControl.fRefNum] = this;
    JackGlobals::fServerRunning = true;
    jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum);
    return 0;

error:
    fChannel->Stop();
    fChannel->Close();
    return -1;
}
int JackServer::Stop()
{
    jack_log("JackServer::Stop");
    fEngine->NotifyQuit();
    fChannel.Stop();
    
    fEngine->ShutDown();

    if (fFreewheel) {
        return fThreadedFreewheelDriver->Stop();
    } else {
        return fAudioDriver->Stop();
    }
}
Example #9
0
    bool JackNetAdapter::Init()
    {
        jack_log("JackNetAdapter::Init");

        //init network connection
        if (!JackNetSlaveInterface::Init()) {
            jack_error("JackNetSlaveInterface::Init() error...");
            return false;
        }

        //then set global parameters
        if (!SetParams()) {
            jack_error("SetParams error...");
            return false;
        }

        //set buffers
        if (fCaptureChannels > 0) {
            fSoftCaptureBuffer = new sample_t*[fCaptureChannels];
            for (int port_index = 0; port_index < fCaptureChannels; port_index++) {
                fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize];
                fNetAudioCaptureBuffer->SetBuffer(port_index, fSoftCaptureBuffer[port_index]);
            }
        }

        if (fPlaybackChannels > 0) {
            fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels];
            for (int port_index = 0; port_index < fPlaybackChannels; port_index++) {
                fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize];
                fNetAudioPlaybackBuffer->SetBuffer(port_index, fSoftPlaybackBuffer[port_index]);
            }
        }

        //set audio adapter parameters
        SetAdaptedBufferSize(fParams.fPeriodSize);
        SetAdaptedSampleRate(fParams.fSampleRate);

        // Will do "something" on OSX only...
        fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);

        if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) {
            jack_error("AcquireSelfRealTime error");
        } else {
            set_threaded_log_function();
        }

        //init done, display parameters
        SessionParamsDisplay(&fParams);
        return true;
    }
Example #10
0
// Server to client
int JackSocketNotifyChannel::Open(const char* name)
{
    jack_log("JackSocketNotifyChannel::Open name = %s", name);

    // Connect to client listen socket
    if (fNotifySocket.Connect(jack_client_dir, name, 0) < 0) {
        jack_error("Cannot connect client socket");
        return -1;
    }
    
    // Use a time out for notifications
    fNotifySocket.SetReadTimeOut(SOCKET_TIME_OUT);
    return 0;
}
Example #11
0
// RT
void JackTransportEngine::MakeAllStartingLocating(JackClientInterface** table)
{
    for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) {
        JackClientInterface* client = table[i];
        if (client) {
            JackClientControl* control = client->GetClientControl();
            // Inactive clients don't have their process function called at all, so they must appear as already "rolling" for the transport....
            control->fTransportState = (control->fActive && control->fCallback[kRealTimeCallback]) ? JackTransportStarting : JackTransportRolling;
            control->fTransportSync = true;
            control->fTransportTimebase = true;
            jack_log("MakeAllStartingLocating ref = %ld", i);
        }
    }
}
Example #12
0
int JackWinThread::Kill()
{
    if (fThread != (HANDLE)NULL) { // If thread has been started
        TerminateThread(fThread, 0);
        WaitForSingleObject(fThread, INFINITE);
        CloseHandle(fThread);
        jack_log("JackWinThread::Kill");
        fThread = (HANDLE)NULL;
        fStatus = kIdle;
        return 0;
    } else {
        return -1;
    }
}
Example #13
0
void JackClient::ShutDown(jack_status_t code, const char* message)
{
    jack_log("JackClient::ShutDown");
 
    // If "fInfoShutdown" callback, then call it
    if (fInfoShutdown) {
        fInfoShutdown(code, message, fInfoShutdownArg);
        fInfoShutdown = NULL;
    // Otherwise possibly call the normal "fShutdown"
    } else if (fShutdown) {
        fShutdown(fShutdownArg);
        fShutdown = NULL;
    }
}
Example #14
0
    bool JackNetSlaveInterface::SetParams()
    {
        jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
                fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
                fParams.fSendMidiChannels, fParams.fReturnMidiChannels);

        JackNetInterface::SetParams();

        fTxHeader.fDataStream = 'r';
        fRxHeader.fDataStream = 's';

        // midi net buffers
        if (fParams.fSendMidiChannels > 0) {
            fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData);
        }

        if (fParams.fReturnMidiChannels > 0) {
            fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fTxData);
        }

        try {

            // audio net buffers
            if (fParams.fSendAudioChannels > 0) {
                fNetAudioCaptureBuffer = AudioBufferFactory(fParams.fSendAudioChannels, fRxData);
                assert(fNetAudioCaptureBuffer);
            }

            if (fParams.fReturnAudioChannels > 0) {
                fNetAudioPlaybackBuffer = AudioBufferFactory(fParams.fReturnAudioChannels, fTxData);
                assert(fNetAudioPlaybackBuffer);
            }

        } catch (exception&) {
            jack_error("NetAudioBuffer on slave allocation error...");
            return false;
        }

        // set the new buffer sizes
        if (SetNetBufferSize() == SOCKET_ERROR) {
            jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
            goto error;
        }

        return true;

    error:
        FreeNetworkBuffers();
        return false;
    }
Example #15
0
int JackPosixThread::Kill()
{
    if (fThread != (jack_native_thread_t)NULL) { // If thread has been started
        jack_log("JackPosixThread::Kill");
        void* status;
        pthread_cancel(fThread);
        pthread_join(fThread, &status);
        fStatus = kIdle;
        fThread = (jack_native_thread_t)NULL;
        return 0;
    } else {
        return -1;
    }
}
Example #16
0
void JackClient::SetupRealTime()
{
    jack_log("JackClient::Init : period = %ld computation = %ld constraint = %ld",
             long(int64_t(GetEngineControl()->fPeriod) / 1000.0f),
             long(int64_t(GetEngineControl()->fComputation) / 1000.0f),
             long(int64_t(GetEngineControl()->fConstraint) / 1000.0f));

    // Will do "something" on OSX only...
    fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);

    if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) {
        jack_error("JackClient::AcquireSelfRealTime error");
    }
}
Example #17
0
int JackMMCSS::MMCSSDropRealTime(jack_native_thread_t thread)
{
    if (fHandleTable.find(thread) != fHandleTable.end()) {
        HANDLE task = fHandleTable[thread];
        if (ffMMCSSFun3(task) == 0) {
            jack_error("AvRevertMmThreadCharacteristics error : %d", GetLastError());
        } else {
            jack_log("AvRevertMmThreadCharacteristics success");
        }
        return 0;
    } else {
        return -1;
    }
}
int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* server)
{
    jack_log("JackWinNamedPipeServerChannel::Open");
    snprintf(fServerName, sizeof(fServerName), server_name);

    // Needed for internal connection from JackWinNamedPipeServerNotifyChannel object
    if (ClientListen()) {
        fServer = server;
        return 0;
    } else {
        jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
        return -1;
    }
}
// Server side : destroy the JackGlobals
void JackMachSemaphore::Destroy()
{
    kern_return_t res;

    if (fSemaphore > 0) {
        jack_log("JackMachSemaphore::Destroy name = %s", fName);
        if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) {
            jack_error("JackMachSemaphore::Destroy can't destroy semaphore err = %s", mach_error_string(res));
        }
        fSemaphore = 0;
    } else {
        jack_error("JackMachSemaphore::Destroy semaphore < 0");
    }
}
Example #20
0
int JackWinThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg)
{
    DWORD id;
    *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id);

    if (*thread == NULL) {
        jack_error("Cannot create thread error = %d", GetLastError());
        return -1;
    }

    if (realtime) {

        jack_log("JackWinThread::StartImp : create RT thread");
        if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) {
            jack_error("Cannot set priority class = %d", GetLastError());
            return -1;
        }

    } else {
        jack_log("JackWinThread::StartImp : create non RT thread");
    }

    return 0;
}
Example #21
0
int JackClient::PortDisconnect(const char* src, const char* dst)
{
    jack_log("JackClient::Disconnect src = %s dst = %s", src, dst);
    if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
        jack_error("\"%s\" is too long to be used as a JACK port name.\n", src);
        return -1; 
    }
    if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
        jack_error("\"%s\" is too long to be used as a JACK port name.\n", src);
        return -1; 
    }
    int result = -1;
    fChannel->PortDisconnect(GetClientControl()->fRefNum, src, dst, &result);
    return result;
}
Example #22
0
int JackClient::PortUnRegister(jack_port_id_t port_index)
{
    jack_log("JackClient::PortUnRegister port_index = %ld", port_index);
    list<jack_port_id_t>::iterator it = find(fPortList.begin(), fPortList.end(), port_index);

    if (it != fPortList.end()) {
        fPortList.erase(it);
        int result = -1;
        fChannel->PortUnRegister(GetClientControl()->fRefNum, port_index, &result);
        return result;
    } else {
        jack_error("unregistering a port %ld that is not own by the client", port_index);
        return -1;
    }
}
Example #23
0
/*!
\brief Need to stop thread after deactivating in the server.
*/
int JackClient::Deactivate()
{
    jack_log("JackClient::Deactivate");
    if (!IsActive()) {
        return 0;
    }

    GetClientControl()->fActive = false;

    // Transport related callback become "unactive"
    GetClientControl()->fTransportSync = false;
    GetClientControl()->fTransportTimebase = false;

    // We need to wait for the new engine cycle before stopping the RT thread, but this is done by ClientDeactivate
    int result = -1;
    fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
    jack_log("JackClient::Deactivate res = %ld", result);

    // RT thread is stopped only when needed...
    if (IsRealTime()) {
        fThread.Kill();
    }
    return result;
}
Example #24
0
int JackClient::SessionReply(jack_session_event_t* ev)
{
    if (ev->command_line) {
        strncpy(GetClientControl()->fSessionCommand, ev->command_line, sizeof(GetClientControl()->fSessionCommand));
    } else {
        GetClientControl()->fSessionCommand[0] = '\0';
    }

    GetClientControl()->fSessionFlags = ev->flags;

    jack_log("JackClient::SessionReply... we are here");
    if (fChannel->IsChannelThread()) {
        jack_log("JackClient::SessionReply... in callback reply");
        // OK, immediate reply...
        fSessionReply = kImmediateSessionReply;
        return 0;
    }

    jack_log("JackClient::SessionReply... out of cb");

    int result = -1;
    fChannel->SessionReply(GetClientControl()->fRefNum, &result);
    return result;
}
bool JackPosixSemaphore::Disconnect()
{
    if (fSemaphore) {
        jack_log("JackPosixSemaphore::Disconnect name = %s", fName);
        if (sem_close(fSemaphore) != 0) {
            jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno));
            return false;
        } else {
            fSemaphore = NULL;
            return true;
        }
    } else {
        return true;
    }
}
Example #26
0
bool JackFifo::Disconnect()
{
    if (fFifo >= 0) {
        jack_log("JackFifo::Disconnect %s", fName);
        if (close(fFifo) != 0) {
            jack_error("Disconnect: can't disconnect named fifo name = %s err = %s", fName, strerror(errno));
            return false;
        } else {
            fFifo = -1;
            return true;
        }
    } else {
        return true;
    }
}
Example #27
0
    net_status_t JackNetSlaveInterface::SendStartToMaster()
    {
        jack_log("JackNetSlaveInterface::SendStartToMaster");

        // tell the master to start
        session_params_t net_params;
        memset(&net_params, 0, sizeof(session_params_t));
        SetPacketType(&fParams, START_MASTER);
        SessionParamsHToN(&fParams, &net_params);
        if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
            jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
            return (fSocket.GetError() == NET_CONN_ERROR) ? NET_ERROR : NET_SEND_ERROR;
        }
        return NET_ROLLING;
    }
Example #28
0
int JackMidiDriver::Detach()
{
    int i;
    jack_log("JackMidiDriver::Detach");

    for (i = 0; i < fCaptureChannels; i++) {
        fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]);
    }

    for (i = 0; i < fPlaybackChannels; i++) {
        fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]);
    }

    return 0;
}
// Client side : get the published semaphore from server
bool JackAndroidSemaphore::ConnectInput(const char* name, const char* server_name)
{
    pthread_mutex_lock (&mutex);
    BuildName(name, server_name, fName, sizeof(fName));
    jack_log("JackAndroidSemaphore::Connect name = %s", fName);

    // Temporary...
    if (fSemaphore) {
        jack_log("Already connected name = %s", name);
        pthread_mutex_unlock (&mutex);
        return true;
    }

	android::sp<android::IAndroidShm> service = android::Shm::getShmService();
	if(service == NULL){
		jack_error("shm service is null");
		return false;
	}

    fSemaphoreMemory = service->InitSemaphore(fName);
    if(fSemaphoreMemory != NULL){
        fSemaphore = (sem_t*)(fSemaphoreMemory->getBase());
    }

    if(fSemaphore == NULL) {
        jack_error("Connect: can't connect named semaphore name = %s err = %s", fName, strerror(errno));
        pthread_mutex_unlock (&mutex);
        return false;
    } else {
        int val = 0;
        sem_getvalue(fSemaphore, &val);
        jack_log("JackAndroidSemaphore::Connect sem_getvalue %ld", val);
        pthread_mutex_unlock (&mutex);
        return true;
    }
}
void JackSocketServerChannel::BuildPoolTable()
{
    if (fRebuild) {
        fRebuild = false;
        delete[] fPollTable;
        fPollTable = new pollfd[fSocketTable.size() + 1];

        jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1);

        // First fd is the server request socket
        fPollTable[0].fd = fRequestListenSocket.GetFd();
        fPollTable[0].events = POLLIN | POLLERR;

        // Next fd for clients
        map<int, pair<int, JackClientSocket*> >::iterator it;
        int i;

        for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
            jack_log("JackSocketServerChannel::BuildPoolTable fSocketTable i = %ld fd = %ld", i, it->first);
            fPollTable[i].fd = it->first;
            fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
        }
    }
}