#pragma once #include #include #include #include #include #include "boo/BooObject.hpp" #include "boo/audiodev/IAudioSubmix.hpp" #include "boo/audiodev/IAudioVoice.hpp" #include "boo/audiodev/IMIDIPort.hpp" namespace boo { struct IAudioVoiceEngine; /** Time-sensitive event callback for synchronizing the client with rendered audio waveform */ struct IAudioVoiceEngineCallback { /** All mixing occurs in virtual 5ms intervals; * this is called at the start of each interval for all mixable entities */ virtual void on5MsInterval(IAudioVoiceEngine& engine, double dt) {} /** When a pumping cycle is complete this is called to allow the client to * perform periodic cleanup tasks */ virtual void onPumpCycleComplete(IAudioVoiceEngine& engine) {} }; /** Mixing and sample-rate-conversion system. Allocates voices and mixes them * before sending the final samples to an OS-supplied audio-queue */ struct IAudioVoiceEngine { virtual ~IAudioVoiceEngine() = default; /** Client calls this to request allocation of new mixer-voice. * Returns empty unique_ptr if necessary resources aren't available. * ChannelLayout automatically reduces to maximum-supported layout by HW. * * Client must be prepared to supply audio frames via the callback when this is called; * the backing audio-buffers are primed with initial data for low-latency playback start */ virtual ObjToken allocateNewMonoVoice(double sampleRate, IAudioVoiceCallback* cb, bool dynamicPitch = false) = 0; /** Same as allocateNewMonoVoice, but source audio is stereo-interleaved */ virtual ObjToken allocateNewStereoVoice(double sampleRate, IAudioVoiceCallback* cb, bool dynamicPitch = false) = 0; /** Client calls this to allocate a Submix for gathering audio together for effects processing */ virtual ObjToken allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId) = 0; /** Client can register for key callback events from the mixing engine this way */ virtual void setCallbackInterface(IAudioVoiceEngineCallback* cb) = 0; /** Client may use this to determine current speaker-setup */ virtual AudioChannelSet getAvailableSet() = 0; /** Ensure backing platform buffer is filled as much as possible with mixed samples */ virtual void pumpAndMixVoices() = 0; /** Set total volume of engine */ virtual void setVolume(float vol) = 0; /** Enable or disable Lt/Rt surround encoding. If successful, getAvailableSet() will return Surround51 */ virtual bool enableLtRt(bool enable) = 0; /** Get current Audio output in use */ virtual std::string getCurrentAudioOutput() const = 0; /** Set current Audio output to use */ virtual bool setCurrentAudioOutput(const char* name) = 0; /** Get list of Audio output devices found on system */ virtual std::vector> enumerateAudioOutputs() const = 0; /** Get list of MIDI input devices found on system */ virtual std::vector> enumerateMIDIInputs() const = 0; /** Query if system supports creating a virtual MIDI input */ virtual bool supportsVirtualMIDIIn() const = 0; /** Create ad-hoc MIDI in port and register with system */ virtual std::unique_ptr newVirtualMIDIIn(ReceiveFunctor&& receiver) = 0; /** Create ad-hoc MIDI out port and register with system */ virtual std::unique_ptr newVirtualMIDIOut() = 0; /** Create ad-hoc MIDI in/out port and register with system */ virtual std::unique_ptr newVirtualMIDIInOut(ReceiveFunctor&& receiver) = 0; /** Open named MIDI in port, name format depends on OS */ virtual std::unique_ptr newRealMIDIIn(const char* name, ReceiveFunctor&& receiver) = 0; /** Open named MIDI out port, name format depends on OS */ virtual std::unique_ptr newRealMIDIOut(const char* name) = 0; /** Open named MIDI in/out port, name format depends on OS */ virtual std::unique_ptr newRealMIDIInOut(const char* name, ReceiveFunctor&& receiver) = 0; /** If this returns true, MIDI callbacks are assumed to be *not* thread-safe; need protection via mutex */ virtual bool useMIDILock() const = 0; /** Get canonical count of frames for each 5ms output block */ virtual size_t get5MsFrames() const = 0; }; /** Construct host platform's voice engine */ std::unique_ptr NewAudioVoiceEngine(); /** Construct WAV-rendering voice engine */ std::unique_ptr NewWAVAudioVoiceEngine(const char* path, double sampleRate, int numChans); } // namespace boo