// Captures system output audio, applies DSP, and replays it in real time.
// Designed for low-latency playback while controls change during runtime.

#ifndef WIN32BASSBOOSTER_SRC_AUDIO_PIPELINE_HPP_
#define WIN32BASSBOOSTER_SRC_AUDIO_PIPELINE_HPP_

#include <algorithm>
#include <atomic>
#include <cmath>
#include <memory>
#include <stop_token>
#include <string>
#include <thread>

#include "audio_device.hpp"
#include "audio_pipeline_interface.hpp"
#include "bass_boost_filter.hpp"

// Coordinates device startup, the background capture/DSP/render loop, and the
// user-facing boost controls.
class AudioPipeline final : public AudioPipelineInterface {
 public:
  // Creates a pipeline with a `WasapiAudioDevice` for production use.
  AudioPipeline();
  // Takes ownership of `device`; the device provides all audio I/O.
  explicit AudioPipeline(std::unique_ptr<AudioDevice> device);
  ~AudioPipeline() override;

  AudioPipeline(const AudioPipeline&) = delete;
  AudioPipeline& operator=(const AudioPipeline&) = delete;

  // Opens the device, caches endpoint metadata, and starts the background
  // audio thread. Returns the first startup failure from the device.
  [[nodiscard]] AudioPipelineInterface::Status Start() override;
  // Stops the background thread, closes the device, and leaves the pipeline in
  // a safe stopped state even if startup only partially completed.
  void Stop() override;

  // Maps UI boost `level` from [0.0, 1.0] onto the filter gain curve.
  void SetBoostLevel(double level) override {
    const double clamped = std::clamp(level, 0.0, 1.0);
    filter_.SetGainDb(BassBoostFilter::kMaxGainDb * std::sqrt(clamped));
  }

  // Returns whether the background audio thread is currently running.
  [[nodiscard]] bool is_running() const noexcept { return running_.load(); }
  // Returns the current bass boost gain in dB.
  [[nodiscard]] double gain_db() const override { return filter_.gain_db(); }
  // Returns the cached friendly name of the most recently opened endpoint.
  [[nodiscard]] const std::wstring& endpoint_name() const override {
    return endpoint_name_;
  }

 private:
  // Owned audio I/O boundary used for startup, packet reads, writes, and
  // recovery.
  std::unique_ptr<AudioDevice> device_;

  // Low-shelf EQ that boosts bass frequencies. Applied first in the DSP chain.
  BassBoostFilter filter_;

  // Runs the capture-DSP-render loop off the UI thread so audio processing
  // never blocks the window message pump.
  std::jthread audio_thread_;
  // Lets callers observe pipeline state without querying the thread directly.
  std::atomic<bool> running_ = false;

  // Cached endpoint label to avoid repeated COM/property-store reads.
  std::wstring endpoint_name_;
};

#endif  // WIN32BASSBOOSTER_SRC_AUDIO_PIPELINE_HPP_

Generated by OpenCppCoverage (Version: 0.9.9.0)