Play live stereo on desktop and verify channel separation
This commit is contained in:
1 parent
e06e9b0e22
commit
214a98efb1
3 files changed
+30
-14
No files matched your search
@@ -39,7 +39,7 @@ QString text(const char* value) { return QCoreApplication::translate("ChatGui",
|
||||
|
||||
struct StreamPlayerWindow::Playback {
|
||||
struct Video { QImage image; int64_t pts; };
|
||||
struct Audio { std::array<int16_t, 960> pcm; int64_t pts; unsigned offset = 0; };
|
||||
struct Audio { std::array<int16_t, 1920> pcm; int64_t pts; unsigned offset = 0; };
|
||||
uint64_t id = ++nextId, group = 0, source = 0, epoch = 0;
|
||||
std::atomic<bool> running{true}, audioAvailable{false};
|
||||
std::atomic<float> volume{1.0f};
|
||||
@@ -96,11 +96,11 @@ void StreamPlayerWindow::openAudio() {
|
||||
ma_context* context = SoundManager::instance()->context();
|
||||
if (!context) { DEBUG_WARN(DEBUG_CATEGORY_STREAM, "desktop stream audio unavailable: no context"); return; }
|
||||
auto config = ma_device_config_init(ma_device_type_playback);
|
||||
config.sampleRate = 48000; config.playback.channels = 1; config.playback.format = ma_format_s16;
|
||||
config.sampleRate = 48000; config.playback.channels = 2; config.playback.format = ma_format_s16;
|
||||
ma_device_id device;
|
||||
if (SoundManager::deviceId(SoundManager::instance()->playbackDevice(), &device)) config.playback.pDeviceID = &device;
|
||||
bool initialized = m_audio.init(context, config, "stream", m_playback->id, [this](const void*, void* output, unsigned frames) {
|
||||
auto* pcm = static_cast<int16_t*>(output); std::fill(pcm, pcm + frames, 0);
|
||||
auto* pcm = static_cast<int16_t*>(output); std::fill(pcm, pcm + frames * 2, 0);
|
||||
auto& p = *m_playback; std::lock_guard<std::mutex> guard(p.lock);
|
||||
int64_t now = nowUs();
|
||||
if (!p.prefillUntil || now < p.prefillUntil) return;
|
||||
@@ -109,7 +109,7 @@ void StreamPlayerWindow::openAudio() {
|
||||
auto& packet = p.audios.front();
|
||||
if (firstPts < 0) firstPts = packet.pts + packet.offset * 1000000LL / 48000 - written * 1000000LL / 48000;
|
||||
unsigned count = std::min(frames - written, 960 - packet.offset);
|
||||
for (unsigned i = 0; i < count; i++) pcm[written + i] = static_cast<int16_t>(packet.pcm[packet.offset + i] * volume);
|
||||
for (unsigned i = 0; i < count * 2; i++) pcm[written * 2 + i] = static_cast<int16_t>(packet.pcm[packet.offset * 2 + i] * volume);
|
||||
written += count; packet.offset += count;
|
||||
if (packet.offset == 960) p.audios.pop_front();
|
||||
}
|
||||
@@ -124,7 +124,7 @@ void StreamPlayerWindow::openAudio() {
|
||||
m_audio.close(); m_playback->audioAvailable = false; return;
|
||||
}
|
||||
m_playback->audioAvailable = true;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop stream audio output ready id=%llu", (unsigned long long)m_playback->id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop stream audio output ready id=%llu rate=48000 channels=2", (unsigned long long)m_playback->id);
|
||||
}
|
||||
|
||||
/* GUI забирает последний готовый кадр по аппаратным часам, не накапливая Qt-сигналы с QImage. */
|
||||
@@ -216,7 +216,7 @@ void StreamPlayerWindow::decode() {
|
||||
if (record.pts > INT64_MAX) { fail(text("Invalid stream timestamp")); break; }
|
||||
if (record.kind == StreamRecordKind::Audio) {
|
||||
if (!p.audioAvailable) continue;
|
||||
if (!opus) opus = opus_codec_decoder_create(48000, 1);
|
||||
if (!opus) opus = opus_codec_decoder_create(48000, 2);
|
||||
if (!opus) { fail(text("Stream audio decoder failed")); break; }
|
||||
if (expectedAudio >= 0 && (static_cast<int64_t>(record.pts) < expectedAudio - 10000
|
||||
|| static_cast<int64_t>(record.pts) > expectedAudio + 100000)) {
|
||||
|
||||
Reference in new issue
Block a user