diff options
| author | 2026-03-12 12:40:59 +0100 | |
|---|---|---|
| committer | 2026-03-12 12:41:08 +0100 | |
| commit | 70d4b9bc5d488bf71e571c14eec46615319e2c2c (patch) | |
| tree | d3f326cb677a79bd04c0e1696953b9060a97a9a7 /src/osd | |
| parent | ba6db4a6c2f8d5f31598bb3d482daac0b6b9f7cc (diff) | |
sound abuffer: derive min_buffers from max_buffers, add over/underrun stats
Diffstat (limited to 'src/osd')
| -rw-r--r-- | src/osd/modules/sound/sound_module.cpp | 28 | ||||
| -rw-r--r-- | src/osd/modules/sound/sound_module.h | 5 |
2 files changed, 21 insertions, 12 deletions
diff --git a/src/osd/modules/sound/sound_module.cpp b/src/osd/modules/sound/sound_module.cpp index 801edb74df1..20220cf2c77 100644 --- a/src/osd/modules/sound/sound_module.cpp +++ b/src/osd/modules/sound/sound_module.cpp @@ -40,6 +40,8 @@ void sound_module::abuffer::clear() m_delta = 0; m_delta2 = 0; + m_underruns = 0; + m_overruns = 0; } void sound_module::abuffer::get(int16_t *data, uint32_t samples) noexcept @@ -50,6 +52,7 @@ void sound_module::abuffer::get(int16_t *data, uint32_t samples) noexcept while(pos != samples) { if(!m_used_buffers) { m_delta2 += samples - pos; + m_underruns++; while(pos != samples) { std::copy_n(m_last_sample.data(), m_channels, data); data += m_channels; @@ -77,7 +80,7 @@ void sound_module::abuffer::get(int16_t *data, uint32_t samples) noexcept pos += avail; data += avail * m_channels; } - //printf("# %d %d %d\n", m_used_buffers, m_delta, m_delta2); + //printf("%d -%d +%d # %d %d\n", m_used_buffers, m_underruns, m_overruns, m_delta, m_delta2); } void sound_module::abuffer::push(const int16_t *data, uint32_t samples) @@ -90,6 +93,13 @@ void sound_module::abuffer::push(const int16_t *data, uint32_t samples) std::copy_n(data, samples * m_channels, buf.m_data.data()); std::copy_n(data + ((samples - 1) * m_channels), m_channels, m_last_sample.data()); + // maximum number of buffers relative to samples + const uint32_t max_buffers = std::max(m_max_buffers * 48000 / samples / 50, 4U); + + // minimum number of buffers after overrun + // (lower limit of 2 prevents buffer underruns with push(this), get, get, push) + const uint32_t min_buffers = std::max(max_buffers / 4, 2U); + m_history[m_hindex] = m_used_buffers_prev - m_used_buffers; m_hindex = (m_hindex + 1) % m_history.size(); @@ -104,25 +114,21 @@ void sound_module::abuffer::push(const int16_t *data, uint32_t samples) }; if(m_overrun && std::accumulate(m_history.begin(), m_history.end(), 0) >= -2) { - if(m_used_buffers > 2) { - // Once it's stabilized after an overrun, reduce buffers to 2 - flush_buffers(2); + if(m_used_buffers > min_buffers) { + // Once it's stabilized after an overrun, reduce buffers to minimum latency + flush_buffers(min_buffers); std::fill(m_history.begin(), m_history.end(), 0); } m_overrun = false; - } - - // maximum amount of buffers relative to samples - const uint32_t max_buffers = std::max(m_max_buffers * 48000 / samples / 50, 4U); - - if(m_used_buffers > max_buffers) { + } else if(m_used_buffers > max_buffers) { // If there are too many buffers, drop some and mark this event as an overrun flush_buffers(max_buffers); m_overrun = true; + m_overruns++; } m_used_buffers_prev = m_used_buffers; - //printf("# %d %d %d\n", m_used_buffers, m_delta, m_delta2); + //printf("%d -%d +%d # %d %d\n", m_used_buffers, m_underruns, m_overruns, m_delta, m_delta2); } uint32_t sound_module::abuffer::available() const noexcept diff --git a/src/osd/modules/sound/sound_module.h b/src/osd/modules/sound/sound_module.h index 5c90433ce55..8d1697931dc 100644 --- a/src/osd/modules/sound/sound_module.h +++ b/src/osd/modules/sound/sound_module.h @@ -64,7 +64,6 @@ protected: void pop_buffer() noexcept; buffer &push_buffer(); - int32_t m_delta, m_delta2; uint32_t m_channels; uint32_t m_used_buffers; uint32_t m_used_buffers_prev; @@ -74,6 +73,10 @@ protected: bool m_overrun; std::vector<int16_t> m_last_sample; std::vector<buffer> m_buffers; + + // statistics + int32_t m_delta, m_delta2; + uint32_t m_underruns, m_overruns; }; }; |
