#include #include #include "jack.h" #include "portmanager.h" #include "gui.h" JackDriver::JackDriver() { m_connected = false; m_client = NULL; } JackDriver::~JackDriver() { Disconnect(); } void JackDriver::Connect() { if (m_connected) return; jack_status_t status; m_client = jack_client_open("jsweeper", JackNoStartServer, &status); if (m_client == NULL) { if (status & JackServerFailed) { std::cerr << "JACK server not running" << std::endl; } else { std::cerr << "jack_client_open() failed, status = " << status << std::endl; } return; } m_buffer = jack_ringbuffer_create(4096); m_connected = true; jack_on_shutdown(m_client, &ShutdownCallbackHandler, this); jack_set_port_registration_callback(m_client, &PortRegistrationCallbackHandler, this); jack_set_port_connect_callback(m_client, &PortConnectCallbackHandler, this); if (jack_set_port_rename_callback) { jack_set_port_rename_callback(m_client, &PortRenameCallbackHandler, this); } jack_activate(m_client); pm.Refresh(); return; } void JackDriver::Disconnect() { if (!m_connected) return; m_connected = false; jack_deactivate(m_client); jack_client_close(m_client); jack_ringbuffer_free(m_buffer); pm.Refresh(); } void JackDriver::ShutdownCallback() { m_connected = false; jack_ringbuffer_free(m_buffer); pm.Refresh(); if (g) g->Refresh(); } void JackDriver::PortRegistrationCallback(jack_port_id_t port_id, int reg) { PortEvent pe; pe.type = reg ? PET_REGISTER : PET_UNREGISTER; pe.port_id_a = port_id; if (jack_ringbuffer_write_space(m_buffer) < sizeof pe) { std::cerr << "Ringbuffer full!" << std::endl; } else { jack_ringbuffer_write(m_buffer, (const char *)&pe, sizeof pe); } } void JackDriver::PortConnectCallback(jack_port_id_t port_id_a, jack_port_id_t port_id_b, int connect) { PortEvent pe; pe.type = connect ? PET_CONNECT : PET_DISCONNECT; pe.port_id_a = port_id_a; pe.port_id_b = port_id_b; if (jack_ringbuffer_write_space(m_buffer) < sizeof pe) { std::cerr << "Ringbuffer full!" << std::endl; } else { jack_ringbuffer_write(m_buffer, (const char *)&pe, sizeof pe); } } int JackDriver::PortRenameCallback(jack_port_id_t port_id) { PortEvent pe; pe.type = PET_RENAME; pe.port_id_a = port_id; if (jack_ringbuffer_write_space(m_buffer) < sizeof pe) { std::cerr << "Ringbuffer full!" << std::endl; } else { jack_ringbuffer_write(m_buffer, (const char *)&pe, sizeof pe); } return 0; } bool JackDriver::ProcessEvents() { bool ret = false; if (!m_connected) return false; PortEvent pe; while (jack_ringbuffer_read_space(m_buffer) >= sizeof pe) { jack_ringbuffer_read(m_buffer, (char *)&pe, sizeof pe); switch (pe.type) { case PET_REGISTER: pm.Add(jack_port_by_id(m_client, pe.port_id_a)); ret = true; break; case PET_UNREGISTER: pm.Delete(jack_port_by_id(m_client, pe.port_id_a)); ret = true; break; case PET_CONNECT: pm.Connect(jack_port_by_id(m_client, pe.port_id_a), jack_port_by_id(m_client, pe.port_id_b)); ret = true; break; case PET_DISCONNECT: pm.Disconnect(jack_port_by_id(m_client, pe.port_id_a), jack_port_by_id(m_client, pe.port_id_b)); ret = true; break; case PET_RENAME: pm.Rename(jack_port_by_id(m_client, pe.port_id_a)); ret = true; break; } } return ret; } void JackDriver::Connect(jack_port_t *a, jack_port_t *b) { jack_connect(m_client, jack_port_name(a), jack_port_name(b)); } void JackDriver::Disconnect(jack_port_t *a, jack_port_t *b) { jack_disconnect(m_client, jack_port_name(a), jack_port_name(b)); }