Browse Source

Preserve measured versus estimated device timing in voice mixer

master
evgeny 5 days ago
parent
commit
2f3eb66c4c
  1. 9
      tools/chatgui/src/sound_manager.cpp
  2. 2
      tools/chatgui/src/sound_manager.h

9
tools/chatgui/src/sound_manager.cpp

@ -95,7 +95,8 @@ void SoundManager::openOutput() {
uint64_t route = m_output.route();
if (previousRoute && route != previousRoute) for (auto* voice : m_voices) if (voice) voice->resetPlayback();
previousRoute = route;
m_renderErrors.fetch_add(renderOutput(m_engine, m_voices, static_cast<float*>(out), frames, m_output.callbackTimeUs()));
m_renderErrors.fetch_add(renderOutput(m_engine, m_voices, static_cast<float*>(out), frames,
m_output.callbackTimeUs(), m_output.timingMeasured()));
};
if (m_output.init(m_context, config, "sound-engine", 0, callback) && m_output.start()) {
m_actualOutput = resolveOutput(m_playbackId); return;
@ -154,7 +155,7 @@ void SoundManager::recoverAudio() {
/* Последнее смешивание и ограничение: тот же PCM передаётся устройству и всем AEC этого выхода. */
unsigned SoundManager::renderOutput(ma_engine* engine, const std::array<VoiceAudioIo*, 2>& voices,
float* out, unsigned frames, int64_t firstTimeUs) {
float* out, unsigned frames, int64_t firstTimeUs, bool measured) {
unsigned errors = 0;
for (unsigned offset = 0; offset < frames;) {
unsigned count = std::min(frames - offset, 960u);
@ -163,7 +164,7 @@ unsigned SoundManager::renderOutput(ma_engine* engine, const std::array<VoiceAud
if (engine && ma_engine_read_pcm_frames(engine, destination, count, nullptr) != MA_SUCCESS) {
++errors; std::fill_n(destination, count * 2, 0.0f);
}
for (auto* voice : voices) if (voice) voice->mix(destination, count, firstTimeUs + (int64_t)offset * 1000000 / 48000);
for (auto* voice : voices) if (voice) voice->mix(destination, count, firstTimeUs + (int64_t)offset * 1000000 / 48000, measured);
for (unsigned i = 0; i < count * 2; ++i) {
float value = destination[i];
destination[i] = std::isfinite(value) ? std::clamp(value, -1.0f, 1.0f) : 0.0f;
@ -199,7 +200,7 @@ bool SoundManager::openVoiceRoute(VoiceRoute& route) {
if (physical && physical == m_output.route()) {
std::fill_n(static_cast<float*>(out), frames * 2, 0.0f); return; // GUI объединит совпавшие маршруты.
}
renderOutput(nullptr, route.voices, static_cast<float*>(out), frames, route.device.callbackTimeUs());
renderOutput(nullptr, route.voices, static_cast<float*>(out), frames, route.device.callbackTimeUs(), route.device.timingMeasured());
};
if (route.device.init(m_context, config, "voice-output", 0, callback) && route.device.start()) {
route.actual = resolveOutput(route.wanted); return true;

2
tools/chatgui/src/sound_manager.h

@ -111,7 +111,7 @@ private:
bool openVoiceRoute(VoiceRoute& route);
void mergeVoiceRoutes();
static unsigned renderOutput(ma_engine* engine, const std::array<VoiceAudioIo*, 2>& voices,
float* out, unsigned frames, int64_t firstTimeUs);
float* out, unsigned frames, int64_t firstTimeUs, bool measured);
std::atomic<unsigned> m_renderErrors{0};
std::array<VoiceAudioIo*, 2> m_voices{};
std::map<QString, std::unique_ptr<VoiceRoute>> m_voiceRoutes;

Loading…
Cancel
Save