Browse Source

fix: voice playback coordinate bug + debug logging + device name encoding

- messagedelegate: editorEvent now adjusts me->pos() by option.rect.topLeft()
- voiceplayback: enhanced debug logging for file open/decode/play
- messagelist: debug voice file path + exists check
- inputbar: debug mediaDir path on record
- sound_manager: debug in playRawPcm, decodeDeviceName() for mixed encodings
- voiceencoder: debug file write path
topo_upd
Evgeny 2 months ago
parent
commit
01012675d0
  1. 3
      tools/chatgui/src/inputbar.cpp
  2. 7
      tools/chatgui/src/messagedelegate.cpp
  3. 5
      tools/chatgui/src/messagelist.cpp
  4. 19
      tools/chatgui/src/sound_manager.cpp
  5. 3
      tools/chatgui/src/voicemessageencoder.cpp
  6. 15
      tools/chatgui/src/voiceplayback.cpp

3
tools/chatgui/src/inputbar.cpp

@ -15,6 +15,7 @@
#include <QApplication>
#include <QLabel>
#include <QResizeEvent>
#include <QDir>
static QPushButton *makeIconBtn(const QString &text, const QString &tooltip, QWidget *parent) {
auto *btn = new QPushButton(text, parent);
@ -214,6 +215,8 @@ void InputBar::onPttReleased() {
QString mediaPath = m_mediaDirBase + "/" + m_channelIdForRecord;
VoiceEncoder::ensureMediaDir(mediaPath);
qDebug("InputBar::onPttReleased: mediaDir=%s exists=%d channel=%s",
qPrintable(mediaPath), QDir(mediaPath).exists(), qPrintable(m_channelIdForRecord));
QString fileName = VoiceEncoder::generateFileName();
QString filePath = mediaPath + "/" + fileName;

7
tools/chatgui/src/messagedelegate.cpp

@ -16,6 +16,8 @@
#include <QMap>
#include <QDateTime>
#include <QTimer>
#include <QFile>
#include <QDebug>
MessageDelegate::MessageDelegate(QObject *parent)
: QStyledItemDelegate(parent) {}
@ -61,9 +63,12 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
if (!L.isVoice) return false;
QMouseEvent* me = static_cast<QMouseEvent*>(event);
if (!L.voicePlayBtnRect.contains(me->pos())) return false;
QPoint localPos = me->pos() - option.rect.topLeft();
if (!L.voicePlayBtnRect.contains(localPos)) return false;
QString filePath = index.data(MsgVoiceFileRole).toString();
qDebug("MessageDelegate::editorEvent voice click: filePath=%s exists=%d",
qPrintable(filePath), QFile::exists(filePath));
if (filePath.isEmpty()) return false;
ensureVoiceTimer();

5
tools/chatgui/src/messagelist.cpp

@ -18,6 +18,7 @@
#include <QApplication>
#include <QDebug>
#include <QFileInfo>
#include <QFile>
#include <vector>
#include <memory>
@ -102,6 +103,10 @@ static void setVoiceMessageRoles(QStandardItem* item, const QByteArray& data,
if (!fname.isEmpty()) {
QString fullPath = mediaDirBase + "/" + channelId + "/" + fname;
item->setData(fullPath, MsgVoiceFileRole);
qDebug("setVoiceMessageRoles: voice file=%s dur=%s exists=%d",
qPrintable(fullPath), qPrintable(dur), QFile::exists(fullPath));
} else {
qWarning("setVoiceMessageRoles: empty filename, raw='%s'", qPrintable(raw));
}
}
}

19
tools/chatgui/src/sound_manager.cpp

@ -141,7 +141,11 @@ ma_context* SoundManager::context() {
}
void SoundManager::playRawPcm(const int16_t* pcm, int sampleCount, int sampleRate, int channels) {
if (!m_engine || !m_initialized) return;
if (!m_engine || !m_initialized) {
qWarning("SoundManager::playRawPcm: not initialized (engine=%p init=%d)", (void*)m_engine, m_initialized);
return;
}
qDebug("SoundManager::playRawPcm: %d samples %dHz %dch vol=%.2f", sampleCount, sampleRate, channels, m_volume);
ma_audio_buffer_config bufCfg = ma_audio_buffer_config_init(
ma_format_s16, (ma_uint32)channels, (ma_uint64)sampleCount, pcm, NULL);
@ -165,7 +169,14 @@ void SoundManager::playRawPcm(const int16_t* pcm, int sampleCount, int sampleRat
ma_sound_set_volume(sound, m_volume);
ma_sound_start(sound);
qDebug("SoundManager: playing PCM (%d samples, %dHz, %dch)", sampleCount, sampleRate, channels);
qDebug("SoundManager::playRawPcm: started");
}
static QString decodeDeviceName(const char* name) {
QString s = QString::fromUtf8(name);
if (s.contains(QChar(0xFFFD)))
s = QString::fromLocal8Bit(name);
return s;
}
QVector<SoundManager::DeviceInfo> SoundManager::enumeratePlaybackDevices() {
@ -177,7 +188,7 @@ QVector<SoundManager::DeviceInfo> SoundManager::enumeratePlaybackDevices() {
ma_uint32 count = 0;
if (ma_context_get_devices(ctx, &pDevices, &count, nullptr, nullptr) != MA_SUCCESS) return result;
for (ma_uint32 i = 0; i < count; i++)
result.append({QString::fromLocal8Bit(pDevices[i].name), pDevices[i].isDefault != MA_FALSE});
result.append({decodeDeviceName(pDevices[i].name), pDevices[i].isDefault != MA_FALSE});
return result;
}
@ -190,6 +201,6 @@ QVector<SoundManager::DeviceInfo> SoundManager::enumerateCaptureDevices() {
ma_uint32 count = 0;
if (ma_context_get_devices(ctx, nullptr, nullptr, &pDevices, &count) != MA_SUCCESS) return result;
for (ma_uint32 i = 0; i < count; i++)
result.append({QString::fromLocal8Bit(pDevices[i].name), pDevices[i].isDefault != MA_FALSE});
result.append({decodeDeviceName(pDevices[i].name), pDevices[i].isDefault != MA_FALSE});
return result;
}

3
tools/chatgui/src/voicemessageencoder.cpp

@ -47,10 +47,11 @@ int VoiceEncoder::encodeToFile(const std::vector<int16_t>& pcm, int sampleRate,
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly)) {
qWarning("VoiceEncoder: cannot open file %s", qPrintable(filePath));
qWarning("VoiceEncoder: cannot open file %s (%s)", qPrintable(filePath), qPrintable(file.errorString()));
opus_codec_encoder_destroy(enc);
return -1;
}
qDebug("VoiceEncoder::encodeToFile: writing to %s pcm=%zu samples", qPrintable(filePath), pcm.size());
/* write header */
uint32_t magic = OPUS_MAGIC;

15
tools/chatgui/src/voiceplayback.cpp

@ -13,10 +13,15 @@ static const uint32_t OPUS_MAGIC = 0x5355504F;
int VoicePlayer::decodeOpusFile(const QString& filePath, std::vector<int16_t>& outPcm,
int& outSampleRate, int& outChannels, float& outDurationSec) {
QFile file(filePath);
if (!file.exists()) {
qWarning("VoicePlayer: file not found: %s", qPrintable(filePath));
return -1;
}
if (!file.open(QIODevice::ReadOnly)) {
qWarning("VoicePlayer: cannot open %s", qPrintable(filePath));
qWarning("VoicePlayer: cannot open %s (%s)", qPrintable(filePath), qPrintable(file.errorString()));
return -1;
}
qDebug("VoicePlayer: opened file %s size=%lld", qPrintable(filePath), (long long)file.size());
uint32_t magic, sr32;
uint16_t ch16, frameSamples;
@ -68,11 +73,17 @@ int VoicePlayer::decodeOpusFile(const QString& filePath, std::vector<int16_t>& o
}
void VoicePlayer::playOpusFile(const QString& filePath) {
qDebug("VoicePlayer::playOpusFile: %s", qPrintable(filePath));
std::vector<int16_t> pcm;
int sampleRate, channels;
float duration;
if (decodeOpusFile(filePath, pcm, sampleRate, channels, duration) <= 0) return;
if (decodeOpusFile(filePath, pcm, sampleRate, channels, duration) <= 0) {
qWarning("VoicePlayer::playOpusFile: decode failed for %s", qPrintable(filePath));
return;
}
qDebug("VoicePlayer::playOpusFile: decoded %zu samples %dHz %dch %.1fs → playing",
pcm.size(), sampleRate, channels, duration);
SoundManager::instance()->playRawPcm(pcm.data(), pcm.size() / channels, sampleRate, channels);
}

Loading…
Cancel
Save