From 11cfaf2a854789f95e8ed97bec2921099a3d512b Mon Sep 17 00:00:00 2001 From: Mariotaku Date: Fri, 10 Oct 2025 23:18:57 +0900 Subject: [PATCH 1/2] added continuous audio for windows --- src/audio.cpp | 5 +++-- src/audio.h | 1 + src/nvhttp.cpp | 1 + src/platform/common.h | 2 +- src/platform/linux/audio.cpp | 2 +- src/platform/macos/microphone.mm | 2 +- src/platform/windows/audio.cpp | 14 ++++++++++---- src/rtsp.cpp | 4 ++++ src/rtsp.h | 1 + 9 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/audio.cpp b/src/audio.cpp index 0d287071a25..4d306b48ddd 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -193,7 +193,8 @@ namespace audio { } auto frame_size = config.packetDuration * stream.sampleRate / 1000; - auto mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size); + bool continuous_audio = config.flags[config_t::CONTINUOUS_AUDIO]; + auto mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size, continuous_audio); if (!mic) { return; } @@ -230,7 +231,7 @@ namespace audio { BOOST_LOG(info) << "Reinitializing audio capture"sv; mic.reset(); do { - mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size); + mic = control->microphone(stream.mapping, stream.channelCount, stream.sampleRate, frame_size, continuous_audio); if (!mic) { BOOST_LOG(warning) << "Couldn't re-initialize audio input"sv; } diff --git a/src/audio.h b/src/audio.h index 2afb42e5f70..763cc9886dd 100644 --- a/src/audio.h +++ b/src/audio.h @@ -45,6 +45,7 @@ namespace audio { HIGH_QUALITY, ///< High quality audio HOST_AUDIO, ///< Host audio CUSTOM_SURROUND_PARAMS, ///< Custom surround parameters + CONTINUOUS_AUDIO, ///< Continuous audio MAX_FLAGS ///< Maximum number of flags }; diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index c1d9401c2f2..8a3da7142ff 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -307,6 +307,7 @@ namespace nvhttp { launch_session->enable_sops = util::from_view(get_arg(args, "sops", "0")); launch_session->surround_info = util::from_view(get_arg(args, "surroundAudioInfo", "196610")); launch_session->surround_params = (get_arg(args, "surroundParams", "")); + launch_session->continuous_audio = util::from_view(get_arg(args, "continuousAudio", "0")); launch_session->gcmap = util::from_view(get_arg(args, "gcmap", "0")); launch_session->enable_hdr = util::from_view(get_arg(args, "hdrMode", "0")); diff --git a/src/platform/common.h b/src/platform/common.h index 28704bb128e..d764f56dd9f 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -554,7 +554,7 @@ namespace platf { public: virtual int set_sink(const std::string &sink) = 0; - virtual std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) = 0; + virtual std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous) = 0; /** * @brief Check if the audio sink is available in the system. diff --git a/src/platform/linux/audio.cpp b/src/platform/linux/audio.cpp index 0e53e939b2a..a2df7bb05be 100644 --- a/src/platform/linux/audio.cpp +++ b/src/platform/linux/audio.cpp @@ -440,7 +440,7 @@ namespace platf { return monitor_name; } - std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override { + std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous_audio) override { // Sink choice priority: // 1. Config sink // 2. Last sink swapped to (Usually virtual in this case) diff --git a/src/platform/macos/microphone.mm b/src/platform/macos/microphone.mm index 06b9c19a899..fb702916f5d 100644 --- a/src/platform/macos/microphone.mm +++ b/src/platform/macos/microphone.mm @@ -49,7 +49,7 @@ int set_sink(const std::string &sink) override { return 0; } - std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override { + std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous_audio) override { auto mic = std::make_unique(); const char *audio_sink = ""; diff --git a/src/platform/windows/audio.cpp b/src/platform/windows/audio.cpp index 964a6afb1f0..98af1e75bc8 100644 --- a/src/platform/windows/audio.cpp +++ b/src/platform/windows/audio.cpp @@ -432,7 +432,11 @@ namespace platf::audio { // Refill the sample buffer if needed while (sample_buf_pos - std::begin(sample_buf) < sample_size) { auto capture_result = _fill_buffer(); - if (capture_result != capture_e::ok) { + if (capture_result == capture_e::timeout && continuous_audio) { + // Write silence to sample_buf + std::fill_n(sample_buf_pos, sample_size, 0.0f); + sample_buf_pos += sample_size; + } else if (capture_result != capture_e::ok) { return capture_result; } } @@ -447,7 +451,7 @@ namespace platf::audio { return capture_e::ok; } - int init(std::uint32_t sample_rate, std::uint32_t frame_size, std::uint32_t channels_out) { + int init(std::uint32_t sample_rate, std::uint32_t frame_size, std::uint32_t channels_out, bool continuous) { audio_event.reset(CreateEventA(nullptr, FALSE, FALSE, nullptr)); if (!audio_event) { BOOST_LOG(error) << "Couldn't create Event handle"sv; @@ -508,6 +512,7 @@ namespace platf::audio { REFERENCE_TIME default_latency; audio_client->GetDevicePeriod(&default_latency, nullptr); default_latency_ms = default_latency / 1000; + continuous_audio = continuous; std::uint32_t frames; status = audio_client->GetBufferSize(&frames); @@ -678,6 +683,7 @@ namespace platf::audio { util::buffer_t sample_buf; float *sample_buf_pos; int channels; + bool continuous_audio; HANDLE mmcss_task_handle = nullptr; }; @@ -761,10 +767,10 @@ namespace platf::audio { return std::nullopt; } - std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size) override { + std::unique_ptr microphone(const std::uint8_t *mapping, int channels, std::uint32_t sample_rate, std::uint32_t frame_size, bool continuous_audio) override { auto mic = std::make_unique(); - if (mic->init(sample_rate, frame_size, channels)) { + if (mic->init(sample_rate, frame_size, channels, continuous_audio)) { return nullptr; } diff --git a/src/rtsp.cpp b/src/rtsp.cpp index 25647e2e3d1..43117f37755 100644 --- a/src/rtsp.cpp +++ b/src/rtsp.cpp @@ -1030,6 +1030,10 @@ namespace rtsp_stream { } config.audio.flags[audio::config_t::CUSTOM_SURROUND_PARAMS] = valid; } + if (session.continuous_audio) { + BOOST_LOG(info) << "Client requested continuous audio"sv; + config.audio.flags[audio::config_t::CONTINUOUS_AUDIO] = true; + } // If the client sent a configured bitrate, we will choose the actual bitrate ourselves // by using FEC percentage and audio quality settings. If the calculated bitrate ends up diff --git a/src/rtsp.h b/src/rtsp.h index 2303b96b6b3..6dfa16e12e8 100644 --- a/src/rtsp.h +++ b/src/rtsp.h @@ -32,6 +32,7 @@ namespace rtsp_stream { int appid; int surround_info; std::string surround_params; + bool continuous_audio; bool enable_hdr; bool enable_sops; From e3069d9bff8438ed6997e98fb4396f5a0a949c28 Mon Sep 17 00:00:00 2001 From: Mariotaku Date: Sat, 11 Oct 2025 12:12:26 +0900 Subject: [PATCH 2/2] fixed test compile error --- tests/unit/test_audio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_audio.cpp b/tests/unit/test_audio.cpp index 46f060609a9..648b838ea17 100644 --- a/tests/unit/test_audio.cpp +++ b/tests/unit/test_audio.cpp @@ -19,7 +19,7 @@ struct AudioTest: PlatformTestSuite, testing::WithParamInterface config_flags(const int flag = -1) { - std::bitset<3> result = std::bitset(); + auto result = std::bitset(); if (flag >= 0) { result.set(flag); }