Implemented Tracks backend/engine reaction on device configuration changes (like I/O layout changes etc.) on Windows

This commit is contained in:
Greg Zharun 2014-07-01 14:25:03 +03:00
parent c8b931d1b5
commit 9cdb799f3b
5 changed files with 65 additions and 23 deletions

View file

@ -669,12 +669,11 @@ TracksControlPanel::populate_sample_rate_combo()
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1); PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
set_popdown_strings (_sample_rate_combo, s); set_popdown_strings (_sample_rate_combo, s);
_sample_rate_combo.set_sensitive (s.size() > 1); _sample_rate_combo.set_sensitive (s.size() > 1);
}
if (!s.empty() ) { if (!s.empty() ) {
std::string active_sr = rate_as_string(EngineStateController::instance()->get_current_sample_rate() ); std::string active_sr = rate_as_string(EngineStateController::instance()->get_current_sample_rate() );
_sample_rate_combo.set_active_text(active_sr);
_sample_rate_combo.set_active_text(active_sr); }
} }
} }
@ -694,11 +693,11 @@ TracksControlPanel::populate_buffer_size_combo()
PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1); PBD::Unwinder<uint32_t> protect_ignore_changes (_ignore_changes, _ignore_changes + 1);
set_popdown_strings (_buffer_size_combo, s); set_popdown_strings (_buffer_size_combo, s);
_buffer_size_combo.set_sensitive (s.size() > 1); _buffer_size_combo.set_sensitive (s.size() > 1);
}
if (!s.empty() ) { if (!s.empty() ) {
std::string active_bs = bufsize_as_string(EngineStateController::instance()->get_current_buffer_size()); std::string active_bs = bufsize_as_string(EngineStateController::instance()->get_current_buffer_size());
_buffer_size_combo.set_active_text(active_bs); _buffer_size_combo.set_active_text(active_bs);
}
} }
} }
@ -1133,12 +1132,8 @@ TracksControlPanel::sample_rate_changed()
void void
TracksControlPanel::engine_running () TracksControlPanel::engine_running ()
{ {
_buffer_size_combo.set_active_text (bufsize_as_string (EngineStateController::instance()->get_current_buffer_size() ) ); populate_buffer_size_combo();
populate_sample_rate_combo();
_sample_rate_combo.set_active_text (rate_as_string (EngineStateController::instance()->get_current_sample_rate() ) );
_buffer_size_combo.set_sensitive (true);
_sample_rate_combo.set_sensitive (true);
} }

View file

@ -107,6 +107,8 @@ public:
bool in_process_thread (); bool in_process_thread ();
uint32_t process_thread_count (); uint32_t process_thread_count ();
void request_backend_reset();
bool is_realtime() const; bool is_realtime() const;
bool connected() const; bool connected() const;
@ -230,6 +232,7 @@ public:
/// the number of frames processed since start() was called /// the number of frames processed since start() was called
framecnt_t _processed_frames; framecnt_t _processed_frames;
Glib::Threads::Thread* m_meter_thread; Glib::Threads::Thread* m_meter_thread;
Glib::Threads::Thread* m_hw_event_thread;
ProcessThread* _main_thread; ProcessThread* _main_thread;
MTDM* _mtdm; MTDM* _mtdm;
bool _measuring_latency; bool _measuring_latency;
@ -243,6 +246,9 @@ public:
bool _started_for_latency; bool _started_for_latency;
bool _in_destructor; bool _in_destructor;
void do_reset_backend();
void wait_hw_event_processing_complete();
void meter_thread (); void meter_thread ();
void start_metering_thread (); void start_metering_thread ();
void stop_metering_thread (); void stop_metering_thread ();

View file

@ -89,6 +89,7 @@ AudioEngine::~AudioEngine ()
{ {
_in_destructor = true; _in_destructor = true;
stop_metering_thread (); stop_metering_thread ();
wait_hw_event_processing_complete();
drop_backend (); drop_backend ();
} }
@ -362,6 +363,44 @@ AudioEngine::process_callback (pframes_t nframes)
} }
void
AudioEngine::request_backend_reset()
{
if (m_hw_event_thread != 0) {
m_hw_event_thread->join ();
m_hw_event_thread = 0;
}
m_hw_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
}
void
AudioEngine::do_reset_backend()
{
SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 512);
if (_backend) {
std::string name = _backend->device_name ();
stop();
_backend->drop_device();
_backend->set_device_name(name);
start();
SampleRateChanged(_backend->sample_rate() );
BufferSizeChanged(_backend->buffer_size() );
}
}
void
AudioEngine::wait_hw_event_processing_complete()
{
m_hw_event_thread->join ();
m_hw_event_thread = 0;
}
void void
AudioEngine::stop_metering_thread () AudioEngine::stop_metering_thread ()
{ {
@ -653,7 +692,6 @@ AudioEngine::start (bool for_latency)
_backend->set_time_master (true); _backend->set_time_master (true);
} }
_session->reconnect_existing_routes (true, true);
} }
start_metering_thread (); start_metering_thread ();

View file

@ -28,13 +28,16 @@ void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reaso
switch (reason) { switch (reason) {
case WCMRAudioDeviceManagerClient::DeviceDebugInfo: case WCMRAudioDeviceManagerClient::DeviceDebugInfo:
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDebugInfo -- " << (char*)parameter << std::endl; std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDebugInfo -- " << (char*)parameter << std::endl;
break; break;
case WCMRAudioDeviceManagerClient::BufferSizeChanged: case WCMRAudioDeviceManagerClient::BufferSizeChanged:
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::BufferSizeChanged: " << *(uint32_t*)parameter << std::endl; std::cout << "------------------------------- WCMRAudioDeviceManagerClient::BufferSizeChanged: " << *(uint32_t*)parameter << std::endl;
_buffer_size_change(*(uint32_t*)parameter); _buffer_size_change(*(uint32_t*)parameter);
break; break;
case WCMRAudioDeviceManagerClient::RequestReset: case WCMRAudioDeviceManagerClient::RequestReset:
{
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestReset" << std::endl; std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestReset" << std::endl;
engine.request_backend_reset();
}
break; break;
case WCMRAudioDeviceManagerClient::RequestResync: case WCMRAudioDeviceManagerClient::RequestResync:
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestResync" << std::endl; std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestResync" << std::endl;
@ -43,6 +46,9 @@ void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reaso
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::SamplingRateChanged: " << *(float*)parameter << std::endl; std::cout << "------------------------------- WCMRAudioDeviceManagerClient::SamplingRateChanged: " << *(float*)parameter << std::endl;
set_sample_rate(*(float*)parameter); set_sample_rate(*(float*)parameter);
break; break;
case WCMRAudioDeviceManagerClient::Dropout:
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::Dropout: " << std::endl;
break;
case WCMRAudioDeviceManagerClient::DeviceDroppedSamples: case WCMRAudioDeviceManagerClient::DeviceDroppedSamples:
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDroppedSamples" << std::endl; std::cout << "------------------------------- WCMRAudioDeviceManagerClient::DeviceDroppedSamples" << std::endl;
break; break;
@ -816,7 +822,7 @@ WavesAudioBackend::_audio_device_callback (const float* input_buffer,
uint64_t dsp_end_time_nanos = __get_time_nanos(); uint64_t dsp_end_time_nanos = __get_time_nanos();
_dsp_load_accumulator -= *_dsp_load_history.begin(); _dsp_load_accumulator -= *_dsp_load_history.begin();
_dsp_load_history.pop_front(); _dsp_load_history.pop_front();
uint64_t dsp_load_nanos = dsp_end_time_nanos - dsp_start_time_nanos; uint64_t dsp_load_nanos = dsp_end_time_nanos - dsp_start_time_nanos;
_dsp_load_accumulator += dsp_load_nanos; _dsp_load_accumulator += dsp_load_nanos;
_dsp_load_history.push_back(dsp_load_nanos); _dsp_load_history.push_back(dsp_load_nanos);

View file

@ -998,9 +998,6 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
bool wasStreaming = Streaming(); bool wasStreaming = Streaming();
bool wasActive = Active(); bool wasActive = Active();
// Notify the Application about reset
m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
// Reset the device // Reset the device
stopStreaming(); stopStreaming();
deactivateDevice(); deactivateDevice();
@ -1080,7 +1077,7 @@ long WCMRPortAudioDevice::ASIOMessageHook (long selector, long WCUNUSEDPARAM(val
case kAsioResetRequest: case kAsioResetRequest:
m_ResetRequested++; m_ResetRequested++;
std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioResetRequest" << std::endl; std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioResetRequest" << std::endl;
SetEvent(m_hResetFromDevRequestedEvent); m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
break; break;
case kAsioResyncRequest: case kAsioResyncRequest: