From 91cadd2b7a7745fed2012c9fa9b00c562d843f8a Mon Sep 17 00:00:00 2001 From: webadderall <131426131+webadderall@users.noreply.github.com> Date: Thu, 19 Mar 2026 19:53:44 +1100 Subject: [PATCH] Fix missing WasapiCapture pause and resume methods --- .../wgc-capture/src/wasapi_loopback.cpp | 68 ++++++++++++++----- .../native/wgc-capture/src/wasapi_loopback.h | 5 ++ 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/electron/native/wgc-capture/src/wasapi_loopback.cpp b/electron/native/wgc-capture/src/wasapi_loopback.cpp index af9b5bc3..8ae15ad1 100644 --- a/electron/native/wgc-capture/src/wasapi_loopback.cpp +++ b/electron/native/wgc-capture/src/wasapi_loopback.cpp @@ -125,19 +125,61 @@ bool WasapiCapture::initializeCommon() { } bool WasapiCapture::start() { + if (capturing_) return true; + + outputFile_ = CreateFileA( + outputPath_.c_str(), GENERIC_WRITE, 0, nullptr, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + + if (outputFile_ == INVALID_HANDLE_VALUE) { + std::cerr << "ERROR: Cannot create audio output file" << std::endl; + return false; + } + + totalDataBytes_ = 0; + writeWavHeader(outputFile_, 0); + HRESULT hr = audioClient_->Start(); - if (FAILED(hr)) return false; + if (FAILED(hr)) { + CloseHandle(outputFile_); + outputFile_ = INVALID_HANDLE_VALUE; + return false; + } capturing_ = true; + paused_ = false; thread_ = std::thread(&WasapiCapture::captureThread, this); return true; } +bool WasapiCapture::pause() { + if (!capturing_ || paused_) return true; + paused_ = true; + return audioClient_ ? SUCCEEDED(audioClient_->Stop()) : false; +} + +bool WasapiCapture::resume() { + if (!capturing_ || !paused_) return true; + HRESULT hr = audioClient_ ? audioClient_->Start() : E_FAIL; + if (FAILED(hr)) return false; + paused_ = false; + return true; +} + void WasapiCapture::stop() { if (!capturing_) return; capturing_ = false; if (thread_.joinable()) thread_.join(); if (audioClient_) audioClient_->Stop(); + + if (outputFile_ != INVALID_HANDLE_VALUE) { + SetFilePointer(outputFile_, 0, nullptr, FILE_BEGIN); + writeWavHeader(outputFile_, totalDataBytes_); + CloseHandle(outputFile_); + outputFile_ = INVALID_HANDLE_VALUE; + } + + paused_ = false; } static int16_t floatToInt16(float v) { @@ -179,22 +221,16 @@ void WasapiCapture::captureThread() { reinterpret_cast(mixFormat_)->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); std::vector pcmBuffer; - HANDLE tmpFile = CreateFileA( - outputPath_.c_str(), GENERIC_WRITE, 0, nullptr, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - - if (tmpFile == INVALID_HANDLE_VALUE) { - std::cerr << "ERROR: Cannot create audio output file" << std::endl; - return; - } - - writeWavHeader(tmpFile, 0); - DWORD totalDataBytes = 0; DWORD sleepMs = static_cast((static_cast(bufferFrameCount_) / mixFormat_->nSamplesPerSec) * 500.0); if (sleepMs < 5) sleepMs = 5; while (capturing_) { + if (paused_) { + Sleep(10); + continue; + } + Sleep(sleepMs); UINT32 packetLength = 0; @@ -228,15 +264,11 @@ void WasapiCapture::captureThread() { DWORD bytesToWrite = totalSamples * sizeof(int16_t); DWORD written; - WriteFile(tmpFile, pcmBuffer.data(), bytesToWrite, &written, nullptr); - totalDataBytes += written; + WriteFile(outputFile_, pcmBuffer.data(), bytesToWrite, &written, nullptr); + totalDataBytes_ += written; hr = captureClient_->GetNextPacketSize(&packetLength); if (FAILED(hr)) break; } } - - SetFilePointer(tmpFile, 0, nullptr, FILE_BEGIN); - writeWavHeader(tmpFile, totalDataBytes); - CloseHandle(tmpFile); } diff --git a/electron/native/wgc-capture/src/wasapi_loopback.h b/electron/native/wgc-capture/src/wasapi_loopback.h index 3b2b76df..a4facf13 100644 --- a/electron/native/wgc-capture/src/wasapi_loopback.h +++ b/electron/native/wgc-capture/src/wasapi_loopback.h @@ -16,6 +16,8 @@ public: bool initializeLoopback(const std::string& outputPath); bool initializeMic(const std::string& outputPath, const std::string& deviceName = ""); bool start(); + bool pause(); + bool resume(); void stop(); private: @@ -27,6 +29,9 @@ private: std::string outputPath_; std::thread thread_; std::atomic capturing_{false}; + std::atomic paused_{false}; + HANDLE outputFile_ = INVALID_HANDLE_VALUE; + DWORD totalDataBytes_ = 0; IMMDeviceEnumerator* enumerator_ = nullptr; IMMDevice* device_ = nullptr;