#ifndef SRC_PCM_AUDIO #define SRC_PCM_AUDIO #include #include #include #include #include "struct/atomic_queue.h" #include "struct/message.h" #define FADE_IN_SPEED 0.00001 #define FADE_OUT_SPEED 0.0001 #define BUFFER_WAIT_COUNT 5 struct ChannelConfig { int rate; uint8_t channels; bool operator==(ChannelConfig const &other) const { return rate == other.rate && channels == other.channels; } bool operator!=(ChannelConfig const &other) const { return !(*this == other); } }; class PcmAudio { public: PcmAudio(const char *name = ""); ~PcmAudio(); // Start playing raw PCM data from queue void start(AtomicQueue *data, PcmAudio *fader = nullptr); void stop(); void Fade(bool enble); private: void runner(); void loop(SDL_AudioDeviceID device); void fadecpy(uint8_t *target, uint8_t *source, size_t len); static void callback(void *userdata, Uint8 *stream, int len); static ChannelConfig _configTable[]; static ChannelConfig getConfig(int type); AtomicQueue *_data; ChannelConfig _config; int _offset; PcmAudio *_fader; bool _fade; bool _faded; float _volume; float _fadeVolume; bool _underflow; int _underflowCount; int _lastCount; int _prefill; std::thread _thread; std::mutex _mtx; std::condition_variable _cv; std::atomic _paused{false}; std::atomic _active{false}; std::string _name; }; #endif /* SRC_PCM_AUDIO */