Bind audio API choice to do something.
authorCarl Hetherington <cth@carlh.net>
Sat, 12 Nov 2022 23:11:11 +0000 (00:11 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 12 Nov 2022 23:12:26 +0000 (00:12 +0100)
src/wx/config_dialog.cc
src/wx/config_dialog.h
src/wx/film_viewer.cc

index 50e067aaefe41548288df28f20ef67e704c1e279..3055d248b500adc74aa16adefeb61997c6521063 100644 (file)
@@ -892,6 +892,21 @@ SoundPage::setup ()
                _sound_api->add(api.name(), new wxStringClientData(api.id()));
        }
 
+       update_sound_outputs();
+
+       _sound->bind(&SoundPage::sound_changed, this);
+       _sound_api->bind(&SoundPage::sound_api_changed, this);
+       _sound_output->Bind(wxEVT_CHOICE, bind(&SoundPage::sound_output_changed, this));
+       _map->Changed.connect(bind(&SoundPage::map_changed, this, _1));
+       _reset_to_default->Bind(wxEVT_BUTTON, bind(&SoundPage::reset_to_default, this));
+}
+
+
+
+void
+SoundPage::update_sound_outputs()
+{
+       _sound_output->Clear();
        auto& audio = _viewer->audio_backend();
        for (unsigned int i = 0; i < audio.getDeviceCount(); ++i) {
                try {
@@ -903,13 +918,9 @@ SoundPage::setup ()
                        /* Something went wrong so let's just ignore that device */
                }
        }
-
-       _sound->bind(&SoundPage::sound_changed, this);
-       _sound_output->Bind (wxEVT_CHOICE,   bind(&SoundPage::sound_output_changed, this));
-       _map->Changed.connect (bind(&SoundPage::map_changed, this, _1));
-       _reset_to_default->Bind (wxEVT_BUTTON,   bind(&SoundPage::reset_to_default, this));
 }
 
+
 void
 SoundPage::reset_to_default ()
 {
@@ -928,6 +939,15 @@ SoundPage::sound_changed ()
        Config::instance()->set_sound (_sound->GetValue ());
 }
 
+
+void
+SoundPage::sound_api_changed()
+{
+       Config::instance()->set_sound_api(id_to_audio_api(get_sound_api()).id());
+       Config::instance()->unset_sound_output();
+}
+
+
 void
 SoundPage::sound_output_changed ()
 {
@@ -967,6 +987,8 @@ SoundPage::config_changed ()
                }
        }
 
+       update_sound_outputs();
+
        auto const current_so = get_sound_output ();
        optional<string> configured_so;
 
index 65f05a5a80ad516c274e43e7d6c353cd3acd31e9..1f70a058af48d81521fdcab083ee56b4ab21d488 100644 (file)
@@ -212,10 +212,12 @@ private:
        boost::optional<std::string> get_sound_api() const;
        boost::optional<std::string> get_sound_output() const;
        void sound_changed ();
+       void sound_api_changed();
        void sound_output_changed ();
        void setup_sensitivity ();
        void map_changed (AudioMapping m);
        void reset_to_default ();
+       void update_sound_outputs();
 
        CheckBox* _sound;
        Choice* _sound_api;
index bc6e98623c50dedbc258bc0d2776d08256ae50e6..938b356164cbdc4876dc304b3d72866685c48256 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 
+#include "audio_api.h"
 #include "closed_captions_dialog.h"
 #include "film_viewer.h"
 #include "gl_video_view.h"
@@ -86,7 +87,7 @@ rtaudio_callback (void* out, void *, unsigned int frames, double, RtAudioStreamS
 
 
 FilmViewer::FilmViewer (wxWindow* p)
-       : _audio (DCPOMATIC_RTAUDIO_API)
+       : _audio(new RtAudio(id_to_audio_api(Config::instance()->sound_api()).rtaudio_id()))
        , _closed_captions_dialog (new ClosedCaptionsDialog(p, this))
 {
 #if wxCHECK_VERSION(3, 1, 0)
@@ -601,7 +602,7 @@ FilmViewer::config_changed (Config::Property p)
                return;
        }
 
-       if (p != Config::SOUND && p != Config::SOUND_OUTPUT) {
+       if (p != Config::SOUND && p != Config::SOUND_API && p != Config::SOUND_OUTPUT) {
                return;
        }
 
@@ -609,12 +610,41 @@ FilmViewer::config_changed (Config::Property p)
                _audio->closeStream();
        }
 
-       if (Config::instance()->sound() && _audio.getDeviceCount() > 0) {
+       auto cleanup = [this]() {
+               _audio_channels = 0;
+               destroy_and_maybe_create_butler();
+       };
+
+       auto config = Config::instance();
+
+       if (!config->sound()) {
+               cleanup();
+               return;
+       }
+
+       auto configured_api = id_to_audio_api(config->sound_api()).rtaudio_id();
+
+       if (configured_api != _audio->getCurrentApi()) {
+               try {
+                       delete _audio;
+                       _audio = nullptr;
+                       _audio = new RtAudio(configured_api);
+               } catch (RtAudioError& e) {
+                       cleanup();
+                       error_dialog (
+                               _video_view->get(),
+                               _("There was a problem starting audio playback.  Please try another audio output device in Preferences."), std_to_wx(e.what())
+                               );
+                       return;
+               }
+       }
+
+       if (_audio->getDeviceCount() > 0) {
                unsigned int st = 0;
-               if (Config::instance()->sound_output()) {
+               if (config->sound_output()) {
                        while (st < _audio->getDeviceCount()) {
                                try {
-                                       if (_audio.getDeviceInfo(st).name == Config::instance()->sound_output().get()) {
+                                       if (_audio->getDeviceInfo(st).name == config->sound_output().get()) {
                                                break;
                                        }
                                } catch (RtAudioError&) {
@@ -644,10 +674,8 @@ FilmViewer::config_changed (Config::Property p)
                                );
                }
                destroy_and_maybe_create_butler();
-
        } else {
-               _audio_channels = 0;
-               destroy_and_maybe_create_butler();
+               cleanup();
        }
 }