OSDN Git Service

[OSD][SOUND][Qt] QT_MULTIMEDIA: Reduce jitter and delay.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 18 Oct 2022 13:20:28 +0000 (22:20 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 18 Oct 2022 13:20:28 +0000 (22:20 +0900)
source/src/qt/osd_sound.cpp
source/src/qt/sound-drivers/common/osd_sound_mod_template.cpp
source/src/qt/sound-drivers/qt_multimedia/osd_sound_mod_qtmultimedia.cpp

index c89053f..12ccace 100644 (file)
@@ -295,7 +295,7 @@ void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int*
        sound_buf_ptr = NULL;
        sound_initialized = false;
        // initialize direct sound
-
+       
        snd_total_volume = 127;
    
        snddata.sound_buf_ptr = (uint8_t**)(&sound_buf_ptr);
@@ -445,10 +445,11 @@ void OSD_BASE::update_sound(int* extra_frames)
        *extra_frames = 0;
        
        now_mute = false;
-       if(sound_ok) {
+       if(sound_initialized) {
                // Get sound driver 
                std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
                if(sound_drv.get() == nullptr) {
+                       // ToDo: Fix delay.
                        return;
                }
                
@@ -456,31 +457,32 @@ void OSD_BASE::update_sound(int* extra_frames)
                // source (= by VM) rendering data.
                int sound_samples = sound_drv->get_sample_count();
                // Check driver elapsed by real time.
-               if(sound_started) {
+               if(sound_drv->is_driver_started()) {
                        if(!(sound_drv->check_elapsed_to_render())) {
-#if 0
-                       
-                               int now_mixed_ptr = 0;
-                               if(vm == nullptr) {
-                                       return;
-                               }
-                               now_mixed_ptr = vm->get_sound_buffer_ptr();
-                               if(now_mixed_ptr < ((sound_samples * 100) / 100)) {
-                                       // Render even emulate 100% of latency.
-                                       return;
-                               }
-#else
                                return;
-#endif
                        }
-               } else {
+               } else if(!(sound_ok) /*&& (sound_drv->config_ok())*/) {
                        sound_drv->start();
-                       sound_started = true;
                        if(p_config != nullptr) {
                                sound_drv->set_volume((int)(p_config->general_sound_level));
                        }
-                       sound_drv->update_render_point_usec();
+                       //sound_drv->update_render_point_usec();
+                       sound_ok = true;
+                       return;
+               } else {
+#if 0                  
+                       int now_mixed_ptr = 0;
+                       if(vm == nullptr) {
+                               return;
+                       }
+                       now_mixed_ptr = vm->get_sound_buffer_ptr();
+                       if(now_mixed_ptr < ((sound_samples * 100) / 100)) {
+                               // Render even emulate 100% of latency.
+                               return;
+                       }
+#else
                        return;
+#endif
                }
                int16_t* sound_buffer = (int16_t*)create_sound(extra_frames);
                if(sound_buffer == nullptr) {
@@ -513,17 +515,17 @@ void OSD_BASE::update_sound(int* extra_frames)
                        }
                }
                // ToDo: Convert sound format.
-               if(!(sound_drv->check_enough_to_render())) {
+               if(sound_drv.get() != nullptr) {
+                       if(!(sound_drv->check_enough_to_render())) {
                        // Buffer underflow.
-                       sound_drv->discard();
+                       //sound_drv->discard();
+                       //sound_drv->update_render_point_usec();
+                               return;
+                       }
+                       int64_t _result = 0;
+                       _result = sound_drv->update_sound((void*)sound_buffer, sound_samples);
                        sound_drv->update_render_point_usec();
-                       return;
                }
-               int64_t _result = 0;            
-               _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);
-               sound_drv->update_render_point_usec();
        }
 }
 
@@ -552,7 +554,8 @@ void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int*
        if(sound_drv.get() != nullptr) {
                sound_drv->initialize_sound(rate, samples, presented_rate, presented_samples);
                //sound_drv->update_render_point_usec();
-               sound_ok = true;
+               sound_initialized = true;
+               sound_ok = false;
        }
 }
 void OSD_BASE::release_sound()
@@ -623,6 +626,8 @@ void OSD_BASE::stop_sound()
                        sound_drv->stop_sound();
                }
        }
+       sound_initialized = false;
+       sound_ok = false;
 }
 
 int OSD_BASE::get_sound_rate()
index ff848d2..0469145 100644 (file)
@@ -368,10 +368,12 @@ void M_BASE::release_sound()
 
 bool M_BASE::check_elapsed_to_render()
 {
-       const int64_t sound_us_now = driver_elapsed_usec();
        //const int64_t sound_us_now = driver_processed_usec();
        if(m_rate <= 0) return false;
-       
+       if(!(is_driver_started())) {
+               return false;
+       }
+       const int64_t sound_us_now = driver_elapsed_usec();
        const int64_t  _period_usec = m_latency_ms * 1000;
        int64_t _diff = sound_us_now - m_before_rendered;
        if((_diff < 0) && ((INT64_MAX - m_before_rendered) <= _period_usec))  {
@@ -384,9 +386,9 @@ bool M_BASE::check_elapsed_to_render()
        if(_diff < (_period_usec - 2000)) {
                return false;
        }
-       //if(_diff < _period_usec) {
-       //      return false;
-       //}
+//     if(_diff < _period_usec) {
+//             return false;
+//     }
        return true;
 }
 
@@ -425,14 +427,17 @@ 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()));
        if(q.get() == nullptr) return -1;
-       
+       if(!(is_driver_started()) ||  !(q->isOpen())) {
+               return -1;
+       }
+       int64_t _result = -1;
        if(samples > 0) {
                qint64 _size = (qint64)(samples * m_channels) * (qint64)m_wordsize;
-               return (int64_t)q->write((const char *)datasrc, _size);
+               _result = (int64_t)q->write((const char *)datasrc, _size);
        } else if(samples < 0) {
-               return (int64_t)q->write((const char *)datasrc, m_chunk_bytes);
+               _result = (int64_t)q->write((const char *)datasrc, m_chunk_bytes);
        }
-       return -1;
+       return _result;
 }
 
 
index 93ce90b..446b88d 100644 (file)
@@ -119,12 +119,16 @@ void M_QT_MULTIMEDIA::set_audio_format(QAudioDevice dest_device, QAudioFormat& d
        } else if(dest_device.maximumChannelCount() < _channels) {
                _channels = dest_device.maximumChannelCount();
        }
-       if(dest_device.minimumSampleRate() > rate) {
-               rate = dest_device.minimumSampleRate();
-       } else if(dest_device.maximumSampleRate() < rate) {
-               rate = dest_device.maximumSampleRate();
-       }
-       if((rate <= 0)) {
+       int _rate = rate;
+       if(dest_device.minimumSampleRate() > _rate) {
+               _rate = dest_device.minimumSampleRate();
+       } else if(dest_device.maximumSampleRate() < _rate) {
+               _rate = dest_device.maximumSampleRate();
+       }
+       //if(_rate > 0) {
+       rate = _rate; // Workaround 20221018 K.O
+       //}
+       if(_rate <= 0) {
                return;
        }
        if(_channels > 0) {
@@ -343,11 +347,15 @@ QAudioDeviceInfo M_QT_MULTIMEDIA::get_device_by_name(QString driver_name)
        
 void M_QT_MULTIMEDIA::do_set_device_by_name(QString driver_name)
 {
+       if(m_device_name == driver_name.toLocal8Bit().toStdString()) {
+               return;
+       }
 #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);
 }
 
@@ -434,7 +442,12 @@ void M_QT_MULTIMEDIA::setup_device(QAudioDeviceInfo dest_device, int& rate,int&
 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
                m_audioOutputSink.reset(new QAudioOutput(dest_device, desired, this));
 #endif
+               do_discard_sound();
+               m_prev_started = false;
+               m_before_rendered = 0;
+               
                if(m_audioOutputSink.get() != nullptr) {
+                       m_audioOutputSink->setBufferSize(m_chunk_bytes);
                        connect(m_audioOutputSink.get(), SIGNAL(stateChanged(QAudio::State)), this, SLOT(driver_state_changed(QAudio::State)));
                        channels = m_audioOutputSink->format().channelCount();
                        rate = m_audioOutputSink->format().sampleRate();
@@ -454,9 +467,7 @@ void M_QT_MULTIMEDIA::setup_device(QAudioDeviceInfo dest_device, int& rate,int&
                        }
 
                        recalc_samples(rate, latency_ms, true, true);
-
                        m_config_ok = (m_fileio.get() != nullptr);
-                               
                        if(m_config_ok.load()) {
                                real_reconfig_sound(rate, channels, latency_ms);
                        }
@@ -522,11 +533,11 @@ 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) || (m_latency_ms != latency_ms)) {
+//     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);
                __debug_log_func(_T("Returned Driver=\"%s\" rate=%dHz channles=%d latency=%dmSec"), m_device_name.c_str(), rate, channels, latency_ms);
                //emit sig_set_sound_device(m_device_name);
-       }
+//     }
        if((rate <= 0) || (latency_ms <= 0)) {
                rate = 48000;
                latency_ms = 100;
@@ -544,11 +555,9 @@ bool M_QT_MULTIMEDIA::real_reconfig_sound(int& rate,int& channels,int& latency_m
 void M_QT_MULTIMEDIA::release_sound()
 {
 //     std::lock_guard<std::recursive_timed_mutex> locker(m_locker);
-       
-       m_audioOutputSink->disconnect();
-
        if(m_audioOutputSink.get() != nullptr) {
                m_audioOutputSink->stop();
+               m_audioOutputSink->disconnect();
        }
        m_audioOutputSink.reset();
 
@@ -569,14 +578,24 @@ void M_QT_MULTIMEDIA::do_sound_start()
 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
        std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
 #endif
-       if(m_driver_fileio.get() != nullptr) {
-               m_driver_fileio->reset();
+       if(p.get() == nullptr) {
+               return;
        }
-       if(p.get() != nullptr) {
-               p->start(m_driver_fileio.get());
-               __debug_log_func("GO. fileio=%0llx", m_driver_fileio.get());
+       if((p->state() != QAudio::StoppedState) && (m_prev_started)) {
+//             update_render_point_usec();
+               return;
        }
+       if(m_driver_fileio.get() == nullptr) {
+               //m_driver_fileio->reset();
+               return;
+       }
+       m_driver_fileio->reset();
+       p->setBufferSize(m_chunk_bytes);
+       p->start(m_driver_fileio.get());
        update_render_point_usec();
+       __debug_log_func("GO. fileio=%0llx", m_driver_fileio.get());
+
+       //update_render_point_usec();
        m_prev_started = true;
 }
 
@@ -591,7 +610,7 @@ void M_QT_MULTIMEDIA::do_sound_stop()
                p->stop();
        }
        do_discard_sound();
-       update_render_point_usec();
+       m_before_rendered = 0;
        m_prev_started = false;
 }
 
@@ -641,6 +660,7 @@ int64_t M_QT_MULTIMEDIA::driver_elapsed_usec()
 #endif
        if(p.get() != nullptr) {
                return (int64_t)(p->elapsedUSecs());
+               //return (int64_t)(p->processedUSecs());
        }
        return 0;
 }