OSDN Git Service

[SOUND][Qt] (Maybe) Fix jitters at new driver.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 9 Jan 2023 19:38:14 +0000 (04:38 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 9 Jan 2023 19:38:14 +0000 (04:38 +0900)
source/src/qt/osd_base.cpp
source/src/qt/osd_base.h
source/src/qt/osd_sound.cpp
source/src/qt/sound-drivers/common/osd_sound_mod_template.cpp

index 90ad453..ff32b01 100644 (file)
@@ -69,7 +69,9 @@ OSD_BASE::OSD_BASE(std::shared_ptr<USING_FLAGS> p, std::shared_ptr<CSP_Logger> l
        glContext = NULL;
 
        m_sound_driver.reset();
-
+       m_sound_period = 0;
+       sound_initialized = false;
+       sound_ok = false;
 }
 
 OSD_BASE::~OSD_BASE()
index 3bdf478..bef12f9 100644 (file)
@@ -182,7 +182,7 @@ private:
        QAudioFormat m_audioInputFormat;
        
        #endif
-
+       uint8_t m_sound_period;
 protected:
        EmuThreadClass          *parent_thread;
        sdl_snddata_t           snddata;
index 12ccace..9a0bf27 100644 (file)
@@ -448,41 +448,54 @@ void OSD_BASE::update_sound(int* extra_frames)
        if(sound_initialized) {
                // Get sound driver 
                std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
-               if(sound_drv.get() == nullptr) {
+               __UNLIKELY_IF(sound_drv.get() == nullptr) {
                        // ToDo: Fix delay.
+                       sound_ok = false;
                        return;
                }
-               
-               // Check enough to render accumlated
-               // source (= by VM) rendering data.
-               int sound_samples = sound_drv->get_sample_count();
-               // Check driver elapsed by real time.
-               if(sound_drv->is_driver_started()) {
-                       if(!(sound_drv->check_elapsed_to_render())) {
-                               return;
-                       }
-               } else if(!(sound_ok) /*&& (sound_drv->config_ok())*/) {
-                       sound_drv->start();
-                       if(p_config != nullptr) {
-                               sound_drv->set_volume((int)(p_config->general_sound_level));
+               __UNLIKELY_IF(!(sound_drv->is_driver_started())) {
+                       // ToDo: Fix delay.
+                       __LIKELY_IF(!(sound_ok)) {
+                               sound_drv->start();
+                               __UNLIKELY_IF(p_config != nullptr) {
+                                       sound_drv->set_volume((int)(p_config->general_sound_level));
+                               }
                        }
-                       //sound_drv->update_render_point_usec();
                        sound_ok = true;
                        return;
-               } else {
-#if 0                  
-                       int now_mixed_ptr = 0;
-                       if(vm == nullptr) {
+               }
+
+               // Check enough to render accumlated
+               // source (= by VM) rendering data.
+               int64_t sound_samples = sound_drv->get_sample_count();
+               __UNLIKELY_IF(sound_samples <= 0) {
+                       return;
+               }
+               int _channels = sound_drv->get_channels();
+               size_t word_size = sound_drv->get_word_size();
+               int64_t _left = sound_drv->get_bytes_left();
+               // Pass 1: Check available to write.
+               __UNLIKELY_IF((_channels <= 0) || (word_size == 0)) {
+                       return;
+               }
+               if(_left < (sound_samples * (int64_t)(word_size * _channels))) {
+                       return;
+               }
+               // Pass 2: Check elapsed time.
+               int64_t latency_us    = sound_drv->get_latency_ms() * 1000;
+               int64_t elapsed_usec = sound_drv->driver_elapsed_usec() % (latency_us * 2);
+               //int64_t processed_usec = sound_drv->driver_processed_usec() % (latency_us * 2);
+               switch(m_sound_period) {
+               case 0:
+                       if(elapsed_usec > latency_us) {
                                return;
                        }
-                       now_mixed_ptr = vm->get_sound_buffer_ptr();
-                       if(now_mixed_ptr < ((sound_samples * 100) / 100)) {
-                               // Render even emulate 100% of latency.
+                       break;
+               case 1:
+                       if(elapsed_usec < latency_us) {
                                return;
                        }
-#else
-                       return;
-#endif
+                       break;
                }
                int16_t* sound_buffer = (int16_t*)create_sound(extra_frames);
                if(sound_buffer == nullptr) {
@@ -516,15 +529,12 @@ void OSD_BASE::update_sound(int* extra_frames)
                }
                // ToDo: Convert sound format.
                if(sound_drv.get() != nullptr) {
-                       if(!(sound_drv->check_enough_to_render())) {
-                       // Buffer underflow.
-                       //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();
+                       if(_result > 0) {
+                               m_sound_period = (m_sound_period + 1) % 2;
+                               //printf("%d %ld\n", m_sound_period, _result);
+                       }
                }
        }
 }
@@ -554,6 +564,7 @@ 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();
+               m_sound_period = 0;
                sound_initialized = true;
                sound_ok = false;
        }
@@ -571,6 +582,8 @@ void OSD_BASE::release_sound()
                //sound_drv->update_render_point_usec();
                sound_drv->release_sound();
        }
+       m_sound_period = 0;
+       
 }
 
 void OSD_BASE::do_update_master_volume(int level)
@@ -624,9 +637,10 @@ void OSD_BASE::stop_sound()
        if(sound_drv.get() != nullptr) {
                if(sound_ok && sound_drv->is_driver_started()) {
                        sound_drv->stop_sound();
+                       m_sound_period = 0;
                }
        }
-       sound_initialized = false;
+       //sound_initialized = false;
        sound_ok = false;
 }
 
index 0469145..e722bc6 100644 (file)
@@ -109,7 +109,7 @@ bool M_BASE::recalc_samples(int rate, int latency_ms, bool need_update, bool nee
        int64_t _samples =
                ((int64_t)rate * latency_ms) / 1000;
        size_t _chunk_bytes = (size_t)(_samples * m_wordsize);
-       int64_t _buffer_bytes = _chunk_bytes * 4;
+       int64_t _buffer_bytes = _chunk_bytes * 2;
        
        bool _need_restart = false;
        if(need_resize_fileio) {
@@ -431,11 +431,18 @@ int64_t M_BASE::update_sound(void* datasrc, int samples)
                return -1;
        }
        int64_t _result = -1;
+       qint64 _size = m_chunk_bytes;
        if(samples > 0) {
-               qint64 _size = (qint64)(samples * m_channels) * (qint64)m_wordsize;
+               _size = (qint64)(samples * m_channels) * (qint64)m_wordsize;
+       } else if(samples == 0) {
+               return _result;
+       }
+       if(_size > 0) { 
                _result = (int64_t)q->write((const char *)datasrc, _size);
-       } else if(samples < 0) {
-               _result = (int64_t)q->write((const char *)datasrc, m_chunk_bytes);
+       }
+       if(_result > 0) {
+               _result = _result / (qint64)(m_channels * m_wordsize);
+               
        }
        return _result;
 }
@@ -696,7 +703,6 @@ int64_t M_BASE::get_bytes_left()
        }
        return 0;
 }
-
        /* SOUND_MODULE::OUTPUT */
        }
        /* SOUND_MODULE */