#ifndef SRC_AUDIO_AUDIO_H_ #define SRC_AUDIO_AUDIO_H_ #include #include #include #include #include #ifdef __APPLE__ #include #include #else #include #include #endif #include "../audio.h" #include "../../typedefs.h" namespace audio { struct ALBuffer; class ALAudio; class PCMStream; class ALSound : public Sound { ALAudio* al; uint buffer; std::shared_ptr pcm; duration_t duration; public: ALSound(ALAudio* al, uint buffer, std::shared_ptr pcm, bool keepPCM); ~ALSound(); duration_t getDuration() const override { return duration; } std::shared_ptr getPCM() const override { return pcm; } Speaker* newInstance(int priority, int channel) const override; }; class ALStream : public Stream { static inline constexpr size_t BUFFER_SIZE = 44100; ALAudio* al; std::shared_ptr source; std::queue unusedBuffers; speakerid_t speaker = 0; bool keepSource; char buffer[BUFFER_SIZE]; bool loop = false; bool preloadBuffer(uint buffer, bool loop); public: size_t totalPlayedSamples = 0; ALStream(ALAudio* al, std::shared_ptr source, bool keepSource); ~ALStream(); std::shared_ptr getSource() const override; void bindSpeaker(speakerid_t speaker) override; Speaker* createSpeaker(bool loop, int channel) override; speakerid_t getSpeaker() const override; void update(double delta) override; duration_t getTime() const override; void setTime(duration_t time) override; static inline constexpr uint STREAM_BUFFERS = 3; }; /// @brief AL source adapter class ALSpeaker : public Speaker { ALAudio* al; int priority; int channel; float volume = 0.0f; public: ALStream* stream = nullptr; bool stopped = true; bool paused = false; uint source; duration_t duration = 0.0f; ALSpeaker(ALAudio* al, uint source, int priority, int channel); ~ALSpeaker(); void update(const Channel* channel, float masterVolume) override; int getChannel() const override; State getState() const override; float getVolume() const override; void setVolume(float volume) override; float getPitch() const override; void setPitch(float pitch) override; bool isLoop() const override; void setLoop(bool loop) override; void play() override; void pause() override; void stop() override; duration_t getTime() const override; duration_t getDuration() const override; void setTime(duration_t time) override; void setPosition(glm::vec3 pos) override; glm::vec3 getPosition() const override; void setVelocity(glm::vec3 vel) override; glm::vec3 getVelocity() const override; void setRelative(bool relative) override; bool isRelative() const override; int getPriority() const override; }; class ALAudio : public Backend { ALCdevice* device; ALCcontext* context; std::vector allsources; std::vector freesources; std::vector allbuffers; std::vector freebuffers; uint maxSources; ALAudio(ALCdevice* device, ALCcontext* context); public: ~ALAudio(); uint getFreeSource(); uint getFreeBuffer(); void freeSource(uint source); void freeBuffer(uint buffer); std::vector getAvailableDevices() const; Sound* createSound(std::shared_ptr pcm, bool keepPCM) override; Stream* openStream(std::shared_ptr stream, bool keepSource) override; void setListener( glm::vec3 position, glm::vec3 velocity, glm::vec3 lookAt, glm::vec3 up ) override; void update(double delta) override; bool isDummy() const override { return false; } static ALAudio* create(); }; } #endif /* SRC_AUDIO_AUDIO_H_ */