#pragma once #include #include #include namespace Emulator { struct Interface; struct Audio; struct Filter; struct Stream; struct Audio { auto reset(maybe channels = nothing, maybe frequency = nothing) -> void; auto setInterface(Interface* interface) -> void; auto setVolume(double volume) -> void; auto setBalance(double balance) -> void; auto setReverb(bool enabled) -> void; auto createStream(uint channels, double frequency) -> shared_pointer; private: auto process() -> void; Interface* interface = nullptr; vector> streams; uint channels = 0; double frequency = 0.0; double volume = 1.0; double balance = 0.0; bool reverbEnable = false; vector>> reverb; friend class Stream; }; struct Filter { enum class Order : uint { First, Second }; enum class Type : uint { LowPass, HighPass }; Order order; DSP::IIR::OnePole onePole; //first-order DSP::IIR::Biquad biquad; //second-order }; struct Stream { auto reset(uint channels, double inputFrequency, double outputFrequency) -> void; auto addFilter(Filter::Order order, Filter::Type type, double cutoffFrequency, uint passes = 1) -> void; auto pending() const -> bool; auto read(double* samples) -> uint; auto write(const double* samples) -> void; template auto sample(P&&... p) -> void { double samples[sizeof...(P)] = {forward

(p)...}; write(samples); } private: struct Channel { vector filters; DSP::Resampler::Cubic resampler; }; vector channels; double inputFrequency; double outputFrequency; friend class Audio; }; extern Audio audio; }