feat: waveform display + 3px progress bar in bubble + sliding window RMS

- AudioRecorder: sliding window RMS (avg 5 frames), waveformLevels() getter
- InputBar: downsample RMS to 100 samples, encode as wf0,wf1,... in textData
- MessageList: parse 3rd pipe-separated field as waveform, store in MsgVoiceWaveformRole
- MessageDelegate: new voice layout (16px play btn + 25px waveform + 3px progress bar)
- MessageDelegate: waveform bars colored by progress (blue before, gray after)
- Progress bar integrated at bottom of waveform area as colored fill
This commit is contained in:
Evgeny committed 2026-07-27 09:07:14 +03:00
1 parent 70a0a70b88
commit 05c7b4d47e
7 files changed
+133 -75

No files matched your search

+18 -2
View File
@@ -224,8 +224,24 @@ void InputBar::onPttReleased() {
int frames = VoiceEncoder::encodeToFile(pcm, 48000, 1, filePath, durationSec);
if (frames > 0) {
m_voiceFilePath = filePath;
GUI_INFO("InputBar: voice message ready: %s (%.1fs)", qPrintable(filePath), durationSec);
emit sendVoiceMessage(filePath, durationMs);
const auto& wf = m_recorder->waveformLevels();
QString wfStr;
int N = (int)wf.size();
for (int i = 0; i < 100; i++) {
int s = i * N / 100, e = (i + 1) * N / 100;
if (s >= N) s = N - 1;
if (e <= s) e = s + 1;
if (e > N) e = N;
float sum = 0; int cnt = 0;
for (int j = s; j < e; j++) { sum += wf[j]; cnt++; }
float v = cnt > 0 ? sum / cnt : 0;
if (i > 0) wfStr += ',';
wfStr += QString::number(v, 'f', 3);
}
GUI_INFO("InputBar: voice message ready: %s (%.1fs) wf=%d levels",
qPrintable(filePath), durationSec, N);
emit sendVoiceMessage(filePath, durationMs, wfStr);
}
}