From 595d3ce932864fa5fb35cf9f52ac50178b8bd173 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 30 Nov 2023 22:15:46 +0100 Subject: [PATCH] Support RtAudio >= 6. There's an API break, mostly about removing the use of exceptions. --- src/wx/config_dialog.cc | 26 ++++++++++++++++++ src/wx/film_viewer.cc | 60 +++++++++++++++++++++++++++++++++++++++++ src/wx/film_viewer.h | 7 +++++ 3 files changed, 93 insertions(+) diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 00ae80a4c..104835f4a 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -880,6 +880,14 @@ SoundPage::setup () _sound_output_details->SetFont (font); RtAudio audio (DCPOMATIC_RTAUDIO_API); +#if (RTAUDIO_VERSION_MAJOR >= 6) + for (auto device_id: audio.getDeviceIds()) { + auto dev = audio.getDeviceInfo(device_id); + if (dev.outputChannels > 0) { + _sound_output->Append(std_to_wx(dev.name)); + } + } +#else for (unsigned int i = 0; i < audio.getDeviceCount(); ++i) { try { auto dev = audio.getDeviceInfo (i); @@ -890,6 +898,7 @@ SoundPage::setup () /* Something went wrong so let's just ignore that device */ } } +#endif _sound->bind(&SoundPage::sound_changed, this); _sound_output->Bind (wxEVT_CHOICE, bind(&SoundPage::sound_output_changed, this)); @@ -921,11 +930,15 @@ SoundPage::sound_output_changed () RtAudio audio (DCPOMATIC_RTAUDIO_API); auto const so = get_sound_output(); string default_device; +#if (RTAUDIO_VERSION_MAJOR >= 6) + default_device = audio.getDeviceInfo(audio.getDefaultOutputDevice()).name; +#else try { default_device = audio.getDeviceInfo(audio.getDefaultOutputDevice()).name; } catch (RtAudioError&) { /* Never mind */ } +#endif if (!so || *so == default_device) { Config::instance()->unset_sound_output (); } else { @@ -948,11 +961,15 @@ SoundPage::config_changed () } else { /* No configured output means we should use the default */ RtAudio audio (DCPOMATIC_RTAUDIO_API); +#if (RTAUDIO_VERSION_MAJOR >= 6) + configured_so = audio.getDeviceInfo(audio.getDefaultOutputDevice()).name; +#else try { configured_so = audio.getDeviceInfo(audio.getDefaultOutputDevice()).name; } catch (RtAudioError&) { /* Probably no audio devices at all */ } +#endif } if (configured_so && current_so != configured_so) { @@ -982,6 +999,14 @@ SoundPage::config_changed () int channels = 0; if (configured_so) { +#if (RTAUDIO_VERSION_MAJOR >= 6) + for (auto device_id: audio.getDeviceIds()) { + auto info = audio.getDeviceInfo(device_id); + if (info.name == *configured_so && info.outputChannels > 0) { + channels = info.outputChannels; + } + } +#else for (unsigned int i = 0; i < audio.getDeviceCount(); ++i) { try { auto info = audio.getDeviceInfo(i); @@ -992,6 +1017,7 @@ SoundPage::config_changed () /* Never mind */ } } +#endif } _sound_output_details->SetLabel ( diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 72193fbad..b6f8096e8 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -86,7 +86,11 @@ rtaudio_callback (void* out, void *, unsigned int frames, double, RtAudioStreamS FilmViewer::FilmViewer (wxWindow* p) +#if (RTAUDIO_VERSION_MAJOR >= 6) + : _audio(DCPOMATIC_RTAUDIO_API, boost::bind(&FilmViewer::rtaudio_error_callback, this, _2)) +#else : _audio (DCPOMATIC_RTAUDIO_API) +#endif , _closed_captions_dialog (new ClosedCaptionsDialog(p, this)) { #if wxCHECK_VERSION(3, 1, 0) @@ -351,6 +355,15 @@ FilmViewer::start_audio_stream_if_open () { if (_audio.isStreamOpen()) { _audio.setStreamTime (_video_view->position().seconds()); +#if (RTAUDIO_VERSION_MAJOR >= 6) + if (_audio.startStream() != RTAUDIO_NO_ERROR) { + _audio_channels = 0; + error_dialog( + _video_view->get(), + _("There was a problem starting audio playback. Please try another audio output device in Preferences."), std_to_wx(last_rtaudio_error()) + ); + } +#else try { _audio.startStream (); } catch (RtAudioError& e) { @@ -360,6 +373,7 @@ FilmViewer::start_audio_stream_if_open () _("There was a problem starting audio playback. Please try another audio output device in Preferences."), std_to_wx(e.what()) ); } +#endif } } @@ -609,6 +623,33 @@ FilmViewer::config_changed (Config::Property p) } if (Config::instance()->sound() && _audio.getDeviceCount() > 0) { + optional chosen_device_id; +#if (RTAUDIO_VERSION_MAJOR >= 6) + if (Config::instance()->sound_output()) { + for (auto device_id: _audio.getDeviceIds()) { + if (_audio.getDeviceInfo(device_id).name == Config::instance()->sound_output().get()) { + chosen_device_id = device_id; + break; + } + } + } + + if (!chosen_device_id) { + chosen_device_id = _audio.getDefaultOutputDevice(); + } + _audio_channels = _audio.getDeviceInfo(*chosen_device_id).outputChannels; + RtAudio::StreamParameters sp; + sp.deviceId = *chosen_device_id; + sp.nChannels = _audio_channels; + sp.firstChannel = 0; + if (_audio.openStream(&sp, 0, RTAUDIO_FLOAT32, 48000, &_audio_block_size, &rtaudio_callback, this) != RTAUDIO_NO_ERROR) { + _audio_channels = 0; + error_dialog( + _video_view->get(), + _("Could not set up audio output. There will be no audio during the preview."), std_to_wx(last_rtaudio_error()) + ); + } +#else unsigned int st = 0; if (Config::instance()->sound_output()) { while (st < _audio.getDeviceCount()) { @@ -650,6 +691,7 @@ FilmViewer::config_changed (Config::Property p) _("Could not set up audio output. There will be no audio during the preview."), std_to_wx(e.what()) ); } +#endif destroy_and_maybe_create_butler(); } else { @@ -856,3 +898,21 @@ FilmViewer::unset_crop_guess () _video_view->update (); } + +#if (RTAUDIO_VERSION_MAJOR >= 6) +void +FilmViewer::rtaudio_error_callback(string const& error) +{ + boost::mutex::scoped_lock lm(_last_rtaudio_error_mutex); + _last_rtaudio_error = error; +} + + +string +FilmViewer::last_rtaudio_error() const +{ + boost::mutex::scoped_lock lm(_last_rtaudio_error_mutex); + return _last_rtaudio_error; +} +#endif + diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 0442dac71..5824f8baa 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -171,6 +171,13 @@ private: void ui_finished (); void start_audio_stream_if_open (); +#if (RTAUDIO_VERSION_MAJOR >= 6) + void rtaudio_error_callback(std::string const& error); + mutable boost::mutex _last_rtaudio_error_mutex; + std::string _last_rtaudio_error; + std::string last_rtaudio_error() const; +#endif + dcpomatic::DCPTime uncorrected_time () const; Frame average_latency () const; -- 2.30.2