jsweeper/src/jack.cpp

166 lines
3.5 KiB
C++

#include <iostream>
#include <stdlib.h>
#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));
}