base.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #ifndef ALC_BACKENDS_BASE_H
  2. #define ALC_BACKENDS_BASE_H
  3. #include <chrono>
  4. #include <cstdarg>
  5. #include <cstddef>
  6. #include <memory>
  7. #include <string>
  8. #include <string_view>
  9. #include <vector>
  10. #include "alc/events.h"
  11. #include "core/device.h"
  12. #include "core/except.h"
  13. #include "fmt/core.h"
  14. using uint = unsigned int;
  15. struct ClockLatency {
  16. std::chrono::nanoseconds ClockTime;
  17. std::chrono::nanoseconds Latency;
  18. };
  19. struct BackendBase {
  20. virtual void open(std::string_view name) = 0;
  21. virtual bool reset();
  22. virtual void start() = 0;
  23. virtual void stop() = 0;
  24. virtual void captureSamples(std::byte *buffer, uint samples);
  25. virtual uint availableSamples();
  26. virtual ClockLatency getClockLatency();
  27. DeviceBase *const mDevice;
  28. std::string mDeviceName;
  29. BackendBase() = delete;
  30. BackendBase(const BackendBase&) = delete;
  31. BackendBase(BackendBase&&) = delete;
  32. explicit BackendBase(DeviceBase *device) noexcept : mDevice{device} { }
  33. virtual ~BackendBase() = default;
  34. void operator=(const BackendBase&) = delete;
  35. void operator=(BackendBase&&) = delete;
  36. protected:
  37. /** Sets the default channel order used by most non-WaveFormatEx-based APIs. */
  38. void setDefaultChannelOrder() const;
  39. /** Sets the default channel order used by WaveFormatEx. */
  40. void setDefaultWFXChannelOrder() const;
  41. };
  42. using BackendPtr = std::unique_ptr<BackendBase>;
  43. enum class BackendType {
  44. Playback,
  45. Capture
  46. };
  47. /* Helper to get the device latency from the backend, including any fixed
  48. * latency from post-processing.
  49. */
  50. inline ClockLatency GetClockLatency(DeviceBase *device, BackendBase *backend)
  51. {
  52. ClockLatency ret{backend->getClockLatency()};
  53. ret.Latency += device->FixedLatency;
  54. return ret;
  55. }
  56. struct BackendFactory {
  57. BackendFactory() = default;
  58. BackendFactory(const BackendFactory&) = delete;
  59. BackendFactory(BackendFactory&&) = delete;
  60. virtual ~BackendFactory() = default;
  61. void operator=(const BackendFactory&) = delete;
  62. void operator=(BackendFactory&&) = delete;
  63. virtual auto init() -> bool = 0;
  64. virtual auto querySupport(BackendType type) -> bool = 0;
  65. virtual auto queryEventSupport(alc::EventType, BackendType) -> alc::EventSupport
  66. { return alc::EventSupport::NoSupport; }
  67. virtual auto enumerate(BackendType type) -> std::vector<std::string> = 0;
  68. virtual auto createBackend(DeviceBase *device, BackendType type) -> BackendPtr = 0;
  69. };
  70. namespace al {
  71. enum class backend_error {
  72. NoDevice,
  73. DeviceError,
  74. OutOfMemory
  75. };
  76. class backend_exception final : public base_exception {
  77. backend_error mErrorCode;
  78. static auto make_string(fmt::string_view fmt, fmt::format_args args) -> std::string;
  79. public:
  80. template<typename ...Args>
  81. backend_exception(backend_error code, fmt::format_string<Args...> fmt, Args&& ...args)
  82. : base_exception{make_string(fmt, fmt::make_format_args(args...))}, mErrorCode{code}
  83. { }
  84. backend_exception(const backend_exception&) = default;
  85. backend_exception(backend_exception&&) = default;
  86. ~backend_exception() override;
  87. backend_exception& operator=(const backend_exception&) = default;
  88. backend_exception& operator=(backend_exception&&) = default;
  89. [[nodiscard]] auto errorCode() const noexcept -> backend_error { return mErrorCode; }
  90. };
  91. } // namespace al
  92. #endif /* ALC_BACKENDS_BASE_H */