diff options
Diffstat (limited to 'src/libs/engine/JackAudioDriver.cpp')
-rw-r--r-- | src/libs/engine/JackAudioDriver.cpp | 175 |
1 files changed, 80 insertions, 95 deletions
diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp index 8f5c788a..2c0d4a70 100644 --- a/src/libs/engine/JackAudioDriver.cpp +++ b/src/libs/engine/JackAudioDriver.cpp @@ -48,15 +48,15 @@ namespace Ingen { JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort<Sample>* patch_port) : DriverPort(), ListNode<JackAudioPort*>(this), - m_driver(driver), - m_jack_port(NULL), - m_jack_buffer(NULL), - m_patch_port(patch_port) + _driver(driver), + _jack_port(NULL), + _jack_buffer(NULL), + _patch_port(patch_port) { //assert(patch_port->tied_port() != NULL); assert(patch_port->poly() == 1); - m_jack_port = jack_port_register(m_driver->jack_client(), + _jack_port = jack_port_register(_driver->jack_client(), patch_port->path().c_str(), JACK_DEFAULT_AUDIO_TYPE, (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, 0); @@ -67,21 +67,21 @@ JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort<Sample>* patch_ JackAudioPort::~JackAudioPort() { - jack_port_unregister(m_driver->jack_client(), m_jack_port); + jack_port_unregister(_driver->jack_client(), _jack_port); } void JackAudioPort::add_to_driver() { - m_driver->add_port(this); + _driver->add_port(this); } void JackAudioPort::remove_from_driver() { - m_driver->remove_port(this); + _driver->remove_port(this); } void @@ -93,12 +93,12 @@ JackAudioPort::prepare_buffer(jack_nframes_t nframes) m_patch_port->buffer(0)->join(m_jack_buffer); */ - jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(m_jack_port, nframes); + jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(_jack_port, nframes); - if (jack_buf != m_jack_buffer) { + if (jack_buf != _jack_buffer) { //cerr << "Jack buffer: " << jack_buf << endl; - m_patch_port->buffer(0)->set_data(jack_buf); - m_jack_buffer = jack_buf; + _patch_port->buffer(0)->set_data(jack_buf); + _jack_buffer = jack_buf; } //assert(m_patch_port->tied_port() != NULL); @@ -111,47 +111,36 @@ JackAudioPort::prepare_buffer(jack_nframes_t nframes) //m_patch_port->fixed_buffers(true); - //assert(m_patch_port->buffer(0)->data() == m_patch_port->tied_port()->buffer(0)->data()); - assert(m_patch_port->buffer(0)->data() == jack_buf); + //assert(m_patch_port->buffer(0)->data() == _patch_port->tied_port()->buffer(0)->data()); + assert(_patch_port->buffer(0)->data() == jack_buf); } //// JackAudioDriver //// -JackAudioDriver::JackAudioDriver() -: m_client(NULL), - m_buffer_size(0), - m_sample_rate(0), - m_is_activated(false), - m_local_client(true), - m_root_patch(NULL) +JackAudioDriver::JackAudioDriver(Engine& engine, jack_client_t* jack_client) +: _engine(engine), + _client(jack_client), + _buffer_size(jack_client ? jack_get_buffer_size(jack_client) : 0), + _sample_rate(jack_client ? jack_get_sample_rate(jack_client) : 0), + _is_activated(false), + _local_client(false), + _root_patch(NULL) { - m_client = jack_client_new("Ingen"); - if (m_client == NULL) { - cerr << "[JackAudioDriver] Unable to connect to Jack. Exiting." << endl; - exit(EXIT_FAILURE); + if (!_client) { + _client = jack_client_new("Ingen"); + if (_client == NULL) { + cerr << "[JackAudioDriver] Unable to connect to Jack. Exiting." << endl; + exit(EXIT_FAILURE); + } + _buffer_size = jack_get_buffer_size(_client); + _sample_rate = jack_get_sample_rate(_client); } - jack_on_shutdown(m_client, shutdown_cb, this); - - m_buffer_size = jack_get_buffer_size(m_client); - m_sample_rate = jack_get_sample_rate(m_client); + jack_on_shutdown(_client, shutdown_cb, this); - jack_set_sample_rate_callback(m_client, sample_rate_cb, this); - jack_set_buffer_size_callback(m_client, buffer_size_cb, this); -} - -JackAudioDriver::JackAudioDriver(jack_client_t* jack_client) -: m_client(jack_client), - m_buffer_size(jack_get_buffer_size(jack_client)), - m_sample_rate(jack_get_sample_rate(jack_client)), - m_is_activated(false), - m_local_client(false) -{ - jack_on_shutdown(m_client, shutdown_cb, this); - - jack_set_sample_rate_callback(m_client, sample_rate_cb, this); - jack_set_buffer_size_callback(m_client, buffer_size_cb, this); + jack_set_sample_rate_callback(_client, sample_rate_cb, this); + jack_set_buffer_size_callback(_client, buffer_size_cb, this); } @@ -159,30 +148,30 @@ JackAudioDriver::~JackAudioDriver() { deactivate(); - if (m_local_client) - jack_client_close(m_client); + if (_local_client) + jack_client_close(_client); } void JackAudioDriver::activate() { - if (m_is_activated) { + if (_is_activated) { cerr << "[JackAudioDriver] Jack driver already activated." << endl; return; } - jack_set_process_callback(m_client, process_cb, this); + jack_set_process_callback(_client, process_cb, this); - m_is_activated = true; + _is_activated = true; - if (jack_activate(m_client)) { + if (jack_activate(_client)) { cerr << "[JackAudioDriver] Could not activate Jack client, aborting." << endl; exit(EXIT_FAILURE); } else { cout << "[JackAudioDriver] Activated Jack client." << endl; #ifdef HAVE_LASH - Engine::instance().lash_driver()->set_jack_client_name(jack_client_get_name(m_client)); + _engine.lash_driver()->set_jack_client_name(jack_client_get_name(_client)); #endif } } @@ -191,20 +180,20 @@ JackAudioDriver::activate() void JackAudioDriver::deactivate() { - if (m_is_activated) { - Engine::instance().osc_receiver()->deactivate(); + if (_is_activated) { + _engine.osc_receiver()->deactivate(); - jack_deactivate(m_client); - m_is_activated = false; + jack_deactivate(_client); + _is_activated = false; - for (List<JackAudioPort*>::iterator i = m_ports.begin(); i != m_ports.end(); ++i) - jack_port_unregister(m_client, (*i)->jack_port()); + for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) + jack_port_unregister(_client, (*i)->jack_port()); - m_ports.clear(); + _ports.clear(); cout << "[JackAudioDriver] Deactivated Jack client." << endl; - Engine::instance().post_processor()->stop(); + _engine.post_processor()->stop(); } } @@ -219,7 +208,7 @@ JackAudioDriver::deactivate() void JackAudioDriver::add_port(JackAudioPort* port) { - m_ports.push_back(port); + _ports.push_back(port); } @@ -234,9 +223,9 @@ JackAudioDriver::add_port(JackAudioPort* port) JackAudioPort* JackAudioDriver::remove_port(JackAudioPort* port) { - for (List<JackAudioPort*>::iterator i = m_ports.begin(); i != m_ports.end(); ++i) + for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) if ((*i) == port) - return m_ports.remove(i)->elem(); + return _ports.remove(i)->elem(); cerr << "[JackAudioDriver::remove_port] WARNING: Failed to find Jack port to remove!" << endl; return NULL; @@ -246,7 +235,7 @@ JackAudioDriver::remove_port(JackAudioPort* port) DriverPort* JackAudioDriver::create_port(DuplexPort<Sample>* patch_port) { - if (patch_port->buffer_size() == m_buffer_size) + if (patch_port->buffer_size() == _buffer_size) return new JackAudioPort(this, patch_port); else return NULL; @@ -258,7 +247,7 @@ JackAudioDriver::create_port(DuplexPort<Sample>* patch_port) * Called from the realtime thread once every process cycle. */ void -JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block_end) +JackAudioDriver::process_events(SampleCount nframes, FrameTime cycle_start, FrameTime cycle_end) { Event* ev = NULL; @@ -266,10 +255,9 @@ JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block * makes the process callback (more) realtime-safe by preventing being * choked by events coming in faster than they can be processed. * FIXME: run the math on this and figure out a good value */ - const unsigned int MAX_QUEUED_EVENTS = m_buffer_size / 100; + const unsigned int MAX_QUEUED_EVENTS = _buffer_size / 100; unsigned int num_events_processed = 0; - unsigned int offset = 0; // Process the "slow" events first, because it's possible some of the // RT events depend on them @@ -277,26 +265,21 @@ JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block /* FIXME: Merge these next two loops into one */ // FIXME - while ((ev = Engine::instance().osc_receiver()->pop_earliest_queued_before(block_end))) { - ev->execute(0); // QueuedEvents are not sample accurate - Engine::instance().post_processor()->push(ev); + while ((ev = _engine.osc_receiver()->pop_earliest_queued_before(cycle_end))) { + ev->execute(nframes, cycle_start, cycle_end); + _engine.post_processor()->push(ev); if (++num_events_processed > MAX_QUEUED_EVENTS) break; } - while ((ev = Engine::instance().osc_receiver()->pop_earliest_stamped_before(block_end))) { - if (ev->time_stamp() >= block_start) - offset = ev->time_stamp() - block_start; - else - offset = 0; - - ev->execute(offset); - Engine::instance().post_processor()->push(ev); + while ((ev = _engine.osc_receiver()->pop_earliest_stamped_before(cycle_end))) { + ev->execute(nframes, cycle_start, cycle_end); + _engine.post_processor()->push(ev); ++num_events_processed; } if (num_events_processed > 0) - Engine::instance().post_processor()->whip(); + _engine.post_processor()->whip(); } @@ -310,68 +293,70 @@ JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block * \callgraph */ int -JackAudioDriver::m_process_cb(jack_nframes_t nframes) +JackAudioDriver::_process_cb(jack_nframes_t nframes) { + // FIXME: all of this time stuff is screwy + static jack_nframes_t start_of_current_cycle = 0; static jack_nframes_t start_of_last_cycle = 0; // FIXME: support nframes != buffer_size, even though that never damn well happens - assert(nframes == m_buffer_size); + assert(nframes == _buffer_size); // Jack can elect to not call this function for a cycle, if overloaded // FIXME: this doesn't make sense, and the start time isn't used anyway - start_of_current_cycle = jack_last_frame_time(m_client); + start_of_current_cycle = jack_last_frame_time(_client); start_of_last_cycle = start_of_current_cycle - nframes; // FIXME: ditto assert(start_of_current_cycle - start_of_last_cycle == nframes); - m_transport_state = jack_transport_query(m_client, &m_position); + _transport_state = jack_transport_query(_client, &_position); - process_events(start_of_last_cycle, start_of_current_cycle); - Engine::instance().midi_driver()->prepare_block(start_of_last_cycle, start_of_current_cycle); + process_events(nframes, start_of_last_cycle, start_of_current_cycle); + _engine.midi_driver()->prepare_block(start_of_last_cycle, start_of_current_cycle); // Set buffers of patch ports to Jack port buffers (zero-copy processing) - for (List<JackAudioPort*>::iterator i = m_ports.begin(); i != m_ports.end(); ++i) + for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) (*i)->prepare_buffer(nframes); // Run root patch - assert(m_root_patch != NULL); - m_root_patch->process(nframes); + assert(_root_patch != NULL); + _root_patch->process(nframes, start_of_current_cycle, start_of_current_cycle + nframes); return 0; } void -JackAudioDriver::m_shutdown_cb() +JackAudioDriver::_shutdown_cb() { cout << "[JackAudioDriver] Jack shutdown. Exiting." << endl; - Engine::instance().quit(); + _engine.quit(); } int -JackAudioDriver::m_sample_rate_cb(jack_nframes_t nframes) +JackAudioDriver::_sample_rate_cb(jack_nframes_t nframes) { - if (m_is_activated) { + if (_is_activated) { cerr << "[JackAudioDriver] On-the-fly sample rate changing not supported (yet). Aborting." << endl; exit(EXIT_FAILURE); } else { - m_sample_rate = nframes; + _sample_rate = nframes; } return 0; } int -JackAudioDriver::m_buffer_size_cb(jack_nframes_t nframes) +JackAudioDriver::_buffer_size_cb(jack_nframes_t nframes) { - if (m_is_activated) { + if (_is_activated) { cerr << "[JackAudioDriver] On-the-fly buffer size changing not supported (yet). Aborting." << endl; exit(EXIT_FAILURE); } else { - m_buffer_size = nframes; + _buffer_size = nframes; } return 0; } |