Support RtAudio >= 6.
authorCarl Hetherington <cth@carlh.net>
Thu, 30 Nov 2023 21:15:46 +0000 (22:15 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 30 Nov 2023 21:15:48 +0000 (22:15 +0100)
There's an API break, mostly about removing the use of exceptions.

src/wx/config_dialog.cc
src/wx/film_viewer.cc
src/wx/film_viewer.h

index 00ae80a4c8f1f30079efa58d555ced06cb7cb803..104835f4a772e6338c1d5e71e5251c355ec1eaa7 100644 (file)
@@ -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 (
index 72193fbadb8e76e6651b1681d2bf5dd0fd35c106..b6f8096e85dda7dcfb07a44a6e19fafb9781fc82 100644 (file)
@@ -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<unsigned int> 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
+
index 0442dac715cbfdef47f26678e1772572be69a588..5824f8baabeba7ca8e233a43a75d4db5ac1b1aad 100644 (file)
@@ -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;