diff --git a/src/stream/stream.c b/src/stream/stream.c index 38ea3f2f..38731c5b 100644 --- a/src/stream/stream.c +++ b/src/stream/stream.c @@ -1058,6 +1058,7 @@ int stream_ingest_end(struct UTUN_INSTANCE *inst, const struct stream_descriptor return STREAM_ERR_CONFLICT; } memcpy(s->end, wire, STREAM_END_SIZE); s->end_valid = s->finished = 1; s->last_seq = last; + session_radio_update(s); for (unsigned i = 0; i < s->descriptor.n; i++) if (last == UINT64_MAX || (s->metrics[i].initialized && s->metrics[i].last_seq == last)) stream_metrics_end(&s->metrics[i]); session_schedule(s); stream_network_changed(inst->stream->network); return STREAM_OK; diff --git a/tools/chatgui/tests/test_stream_publish.cpp b/tools/chatgui/tests/test_stream_publish.cpp index a5e78f27..ffa75810 100644 --- a/tools/chatgui/tests/test_stream_publish.cpp +++ b/tools/chatgui/tests/test_stream_publish.cpp @@ -281,6 +281,34 @@ private slots: QTest::qWait(1); } QVERIFY(video >= 10); QVERIFY(audio >= 40); QVERIFY(latest > first + 1000000); QVERIFY(left && right > left * 3); + AudioCapture radio; + std::atomic radioFrames{0}; + QVERIFY(radio.open({}, AudioCapture::Role::Radio, 1, 303, [](int, int) { return true; }, [] {}, + [&radioFrames](const AudioCapture::Frame& frame) { + for (unsigned i = 0; i < frame.frames * frame.channels; i++) + if (frame.pcm[i]) { radioFrames++; break; } + })); + for (bool muted : {true, false}) { + auto before = radioFrames.load(); engine.setMuted(muted); QCOMPARE(engine.muted(), muted); + stream_member_state member{}; + QTRY_VERIFY(stream_member_load(inst, group, inst->node_id, &member, nullptr) == STREAM_OK && member.audio_enabled == !muted); + QCOMPARE(member.source.source_epoch, epoch); + int peak = 0; unsigned checked = 0; + elapsed.restart(); + while (elapsed.elapsed() < 1200) { + if (gui_stream_pull(202, out, 0, true, 60000000) && out.kind == StreamRecordKind::Audio) { + int16_t pcm[1920]; + QCOMPARE(opus_codec_decode(decoder, (const uint8_t*)out.data.constData(), out.data.size(), pcm, 960), 960); + if (elapsed.elapsed() > 400) { + checked++; for (int16_t sample : pcm) peak = std::max(peak, std::abs((int)sample)); + } + } + QTest::qWait(1); + } + QVERIFY(checked >= 20); QVERIFY(muted ? peak < 5 : peak > 100); + QVERIFY(radioFrames.load() > before + 10); QVERIFY(radio.running()); + } + radio.close(); opus_codec_decoder_destroy(decoder); auto next = config; next.video.bitrate = 1000000; next.video.rotation = 90; if (engine.codecs().contains(STREAM_MEDIA_VP9)) next.video.codec = STREAM_MEDIA_VP9;