X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudioengine.cc;h=450bf2a2961f9df696e3d40210049fd6e5c27647;hb=62ce39de7e971ec2b2b37e2e639ad0367fa49056;hp=3aa68478aad978ed930148a0fe0a07ee89fc2da6;hpb=aef76e95d645e4b08f6e3ee54683249b7f995f65;p=ardour.git diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 3aa68478aa..450bf2a296 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -34,27 +34,20 @@ #include #include "midi++/port.h" +#include "midi++/jack_midi_port.h" #include "midi++/mmc.h" #include "midi++/manager.h" -#include "ardour/amp.h" #include "ardour/audio_port.h" #include "ardour/audioengine.h" #include "ardour/buffer.h" -#include "ardour/buffer_set.h" #include "ardour/cycle_timer.h" -#include "ardour/event_type_map.h" -#include "ardour/internal_return.h" #include "ardour/internal_send.h" -#include "ardour/io.h" #include "ardour/meter.h" #include "ardour/midi_port.h" -#include "ardour/process_thread.h" #include "ardour/port.h" -#include "ardour/port_set.h" +#include "ardour/process_thread.h" #include "ardour/session.h" -#include "ardour/timestamps.h" -#include "ardour/utils.h" #include "i18n.h" @@ -69,26 +62,26 @@ AudioEngine* AudioEngine::_instance = 0; #define GET_PRIVATE_JACK_POINTER_RET(j,r) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return r; } AudioEngine::AudioEngine (string client_name, string session_uuid) - : ports (new Ports) + : _jack (0) + , session_remove_pending (false) + , session_removal_countdown (-1) + , _running (false) + , _has_run (false) + , _buffer_size (0) + , _frame_rate (0) + , monitor_check_interval (INT32_MAX) + , last_monitor_check (0) + , _processed_frames (0) + , _freewheeling (false) + , _pre_freewheel_mmc_enabled (false) + , _usecs_per_cycle (0) + , port_remove_in_progress (false) + , m_meter_thread (0) + , _main_thread (0) + , ports (new Ports) { _instance = this; /* singleton */ - session_remove_pending = false; - _running = false; - _has_run = false; - last_monitor_check = 0; - monitor_check_interval = INT32_MAX; - _processed_frames = 0; - _usecs_per_cycle = 0; - _jack = 0; - _frame_rate = 0; - _buffer_size = 0; - _freewheeling = false; - _pre_freewheel_mmc_enabled = false; - _main_thread = 0; - port_remove_in_progress = false; - - m_meter_thread = 0; g_atomic_int_set (&m_meter_exit, 0); if (connect_to_jack (client_name, session_uuid)) { @@ -101,7 +94,7 @@ AudioEngine::AudioEngine (string client_name, string session_uuid) AudioEngine::~AudioEngine () { { - Glib::Mutex::Lock tm (_process_lock); + Glib::Threads::Mutex::Lock tm (_process_lock); session_removed.signal (); if (_running) { @@ -133,7 +126,7 @@ _thread_init_callback (void * /*arg*/) SessionEvent::create_per_thread_pool (X_("Audioengine"), 512); - MIDI::Port::set_process_thread (pthread_self()); + MIDI::JackMIDIPort::set_process_thread (pthread_self()); } static void @@ -233,7 +226,7 @@ AudioEngine::stop (bool forever) } else { jack_deactivate (_priv_jack); Stopped(); /* EMIT SIGNAL */ - MIDI::Port::JackHalted (); /* EMIT SIGNAL */ + MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */ } } @@ -460,7 +453,7 @@ int AudioEngine::process_callback (pframes_t nframes) { GET_PRIVATE_JACK_POINTER_RET(_jack,0); - Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK); + Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK); PT_TIMING_REF; PT_TIMING_CHECK (1); @@ -476,18 +469,57 @@ AudioEngine::process_callback (pframes_t nframes) next_processed_frames = _processed_frames + nframes; } - if (!tm.locked() || _session == 0) { + if (!tm.locked()) { /* return having done nothing */ _processed_frames = next_processed_frames; return 0; } if (session_remove_pending) { + /* perform the actual session removal */ - _session = 0; - session_remove_pending = false; - session_removed.signal(); + + if (session_removal_countdown < 0) { + + /* fade out over 1 second */ + session_removal_countdown = _frame_rate/2; + session_removal_gain = 1.0; + session_removal_gain_step = 1.0/session_removal_countdown; + + } else if (session_removal_countdown > 0) { + + /* we'll be fading audio out. + + if this is the last time we do this as part + of session removal, do a MIDI panic now + to get MIDI stopped. This relies on the fact + that "immediate data" (aka "out of band data") from + MIDI tracks is *appended* after any other data, + so that it emerges after any outbound note ons, etc. + */ + + if (session_removal_countdown <= nframes) { + _session->midi_panic (); + } + + } else { + /* fade out done */ + _session = 0; + session_removal_countdown = -1; // reset to "not in progress" + session_remove_pending = false; + session_removed.signal(); // wakes up thread that initiated session removal + } + } + + if (_session == 0) { + + if (!_freewheeling) { + MIDI::Manager::instance()->cycle_start(nframes); + MIDI::Manager::instance()->cycle_end(); + } + _processed_frames = next_processed_frames; + return 0; } @@ -518,9 +550,13 @@ AudioEngine::process_callback (pframes_t nframes) } } else { + MIDI::Manager::instance()->cycle_start(nframes); + if (_session) { _session->process (nframes); } + + MIDI::Manager::instance()->cycle_end(); } if (_freewheeling) { @@ -553,8 +589,6 @@ AudioEngine::process_callback (pframes_t nframes) if (_session->silent()) { - boost::shared_ptr p = ports.reader(); - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { if (i->second->sends_output()) { @@ -563,6 +597,34 @@ AudioEngine::process_callback (pframes_t nframes) } } + if (session_remove_pending && session_removal_countdown) { + + for (Ports::iterator i = p->begin(); i != p->end(); ++i) { + + if (i->second->sends_output()) { + + boost::shared_ptr ap = boost::dynamic_pointer_cast (i->second); + if (ap) { + Sample* s = ap->engine_get_whole_audio_buffer (); + gain_t g = session_removal_gain; + + for (pframes_t n = 0; n < nframes; ++n) { + *s++ *= g; + g -= session_removal_gain_step; + } + } + } + } + + if (session_removal_countdown > nframes) { + session_removal_countdown -= nframes; + } else { + session_removal_countdown = 0; + } + + session_removal_gain -= (nframes * session_removal_gain_step); + } + // Finalize ports for (Ports::iterator i = p->begin(); i != p->end(); ++i) { @@ -652,7 +714,7 @@ AudioEngine::jack_bufsize_callback (pframes_t nframes) } { - Glib::Mutex::Lock lm (_process_lock); + Glib::Threads::Mutex::Lock lm (_process_lock); boost::shared_ptr p = ports.reader(); @@ -683,8 +745,7 @@ AudioEngine::start_metering_thread () { if (m_meter_thread == 0) { g_atomic_int_set (&m_meter_exit, 0); - m_meter_thread = Glib::Thread::create (boost::bind (&AudioEngine::meter_thread, this), - 500000, true, true, Glib::THREAD_PRIORITY_NORMAL); + m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this)); } } @@ -705,7 +766,7 @@ AudioEngine::meter_thread () void AudioEngine::set_session (Session *s) { - Glib::Mutex::Lock pl (_process_lock); + Glib::Threads::Mutex::Lock pl (_process_lock); SessionHandlePtr::set_session (s); @@ -743,7 +804,7 @@ AudioEngine::set_session (Session *s) void AudioEngine::remove_session () { - Glib::Mutex::Lock lm (_process_lock); + Glib::Threads::Mutex::Lock lm (_process_lock); if (_running) { @@ -1093,7 +1154,7 @@ AudioEngine::halted (void *arg) if (was_running) { ae->Halted(""); /* EMIT SIGNAL */ - MIDI::Port::JackHalted (); /* EMIT SIGNAL */ + MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */ } } @@ -1287,9 +1348,7 @@ AudioEngine::connect_to_jack (string client_name, string session_uuid) { EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa (); boost::scoped_ptr current_epa; - jack_options_t options = JackNullOption; jack_status_t status; - const char *server_name = NULL; /* revert all environment settings back to whatever they were when ardour started */ @@ -1305,7 +1364,7 @@ AudioEngine::connect_to_jack (string client_name, string session_uuid) _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str()); else #endif - _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name); + _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0); if (_jack == NULL) { // error message is not useful here @@ -1331,7 +1390,7 @@ AudioEngine::disconnect_from_jack () } { - Glib::Mutex::Lock lm (_process_lock); + Glib::Threads::Mutex::Lock lm (_process_lock); jack_client_close (_priv_jack); _jack = 0; } @@ -1343,7 +1402,7 @@ AudioEngine::disconnect_from_jack () if (_running) { _running = false; Stopped(); /* EMIT SIGNAL */ - MIDI::Port::JackHalted (); /* EMIT SIGNAL */ + MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */ } return 0;