smooth 0.5 second fade out during quit, plus MIDI panic to turn everything off (someone will want an opton for that, no doubt)
git-svn-id: svn://localhost/ardour2/branches/3.0@12814 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
33d17f176b
commit
39becbeb70
@ -755,11 +755,6 @@ ARDOUR_UI::finish()
|
||||
if (_session) {
|
||||
int tries = 0;
|
||||
|
||||
if (_session->transport_rolling() && (++tries < 8)) {
|
||||
_session->request_stop (false, true);
|
||||
usleep (10000);
|
||||
}
|
||||
|
||||
if (_session->dirty()) {
|
||||
vector<string> actions;
|
||||
actions.push_back (_("Don't quit"));
|
||||
|
@ -49,9 +49,12 @@ class AudioPort : public Port
|
||||
friend class AudioEngine;
|
||||
|
||||
AudioPort (std::string const &, Flags);
|
||||
/* special access for engine only */
|
||||
Sample* engine_get_whole_audio_buffer ();
|
||||
|
||||
private:
|
||||
AudioBuffer* _buffer;
|
||||
bool _buf_valid;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
@ -268,6 +268,9 @@ private:
|
||||
Glib::Mutex _process_lock;
|
||||
Glib::Cond session_removed;
|
||||
bool session_remove_pending;
|
||||
frameoffset_t session_removal_countdown;
|
||||
gain_t session_removal_gain;
|
||||
gain_t session_removal_gain_step;
|
||||
bool _running;
|
||||
bool _has_run;
|
||||
mutable framecnt_t _buffer_size;
|
||||
@ -283,6 +286,8 @@ private:
|
||||
bool _pre_freewheel_mmc_enabled;
|
||||
int _usecs_per_cycle;
|
||||
bool port_remove_in_progress;
|
||||
Glib::Thread* m_meter_thread;
|
||||
ProcessThread* _main_thread;
|
||||
|
||||
SerializedRCUManager<Ports> ports;
|
||||
|
||||
@ -331,11 +336,8 @@ private:
|
||||
void start_metering_thread ();
|
||||
void stop_metering_thread ();
|
||||
|
||||
Glib::Thread* m_meter_thread;
|
||||
static gint m_meter_exit;
|
||||
|
||||
ProcessThread* _main_thread;
|
||||
|
||||
struct ThreadData {
|
||||
AudioEngine* engine;
|
||||
boost::function<void()> f;
|
||||
|
@ -73,10 +73,18 @@ AudioBuffer&
|
||||
AudioPort::get_audio_buffer (pframes_t nframes)
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes) +
|
||||
_global_port_buffer_offset + _port_buffer_offset, nframes);
|
||||
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes) +
|
||||
_global_port_buffer_offset + _port_buffer_offset, nframes);
|
||||
return *_buffer;
|
||||
}
|
||||
|
||||
Sample*
|
||||
AudioPort::engine_get_whole_audio_buffer ()
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
return (Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -62,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)) {
|
||||
@ -476,28 +476,43 @@ AudioEngine::process_callback (pframes_t nframes)
|
||||
}
|
||||
|
||||
if (session_remove_pending) {
|
||||
|
||||
/* perform the actual session removal */
|
||||
_session = 0;
|
||||
session_remove_pending = false;
|
||||
|
||||
/* pump one cycle of silence into the ports
|
||||
before the session tears them all down
|
||||
(asynchronously).
|
||||
*/
|
||||
if (session_removal_countdown < 0) {
|
||||
|
||||
boost::shared_ptr<Ports> p = ports.reader();
|
||||
|
||||
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||
|
||||
if (i->second->sends_output()) {
|
||||
i->second->get_buffer (nframes).silence (nframes);
|
||||
/* 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 ();
|
||||
}
|
||||
}
|
||||
|
||||
session_removed.signal();
|
||||
} 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();
|
||||
@ -574,8 +589,6 @@ AudioEngine::process_callback (pframes_t nframes)
|
||||
|
||||
if (_session->silent()) {
|
||||
|
||||
boost::shared_ptr<Ports> p = ports.reader();
|
||||
|
||||
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||
|
||||
if (i->second->sends_output()) {
|
||||
@ -584,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<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (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) {
|
||||
|
@ -158,7 +158,7 @@ Session::process_routes (pframes_t nframes, bool& need_butler)
|
||||
|
||||
const framepos_t start_frame = _transport_frame;
|
||||
const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
|
||||
|
||||
|
||||
if (_process_graph) {
|
||||
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
|
||||
_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
|
||||
|
Loading…
Reference in New Issue
Block a user