OSDN Git Service

[OSD][SOUND][QT_MULTIMEDIA] New Driver: Selectable output devices.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 27 Sep 2022 16:01:53 +0000 (01:01 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 27 Sep 2022 16:01:53 +0000 (01:01 +0900)
12 files changed:
source/src/qt/CMakeLists.txt
source/src/qt/common/qt_utils.cpp
source/src/qt/gui/CMakeLists.txt
source/src/qt/gui/mainwidget_base.h
source/src/qt/gui/menu_main.cpp
source/src/qt/gui/menu_sound.cpp
source/src/qt/osd_base.cpp
source/src/qt/osd_base.h
source/src/qt/osd_sound.cpp
source/src/qt/osd_sound_mod_qtmultimedia.cpp
source/src/qt/osd_sound_mod_qtmultimedia.h
source/src/qt/osd_sound_mod_template.cpp

index 029d01c..2701839 100644 (file)
@@ -1,5 +1,5 @@
 message("* qt/osd")
-SET(THIS_LIB_VERSION 8.6.0)
+SET(THIS_LIB_VERSION 8.6.1)
 
 set(s_qt_osd_headers
        osd_base.h
index 3ff12f8..3ac4e3c 100644 (file)
@@ -1341,6 +1341,10 @@ int MainLoop(int argc, char *argv[])
        rMainWindow->connect(rMainWindow, SIGNAL(sig_osd_sound_output_device(QString)), (OSD*)(emu->get_osd()), SLOT(do_set_host_sound_output_device(QString)));
        rMainWindow->do_update_sound_output_list();
 
+       QObject::connect((OSD*)(emu->get_osd()), SIGNAL(sig_update_sound_output_list()), rMainWindow, SLOT(do_update_sound_output_list()));
+       QObject::connect((OSD*)(emu->get_osd()), SIGNAL(sig_clear_sound_output_list()), rMainWindow, SLOT(do_clear_sound_output_list()));
+       QObject::connect((OSD*)(emu->get_osd()), SIGNAL(sig_append_sound_output_list(QString)), rMainWindow, SLOT(do_append_sound_output_list(QString)));
+                                        
        QObject::connect(rMainWindow, SIGNAL(sig_update_master_volume(int)), (OSD*)(emu->get_osd()), SLOT(do_update_master_volume(int)));
        
        QObject::connect(GuiMain, SIGNAL(lastWindowClosed()),
index e1459f9..a7c487c 100644 (file)
@@ -1,6 +1,6 @@
 message("* qt/gui")
 
-set(THIS_LIB_VERSION 7.3.0)
+set(THIS_LIB_VERSION 7.3.1)
 
 set(s_qt_gui_headers
          qt_dialogs.h
index 807c98c..cabba0c 100644 (file)
@@ -924,8 +924,11 @@ public slots:
        void do_set_single_dipswitch(bool f);
        void do_set_single_dipswitch_negative(bool f);
        void do_set_multi_dipswitch();
-       void do_update_sound_output_list();
        
+       void do_clear_sound_output_list();
+       void do_update_sound_output_list();
+       void do_append_sound_output_list(QString _name);
+
        void do_start_emu_thread();
        void do_start_draw_thread();
 signals:
index 5f1c1a7..7830a08 100644 (file)
@@ -90,14 +90,8 @@ Ui_MainWindowBase::Ui_MainWindowBase(std::shared_ptr<USING_FLAGS> p, std::shared
 Ui_MainWindowBase::~Ui_MainWindowBase()
 {
        // May need delete items via QVector.
-       if(!(action_HostSoundDevice.empty())) {
-               for(auto ix = action_HostSoundDevice.begin(); ix != action_HostSoundDevice.end(); ++ix) {
-                       if((*ix) != nullptr) {
-                               (*ix)->disconnect();
-                               delete *ix;
-                       }
-               }
-       }
+       do_clear_sound_output_list();
+       
        graphicsView->releaseKeyboard();
        if(ledUpdateTimer != NULL) delete ledUpdateTimer;
        if(driveData != NULL) delete driveData;
index 23cf324..d3c4d52 100644 (file)
 // WIP: Will move to another file
 const double s_late_table[5] = {0.05, 0.1, 0.2, 0.3, 0.4};
 
-void Ui_MainWindowBase::do_update_sound_output_list(void)
+void Ui_MainWindowBase::do_clear_sound_output_list(void)
 {
-       if((p_config == nullptr) || (using_flags == nullptr)) return;
-       int _match = -1;
-       QString matched_devname = QString::fromUtf8("Default");
        if(!(action_HostSoundDevice.empty())) {
                for(auto ix = action_HostSoundDevice.begin(); ix != action_HostSoundDevice.end(); ++ix) {
                        if((*ix) != nullptr) {
@@ -39,42 +36,48 @@ void Ui_MainWindowBase::do_update_sound_output_list(void)
                }
        }
        action_HostSoundDevice.clear();
+}
+
+void Ui_MainWindowBase::do_append_sound_output_list(QString _name)
+{
+       int nums = action_HostSoundDevice.size();
+       if(nums < 0) nums = 0;
+       QString tmps = QString::fromUtf8("action_HostSoundDevice") + QString::number(nums);
+       
        action_HostSoundDevice.append(new Action_Control(this, using_flags));
-       action_HostSoundDevice[0]->setChecked(true);
-       action_HostSoundDevice[0]->setObjectName(QString::fromUtf8("action_HostSoundDevice0"));
-       action_HostSoundDevice[0]->setCheckable(true);
-       actionGroup_Sound_HostDevices->addAction(action_HostSoundDevice[0]);
-       menuSound_HostDevices->addAction(action_HostSoundDevice[0]);
-       connect(action_HostSoundDevice[0], SIGNAL(triggered()),
+       action_HostSoundDevice[nums]->setChecked(false);
+       action_HostSoundDevice[nums]->setObjectName(tmps);
+       action_HostSoundDevice[nums]->setCheckable(true);
+       actionGroup_Sound_HostDevices->addAction(action_HostSoundDevice[nums]);
+       menuSound_HostDevices->addAction(action_HostSoundDevice[nums]);
+
+       do_set_host_sound_name(nums, _name);
+       connect(action_HostSoundDevice[nums], SIGNAL(triggered()),
                        this, SLOT(do_set_host_sound_output_device()));
-       do_set_host_sound_name(0, QString::fromUtf8("Default"));
 
+}
+
+void Ui_MainWindowBase::do_update_sound_output_list(void)
+{
+       if((p_config == nullptr) || (using_flags == nullptr)) return;
+       int _match = -1;
+       QString matched_devname = QString::fromUtf8("Default");
+       
+       do_clear_sound_output_list();
+
+       do_append_sound_output_list(QString::fromUtf8("Default"));
+       
        QString _setname = QString::fromLocal8Bit(p_config->sound_device_name);
-       _setname.truncate(1023);
+       int i = 0;
        if(using_flags->get_osd() != nullptr) {
-               int devs_count = using_flags->get_osd()->get_sound_device_num();
-               for(int i = 0; i < devs_count; i++) {
-                       const _TCHAR* sp = using_flags->get_sound_device_name(i);
-                       QString sname;
-                       sname.clear();
-                       if(sp != NULL) {
-                               sname = QString::fromUtf8(sp);
-                               sname.truncate(1023);
-                       }
-                       if(sname == _setname) {
+               QStringList _l =  using_flags->get_osd()->get_sound_device_list();
+               for(auto p = _l.begin(); p != _l.end(); ++p) {
+                       do_append_sound_output_list((*p));
+                       if((*p) == _setname) {
                                _match = i + 1;
-                               matched_devname = sname;
+                               matched_devname = (*p);
                        }
-                       action_HostSoundDevice.append(new Action_Control(this, using_flags));
-                       QString tmps;
-                       tmps.setNum(i + 1);
-                       action_HostSoundDevice[i + 1]->setObjectName(QString::fromUtf8("action_HostSoundDevice") + tmps);
-                       action_HostSoundDevice[i + 1]->setCheckable(true);
-                       actionGroup_Sound_HostDevices->addAction(action_HostSoundDevice[i + 1]);
-                       menuSound_HostDevices->addAction(action_HostSoundDevice[i + 1]);
-                       connect(action_HostSoundDevice[i + 1], SIGNAL(triggered()),
-                                       this, SLOT(do_set_host_sound_output_device()));
-                       do_set_host_sound_name(i + 1, sname);
+                       i++;
                }
                if(_match > 0) {
                        action_HostSoundDevice[_match]->setChecked(true);
@@ -90,11 +93,13 @@ void Ui_MainWindowBase::do_set_host_sound_output_device(void)
        QAction *cp = qobject_cast<QAction*>(QObject::sender());
        if(cp == nullptr) return;
        QString _name = cp->data().value<QString>();
+       
        if(p_config != nullptr) {
-               QString _old = QString::fromLocal8Bit(p_config->sound_device_name, 1023);
-               _name.truncate(1023);
-               if(/*(_old != _name) &&*/ !(_name.isEmpty())) {
-                       my_tcscpy_s(p_config->sound_device_name, 1023, _name.toLocal8Bit().constData());
+               size_t ssize = sizeof(p_config->sound_device_name) / sizeof(_TCHAR);
+               _name.truncate(ssize - 1);
+               if(!(_name.isEmpty())) {
+                       memset(p_config->sound_device_name, 0x00, sizeof(p_config->sound_device_name));
+                       my_tcscpy_s(p_config->sound_device_name, ssize - 1, _name.toLocal8Bit().constData());
                        emit sig_osd_sound_output_device(_name);
                }
        }
@@ -108,14 +113,14 @@ void Ui_MainWindowBase::do_set_host_sound_name(int num, QString s)
        
        if(s.isEmpty()) {
                action_HostSoundDevice[num]->setVisible(false);
-               QVariant v = QVariant(QString::fromUtf8(""));
-               action_HostSoundDevice[num]->setData(v);
        } else {
                action_HostSoundDevice[num]->setVisible(true);
-               action_HostSoundDevice[num]->setText(s);
-               QVariant v = QVariant(s);
-               action_HostSoundDevice[num]->setData(v);
        }
+       action_HostSoundDevice[num]->setText(s);
+       
+       QVariant v = QVariant(s);
+       action_HostSoundDevice[num]->setData(v);
+       
 }
 
 void Ui_MainWindowBase::do_set_sound_strict_rendering(bool f)
index e5a5320..5a2d823 100644 (file)
@@ -87,7 +87,7 @@ OSD_BASE::OSD_BASE(std::shared_ptr<USING_FLAGS> p, std::shared_ptr<CSP_Logger> l
        is_glcontext_shared = false;
        glContext = NULL;
 
-       #if 1  /* Note: Below are new sound driver. */
+       #if 0  /* Note: Below are new sound driver. */
        m_sound_driver.reset(
                new SOUND_OUTPUT_MODULE::M_QT_MULTIMEDIA(this,
                                                                                                 nullptr,
@@ -96,7 +96,8 @@ OSD_BASE::OSD_BASE(std::shared_ptr<USING_FLAGS> p, std::shared_ptr<CSP_Logger> l
                                                                                                 2,
                                                                                                 nullptr,
                                                                                                 0));
-       get_sound_device_list();
+       init_sound_device_list();
+       emit sig_update_sound_output_list();
        #else
        m_sound_driver.reset();
        #endif  /* END Note: */
index d2c879e..7f568f7 100644 (file)
@@ -326,7 +326,7 @@ protected:
        static void audio_capture_callback(void *udata, Uint8 *stream, int len);
        static void audio_callback(void *udata, Uint8 *stream, int len);
        void convert_sound_format(uint8_t* dst1, uint8_t* dst2, int16_t* src1, int16_t* src2, int samples1, int samples2);
-       virtual void get_sound_device_list();
+       virtual void init_sound_device_list();
 
        int sound_rate, sound_samples;
        bool sound_ok, sound_started, now_mute;
@@ -564,6 +564,10 @@ public:
 
        const _TCHAR *get_vm_device_name();
        const _TCHAR *get_sound_device_name(int num);
+       QStringList  get_sound_device_list()
+       {
+               return sound_device_list;
+       }
        
        int get_sound_device_num();
        
@@ -777,6 +781,10 @@ signals:
        int sig_set_sound_volume(double);
        int sig_set_sound_volume(int);
 
+       int sig_update_sound_output_list();
+       int sig_clear_sound_output_list();
+       int sig_append_sound_output_list(QString);
+
        int sig_update_device_node_name(int id, const _TCHAR *name);
        int sig_enable_mouse(void);
        int sig_disable_mouse(void);
index b06b48b..453d70d 100644 (file)
@@ -222,7 +222,7 @@ const _TCHAR *OSD_BASE::get_sound_device_name(int num)
        return (const _TCHAR*)(_n.constData());
 }
 
-void OSD_BASE::get_sound_device_list()
+void OSD_BASE::init_sound_device_list()
 {
        sound_device_list.clear();
 #if defined(USE_SDL2)
@@ -525,8 +525,8 @@ void OSD_BASE::update_sound(int* extra_frames)
                        return;
                }                  
                int64_t _result = sound_drv->update_sound((void*)sound_buffer, sound_samples);
-               debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
-                                 _T("OSD::%s() : sound result=%d"), __func__, _result);
+               //debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
+               //                _T("OSD::%s() : sound result=%d"), __func__, _result);
                sound_drv->update_render_point_usec();
        }
 }
@@ -535,15 +535,16 @@ void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int*
 {
        // If sound driver hasn't initialized, initialize.
        if(m_sound_driver.get() == nullptr) {
-                       m_sound_driver.reset(
-                               new SOUND_OUTPUT_MODULE::M_QT_MULTIMEDIA(this,
-                                                                                                                nullptr,
-                                                                                                                rate,
-                                                                                                                (samples * 1000) / rate,
-                                                                                                                2,
-                                                                                                                nullptr,
-                                                                                                                0));
-                       get_sound_device_list();
+               m_sound_driver.reset(
+                       new SOUND_OUTPUT_MODULE::M_QT_MULTIMEDIA(this,
+                                                                                                        nullptr,
+                                                                                                        rate,
+                                                                                                        (samples * 1000) / rate,
+                                                                                                        2,
+                                                                                                        nullptr,
+                                                                                                        0));
+               init_sound_device_list();
+               emit sig_update_sound_output_list();
        }
        std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
        
@@ -587,14 +588,19 @@ const _TCHAR *OSD_BASE::get_sound_device_name(int num)
        }
        return (const _TCHAR *)nullptr;
 }
-void OSD_BASE::get_sound_device_list()
+
+void OSD_BASE::init_sound_device_list()
 {
        std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
        sound_device_list.clear();
        if(sound_drv.get() != nullptr) {
                std::list<std::string> _l = sound_drv->get_sound_devices_list();
+               int _xi = 1;
                for(auto s = _l.begin(); s != _l.end(); ++s) {
                        sound_device_list.append(QString::fromStdString(*s));
+                       debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
+                                         "SOUND DEVICE#%03d %s", _xi, (*s).c_str());
+                       _xi++;
                }
        }
 }
index 8d88fb0..3b719aa 100644 (file)
@@ -48,6 +48,7 @@ M_QT_MULTIMEDIA::M_QT_MULTIMEDIA(
                        }
                }
                m_device_name = set_device_sound(_drv.toUtf8().constData(), m_rate, m_channels, m_latency_ms);
+               //it sig_set_sound_device(m_device_name);
                m_config_ok = true;
        }
 
@@ -185,18 +186,36 @@ bool M_QT_MULTIMEDIA::initialize_driver()
                m_samples = 4800;
        }
        m_fileio.reset(new SOUND_BUFFER_QT(m_samples * (qint64)m_channels * sizeof(int16_t) * 4));
-       m_driver_fileio = m_fileio;
+       update_driver_fileio();
+
        __debug_log_func(_T("status=%s"), (m_config_ok) ? _T("OK") : _T("NG"));
        return result;
 }
 
-const std::string M_QT_MULTIMEDIA::set_device_sound(const _TCHAR* driver_name, int& rate,int& channels,int& latency_ms)
+
+std::list<std::string> M_QT_MULTIMEDIA::get_sound_devices_list()
 {
-       if(m_audioOutputSink.get() == nullptr) {
-               return (const std::string)(std::string(""));
+       devices_name_list.clear();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+       QList<QAudioDevice> _list = QMediaDevices::audioOutputs();
+       for(auto i = _list.begin(); i != _list.end(); ++i) {
+               devices_name_list.push_back((*i).description().toStdString());
        }
-       
-       QString _name = QString::fromUtf8(driver_name);
+#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+       QList<QAudioDeviceInfo> _list = QAudioDeviceInfo::audioOutputs();
+       for(auto i = _list.begin(); i != _list.end(); ++i) {
+               devices_name_list.push_back((*i).deviceName().toStdString());
+       }
+#endif 
+       return devices_name_list;
+}
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+QAudioDevice M_QT_MULTIMEDIA::get_device_by_name(QString driver_name)
+#else
+QAudioDeviceInfo M_QT_MULTIMEDIA::get_device_by_name(QString driver_name)
+#endif
+{
 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
        QList<QAudioDevice> _list = QMediaDevices::audioOutputs();
        QAudioDevice dest_device = m_audioOutputDevice;
@@ -205,7 +224,7 @@ const std::string M_QT_MULTIMEDIA::set_device_sound(const _TCHAR* driver_name, i
        QAudioDeviceInfo dest_device = m_audioOutputDevice;
 #endif
        
-       if(_name == QString::fromUtf8("Default")) {
+       if((driver_name == QString::fromUtf8("Default")) || (driver_name.isEmpty())) {
 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
                dest_device = QMediaDevices::defaultAudioOutput();
 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -214,38 +233,80 @@ const std::string M_QT_MULTIMEDIA::set_device_sound(const _TCHAR* driver_name, i
        } else {
                for(auto i = _list.begin(); i != _list.end(); ++i) {
 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
-                       if((*i).description().compare(_name) == 0) {
+                       if((*i).description().compare(driver_name) == 0) {
                                dest_device = *i;
                                break;
                        }
 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-                       if((*i).deviceName().compare(_name) == 0) {
+                       if((*i).deviceName().compare(driver_name) == 0) {
                                dest_device = *i;
                                break;
                        }
 #endif
                }
        }
-       __debug_log_func(_T("desired_driver=%s using=%s"), driver_name, dest_device.description().toLocal8Bit().constData());
+       QString dest_device_name;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+       dest_device_name = dest_device.description();
+#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+       dest_device_name = dest_device.deviceName();
+#endif
        
-       bool req_reinit = !(m_config_ok.load());
-       if(dest_device != m_audioOutputDevice) {
-               req_reinit = true;
-       } else {
+       __debug_log_func(_T("desired_driver=%s using=%s"), driver_name.toLocal8Bit().constData(), dest_device_name.toLocal8Bit().constData());
+
+       return dest_device;
+}
+       
+void M_QT_MULTIMEDIA::do_set_device_by_name(QString driver_name)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+       QAudioDevice dest_device = get_device_by_name(driver_name);
+#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+       QAudioDeviceInfo dest_device = get_device_by_name(driver_name);
+#endif
+       setup_device(dest_device, m_rate, m_channels, m_latency_ms, true);
+}
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+void M_QT_MULTIMEDIA::setup_device(QAudioDevice dest_device, int& rate,int& channels,int& latency_ms, bool force_reinit)
+#else
+void M_QT_MULTIMEDIA::setup_device(QAudioDeviceInfo dest_device, int& rate,int& channels,int& latency_ms, bool force_reinit)
+#endif
+{
+       if(dest_device.isNull()) return; // None initialize if NULL.
+       
+       QAudioFormat desired = dest_device.preferredFormat();
+       set_audio_format(dest_device, desired, channels, rate);
+
+       if((m_audioOutputDevice.isNull()) || (m_audioOutputDevice != dest_device)) {
+               force_reinit = true;
+       }
+       bool force_req_reinit = false;
+       if(m_latency_ms != latency_ms) {
+               force_req_reinit = true;
+       }
+       
+       if(m_audioOutputSink.get() != nullptr) {
                if((m_audioOutputSink->format().channelCount() != channels) ||
                   (m_audioOutputSink->format().sampleRate() != rate)) {
-                       req_reinit = true;
+                       force_req_reinit = true;
                }
+       } else {
+               force_reinit = true;
        }
-       bool req_restart = false;
-       if(req_reinit) {
-               m_audioOutputSink->disconnect();
-               if(m_audioOutputSink->state() != QAudio::StoppedState) {
-                       m_audioOutputSink->stop();
-                       req_restart = true;
+
+       
+       if((force_reinit) || (force_req_reinit)) {
+               if(m_audioOutputSink.get() != nullptr) {
+                       m_audioOutputSink->disconnect();
+                       if(m_audioOutputSink->state() != QAudio::StoppedState) {
+                               m_audioOutputSink->stop();
+                               wait_driver_stopped(1000);
+                       }
                }
-               QAudioFormat desired = dest_device.preferredFormat();
-               set_audio_format(dest_device, desired, channels, rate);
+               
+               m_audioOutputDevice = dest_device;
+               m_audioOutputFormat = desired;
                
 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
                m_audioOutputSink.reset(new QAudioSink(dest_device, desired, this));
@@ -254,10 +315,8 @@ const std::string M_QT_MULTIMEDIA::set_device_sound(const _TCHAR* driver_name, i
 #endif
                if(m_audioOutputSink.get() != nullptr) {
                        connect(m_audioOutputSink.get(), SIGNAL(stateChanged(QAudio::State)), this, SLOT(driver_state_changed(QAudio::State)));
-                       m_audioOutputDevice = dest_device;
-                       m_audioOutputFormat = desired;
-                       m_channels = m_audioOutputSink->format().channelCount();
-                       m_rate = m_audioOutputSink->format().sampleRate();
+                       channels = m_audioOutputSink->format().channelCount();
+                       rate = m_audioOutputSink->format().sampleRate();
                        QString _tmpname;
                #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
                        _tmpname = m_audioOutputDevice.description();
@@ -265,40 +324,78 @@ const std::string M_QT_MULTIMEDIA::set_device_sound(const _TCHAR* driver_name, i
                        _tmpname = m_audioOutputDevice.deviceName();
                #endif
                        m_device_name = _tmpname.toLocal8Bit().toStdString();
+                       config_t* _ccp = get_config_ptr();
+                       if(_ccp != nullptr) {
+                               memset(_ccp->sound_device_name, 0x00, sizeof(_ccp->sound_device_name));
+                               my_tcscpy_s(_ccp->sound_device_name, (sizeof(_ccp->sound_device_name) / sizeof(_TCHAR)) - 1, _tmpname.toUtf8().constData());
+                       }
+                       
+                       //emit sig_set_sound_device(m_device_name);
+                       
                        m_config_ok = true;
-                       req_restart = true;
+                       
+                       int64_t _samples =
+                               ((int64_t)rate * latency_ms) / 1000;
+                       if(_samples < 100) _samples = 100;
+                       
+                       if(m_fileio.get() == nullptr) {
+                               m_fileio.reset(new SOUND_BUFFER_QT(_samples * (qint64)channels * sizeof(int16_t) * 4));
+                               m_config_ok = (m_fileio.get() != nullptr);
+                       } else {
+                               if(m_fileio->isOpen()) {
+                                       m_fileio->close();
+                               }
+                               m_config_ok =  m_fileio->resize(_samples * channels * sizeof(int16_t) * 4);
+                       }
+                       if(m_config_ok.load()) {
+                               m_samples = _samples;
+                               m_latency_ms = latency_ms;
+                               m_rate = rate;
+                               m_channels = channels;
+                               real_reconfig_sound(m_rate, m_channels, m_latency_ms);
+                       }
                } else {
                        m_device_name.clear();
                        m_config_ok = false;
-               }
-       } else if(m_audioOutputSink->state() != QAudio::StoppedState) {
-               if(m_latency_ms != latency_ms) {
-                       m_audioOutputSink->stop();
-                       req_restart = true;
-               }
-       }
-
-       if((req_reinit) || (m_latency_ms != latency_ms)) {
-               int64_t _samples =
-                       ((int64_t)m_rate * m_latency_ms) / 1000;
-               if(m_fileio.get() == nullptr) {
-                       m_fileio.reset(new SOUND_BUFFER_QT(m_samples * (qint64)m_channels * sizeof(int16_t) * 4));
-                       m_config_ok = (m_fileio.get() != nullptr);
-               } else {
-                       if(m_fileio->isOpen()) {
-                               m_fileio->close();
+                       
+                       int64_t _samples =
+                               ((int64_t)rate * latency_ms) / 1000;
+                       if(_samples < 100) _samples = 100;
+                       if(m_fileio.get() != nullptr) {
+                               if(m_fileio->isOpen()) {
+                                       m_fileio->close();
+                               }
+                               m_fileio.reset();
                        }
-                       m_config_ok =  m_fileio->resize(_samples * channels * sizeof(int16_t) * 4);
-               }
-               if(m_config_ok.load()) {
                        m_samples = _samples;
                        m_latency_ms = latency_ms;
+                       m_rate = rate;
+                       m_channels = channels;
                }
        }
-       if(/*(req_restart) && */(m_audioOutputSink.get() != nullptr)) {
+       if(m_audioOutputSink.get() != nullptr) {
                update_driver_fileio();
                emit sig_start_audio();
        }
+}
+
+const std::string M_QT_MULTIMEDIA::set_device_sound(const _TCHAR* driver_name, int& rate,int& channels,int& latency_ms)
+{
+       if(driver_name == nullptr) {
+               return (const std::string)(std::string(""));
+       }
+       if(strlen(driver_name) <= 0) {
+               return (const std::string)(std::string(""));
+       }
+       
+       QString _name = QString::fromUtf8(driver_name);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+       QAudioDevice dest_device = get_device_by_name(_name);
+#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+       QAudioDeviceInfo dest_device = get_device_by_name(_name);
+#endif
+       setup_device(dest_device, rate, channels, latency_ms, false);
+       
 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
        return m_audioOutputDevice.description().toStdString();
 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -315,22 +412,23 @@ bool M_QT_MULTIMEDIA::real_reconfig_sound(int& rate,int& channels,int& latency_m
        }
 
        int64_t _samples = (rate * latency_ms) / 1000;
-       if((rate != m_rate) || (_samples != m_samples)) {
+       if((rate != m_rate) || (_samples != m_samples) || (m_latency_ms != latency_ms)) {
                m_device_name = set_device_sound((const _TCHAR *)(m_device_name.c_str()), rate, channels, latency_ms);
+               //emit sig_set_sound_device(m_device_name);
        }
 //     if(m_config_ok.load()) {
-               std::shared_ptr<SOUND_BUFFER_QT> sp = m_fileio;
-               if(sp.get() != nullptr) {
-                       if(!(sp->isOpen())) {
+       std::shared_ptr<SOUND_BUFFER_QT> sp = m_fileio;
+       if(sp.get() != nullptr) {
+               if(!(sp->isOpen())) {
 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
-                               sp->open(QIODeviceBase::ReadWrite | QIODeviceBase::Truncate | QIODeviceBase::Unbuffered);
+                       sp->open(QIODeviceBase::ReadWrite | QIODeviceBase::Truncate | QIODeviceBase::Unbuffered);
 #else
-                               sp->open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Unbuffered);
+                       sp->open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Unbuffered);
 #endif
-                       }
-                       m_prev_started = m_mute = false;
-                       sp->reset();
                }
+               m_prev_started = m_mute = false;
+               sp->reset();
+       }
 //     }
        
        if((rate <= 0) || (latency_ms <= 0)) {
index a914bf2..45a9b62 100644 (file)
@@ -12,6 +12,7 @@
 #include "./osd_sound_mod_template.h"
 
 #include <string>
+#include <list>
 #include <QAudioFormat>
 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
 #include <QAudioDevice>
@@ -32,6 +33,8 @@ class DLL_PREFIX M_QT_MULTIMEDIA
 protected:
        QAudioFormat                                            m_audioOutputFormat;
        std::string                                                     m_device_name;
+       std::list<std::string>                          devices_name_list;
+
 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
        std::shared_ptr<QAudioSink>                     m_audioOutputSink;
        QAudioDevice m_audioOutputDevice;
@@ -43,6 +46,13 @@ protected:
        virtual void set_audio_format(QAudioDeviceInfo dest_device, QAudioFormat& desired, int& channels, int& rate);
 #endif
 
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+       QAudioDevice get_device_by_name(QString driver_name);
+       void setup_device(QAudioDevice dest_device, int& rate,int& channels,int& latency_ms, bool force_reinit = false);
+#else
+       QAudioDeviceInfo get_device_by_name(QString driver_name);
+       void setup_device(QAudioDeviceInfo dest_device, int& rate,int& channels,int& latency_ms, bool force_reinit = false);
+#endif
        
        virtual bool real_reconfig_sound(int& rate,int& channels,int& latency_ms) override;
        virtual void update_driver_fileio() override;
@@ -65,7 +75,8 @@ public:
        
        virtual int64_t driver_elapsed_usec() override;
        virtual int64_t driver_processed_usec() override;
-                                                                                 
+       virtual std::list<std::string> get_sound_devices_list() override;
+                                                                                                                                       
 public slots:
        virtual void release_sound() override;
 
@@ -80,6 +91,8 @@ public slots:
        virtual void do_sound_suspend();
        virtual void do_discard_sound();
        virtual void do_sound_volume(double level);
-       
+
+       virtual void do_set_device_by_name(QString driver_name) override;
+
 };
 }
index f170eb9..cd5e875 100644 (file)
@@ -341,7 +341,7 @@ bool M_BASE::check_enough_to_render()
 int64_t M_BASE::update_sound(void* datasrc, int samples)
 {
        std::shared_ptr<SOUND_BUFFER_QT>q = m_fileio;   
-       __debug_log_func(_T("SRC=%0llx  samples=%d fileio=%0llx"), (uintptr_t)datasrc, samples, (uintptr_t)(q.get()));
+       //__debug_log_func(_T("SRC=%0llx  samples=%d fileio=%0llx"), (uintptr_t)datasrc, samples, (uintptr_t)(q.get()));
        if(q.get() == nullptr) return -1;
        
        if(samples > 0) {