Try to fix crashes when things go wrong with getDeviceInfo. v2.15.99
authorCarl Hetherington <cth@carlh.net>
Sat, 29 Aug 2020 18:33:45 +0000 (20:33 +0200)
committerCarl Hetherington <cth@carlh.net>
Sat, 29 Aug 2020 18:33:45 +0000 (20:33 +0200)
src/wx/config_dialog.cc
src/wx/film_viewer.cc

index 0a546dc..352c8ae 100644 (file)
@@ -878,9 +878,17 @@ SoundPage::setup ()
 
        RtAudio audio (DCPOMATIC_RTAUDIO_API);
        for (unsigned int i = 0; i < audio.getDeviceCount(); ++i) {
-               RtAudio::DeviceInfo dev = audio.getDeviceInfo (i);
-               if (dev.probed && dev.outputChannels > 0) {
-                       _sound_output->Append (std_to_wx (dev.name));
+               try {
+                       RtAudio::DeviceInfo dev = audio.getDeviceInfo (i);
+                       if (dev.probed && dev.outputChannels > 0) {
+                               _sound_output->Append (std_to_wx (dev.name));
+                       }
+#ifdef DCPOMATIC_USE_RTERROR
+               } catch (RtError&) {
+#else
+               } catch (RtAudioError&) {
+#endif
+                       /* Something went wrong so let's just ignore that device */
                }
        }
 
@@ -913,7 +921,13 @@ SoundPage::sound_output_changed ()
 {
        RtAudio audio (DCPOMATIC_RTAUDIO_API);
        optional<string> const so = get_sound_output();
-       if (!so || *so == audio.getDeviceInfo(audio.getDefaultOutputDevice()).name) {
+       string default_device;
+       try {
+               default_device = audio.getDeviceInfo(audio.getDefaultOutputDevice()).name;
+       } catch (RtAudioError&) {
+               /* Never mind */
+       }
+       if (!so || *so == default_device) {
                Config::instance()->unset_sound_output ();
        } else {
                Config::instance()->set_sound_output (*so);
index d3a6c12..5f60985 100644 (file)
@@ -527,8 +527,12 @@ FilmViewer::config_changed (Config::Property p)
                unsigned int st = 0;
                if (Config::instance()->sound_output()) {
                        while (st < _audio.getDeviceCount()) {
-                               if (_audio.getDeviceInfo(st).name == Config::instance()->sound_output().get()) {
-                                       break;
+                               try {
+                                       if (_audio.getDeviceInfo(st).name == Config::instance()->sound_output().get()) {
+                                               break;
+                                       }
+                               } catch (RtAudioError&) {
+                                       /* Something went wrong with that device so we don't want to use it anyway */
                                }
                                ++st;
                        }
@@ -539,19 +543,19 @@ FilmViewer::config_changed (Config::Property p)
                        st = _audio.getDefaultOutputDevice();
                }
 
-               _audio_channels = _audio.getDeviceInfo(st).outputChannels;
-
-               RtAudio::StreamParameters sp;
-               sp.deviceId = st;
-               sp.nChannels = _audio_channels;
-               sp.firstChannel = 0;
                try {
+                       _audio_channels = _audio.getDeviceInfo(st).outputChannels;
+                       RtAudio::StreamParameters sp;
+                       sp.deviceId = st;
+                       sp.nChannels = _audio_channels;
+                       sp.firstChannel = 0;
                        _audio.openStream (&sp, 0, RTAUDIO_FLOAT32, 48000, &_audio_block_size, &rtaudio_callback, this);
 #ifdef DCPOMATIC_USE_RTERROR
                } catch (RtError& e) {
 #else
                } catch (RtAudioError& e) {
 #endif
+                       _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(e.what())