// Abstract audio device for capture and render I/O. Lets tests substitute a
// mock device that provides canned audio data without real hardware.

#ifndef WIN32BASSBOOSTER_SRC_AUDIO_DEVICE_HPP_
#define WIN32BASSBOOSTER_SRC_AUDIO_DEVICE_HPP_

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <cstdint>
#include <span>
#include <string>
#include <vector>

#include "audio_pipeline_interface.hpp"

// One read result from the capture stream: decoded interleaved stereo float
// (L, R, L, R, ...), or an error/empty read when `status` or `frames` says so.
struct CapturePacket {
  // `S_OK` on success, or the failing HRESULT from the capture path.
  HRESULT status = S_OK;
  // Interleaved stereo float PCM in L,R order.
  std::vector<float> samples;
  // Number of stereo frames represented in `samples`.
  uint32_t frames = 0;
  // True when the endpoint marked the packet as silence.
  bool silent = false;
};

// Abstract capture and render device boundary used by `AudioPipeline`.
class AudioDevice {
 public:
  virtual ~AudioDevice() = default;

  // Acquires the audio endpoint and sets up capture and render streams.
  // Returns `Ok` on success; otherwise returns the failing HRESULT and message.
  [[nodiscard]] virtual AudioPipelineInterface::Status Open() = 0;

  // Starts both capture and render streams. Requires a prior successful
  // `Open()`.
  [[nodiscard]] virtual AudioPipelineInterface::Status StartStreams() = 0;

  // Stops both capture and render streams. Safe to call when not streaming.
  virtual void StopStreams() = 0;

  // Releases all device resources. Safe to call when already closed.
  virtual void Close() = 0;

  // Reads, decodes, and releases one capture packet as interleaved stereo
  // float PCM. Returns an empty packet (`frames == 0`) when no data is
  // pending.
  [[nodiscard]] virtual CapturePacket ReadNextPacket() = 0;

  // Writes processed stereo float samples to the render buffer. Returns
  // `S_OK` on success, `S_FALSE` when the render buffer cannot accept the
  // frames from `pcm`, or a failing HRESULT on error.
  [[nodiscard]] virtual HRESULT WriteRenderPacket(
      std::span<const float> pcm) = 0;

  // Attempts recovery after a stream failure by re-acquiring the endpoint and
  // restarting streams. `failure` is the HRESULT that broke the current
  // stream pair. Returns true when recovery succeeds; false otherwise.
  [[nodiscard]] virtual bool TryRecover(HRESULT failure) = 0;

  // Returns the device sample rate in Hz (e.g. 48000.0).
  [[nodiscard]] virtual double sample_rate() const = 0;

  // Returns the friendly name of the current audio endpoint.
  [[nodiscard]] virtual const std::wstring& endpoint_name() const = 0;
};

#endif  // WIN32BASSBOOSTER_SRC_AUDIO_DEVICE_HPP_

Generated by OpenCppCoverage (Version: 0.9.9.0)