diff --git a/include/eepp/audio.hpp b/include/eepp/audio.hpp index c268961ff..f8c02d48c 100644 --- a/include/eepp/audio.hpp +++ b/include/eepp/audio.hpp @@ -1,12 +1,21 @@ #ifndef EEPP_AUDIO_HPP #define EEPP_AUDIO_HPP -#include -#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include #include -#include + #include #include diff --git a/include/eepp/audio/README b/include/eepp/audio/README new file mode 100644 index 000000000..f71eeba69 --- /dev/null +++ b/include/eepp/audio/README @@ -0,0 +1,22 @@ + +This module is an adaptation of the sfml-audio module. + +SFML - Simple and Fast Multimedia Library +Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org) + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/include/eepp/audio/alresource.hpp b/include/eepp/audio/alresource.hpp new file mode 100644 index 000000000..cd8f1e66a --- /dev/null +++ b/include/eepp/audio/alresource.hpp @@ -0,0 +1,17 @@ +#ifndef EE_AUDIO_ALRESOURCE_HPP +#define EE_AUDIO_ALRESOURCE_HPP + +#include + +namespace EE { namespace Audio { + +class EE_API AlResource { + protected: + AlResource(); + + ~AlResource(); +}; + +}} + +#endif diff --git a/include/eepp/audio/audiodevice.hpp b/include/eepp/audio/audiodevice.hpp deleted file mode 100755 index 7a28fd6a2..000000000 --- a/include/eepp/audio/audiodevice.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef EE_AUDIOCAUDIODEVICE_H -#define EE_AUDIOCAUDIODEVICE_H - -#include -#include - -namespace EE { namespace Audio { - -/** - @brief High-level wrapper around the audio API, it manages - the creation and destruction of the audio device and - context and stores the device capabilities -*/ -class EE_API AudioDevice { - public : - AudioDevice(); - - ~AudioDevice(); - - /** Get the OpenAL format that matches the given number of channels */ - static int getFormatFromChannelCount( unsigned int ChannelCount ); - - /** Checks if a AL or ALC extension is supported */ - static bool isExtensionSupported( const std::string& extension ); - - /** @return True if the audio device was initialized */ - static bool isAvailable(); - private : - void printInfo(); -}; - -}} - -#endif diff --git a/include/eepp/audio/audiolistener.hpp b/include/eepp/audio/audiolistener.hpp deleted file mode 100755 index 18219115f..000000000 --- a/include/eepp/audio/audiolistener.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef EE_AUDIOCLISTENER_H -#define EE_AUDIOCLISTENER_H - -#include -using namespace EE::Math; - -namespace EE { namespace Audio { - -/** @brief Listener is a global interface for defining the audio listener properties. */ -class EE_API AudioListener { - public: - /** Change the global volume of all the sounds. ( default 100 ) - * @param Volume New global volume, in the range [0, 100] - */ - static void setGlobalVolume( const float& Volume ); - - /** Get the Global Volume */ - static float getGlobalVolume(); - - /** Change the position of the listener. \n The default position is (0, 0, 0) */ - static void setPosition( const float& X, const float& Y, const float& Z ); - - /** Change the position of the listener from a 3D vector. */ - static void setPosition(const Vector3ff& setPosition); - - /** Get the current position of the listener */ - static Vector3ff getPosition(); - - /** Change the orientation of the listener (the point he must look at). \n The default target is (0, 0, -1). */ - static void setDirection( const float& X, const float& Y, const float& Z ); - - /** Change the orientation of the listener from a 3D vector. */ - static void setDirection(const Vector3ff& setDirection); - - /** Get the current orientation of the listener (the point he's looking at) */ - static Vector3ff getDirection(); -}; - -}} - -#endif diff --git a/include/eepp/audio/base.hpp b/include/eepp/audio/base.hpp deleted file mode 100644 index 568f690cf..000000000 --- a/include/eepp/audio/base.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef EE_AUDIO_BASE -#define EE_AUDIO_BASE - -#include - -/** -This module is based on the sfml-audio module. - -SFML - Copyright (c) 2007-2009 Laurent Gomila - laurent.gom@gmail.com - -This software is provided 'as-is', without any express or -implied warranty. In no event will the authors be held -liable for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute -it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; - you must not claim that you wrote the original software. - If you use this software in a product, an acknowledgment - in the product documentation would be appreciated but - is not required. - -2. Altered source versions must be plainly marked as such, - and must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any - source distribution. -*/ -#endif diff --git a/include/eepp/audio/inputsoundfile.hpp b/include/eepp/audio/inputsoundfile.hpp new file mode 100644 index 000000000..abd97d808 --- /dev/null +++ b/include/eepp/audio/inputsoundfile.hpp @@ -0,0 +1,226 @@ +#ifndef EE_AUDIO_INPUTSOUNDFILE_HPP +#define EE_AUDIO_INPUTSOUNDFILE_HPP + +#include +#include +#include +#include +#include + +namespace EE { namespace System { +class IOStream; +}} + +using namespace EE::System; + +namespace EE { namespace Audio { + +class SoundFileReader; + +/// \brief Provide read access to sound files +class EE_API InputSoundFile : NonCopyable { + public: + + InputSoundFile(); + + ~InputSoundFile(); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from the disk for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param filename Path of the sound file to load + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + bool openFromFile(const std::string& filename); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file in memory for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + bool openFromMemory(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from a custom stream for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param stream Source stream to read from + /// + /// \return True if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + bool openFromStream(IOStream& stream); + + //////////////////////////////////////////////////////////// + /// \brief Get the total number of audio samples in the file + /// + /// \return Number of samples + /// + //////////////////////////////////////////////////////////// + Uint64 getSampleCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the number of channels used by the sound + /// + /// \return Number of channels (1 = mono, 2 = stereo) + /// + //////////////////////////////////////////////////////////// + unsigned int getChannelCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the sample rate of the sound + /// + /// \return Sample rate, in samples per second + /// + //////////////////////////////////////////////////////////// + unsigned int getSampleRate() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the total duration of the sound file + /// + /// This function is provided for convenience, the duration is + /// deduced from the other sound file attributes. + /// + /// \return Duration of the sound file + /// + //////////////////////////////////////////////////////////// + Time getDuration() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in time + /// + /// \return Time position + /// + //////////////////////////////////////////////////////////// + Time getTimeOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in samples + /// + /// \return Sample position + /// + //////////////////////////////////////////////////////////// + Uint64 getSampleOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given sample offset + /// + /// This function takes a sample offset to provide maximum + /// precision. If you need to jump to a given time, use the + /// other overload. + /// + /// The sample offset takes the channels into account. + /// If you have a time offset instead, you can easily find + /// the corresponding sample offset with the following formula: + /// `timeInSeconds * sampleRate * channelCount` + /// If the given offset exceeds to total number of samples, + /// this function jumps to the end of the sound file. + /// + /// \param sampleOffset Index of the sample to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(Uint64 sampleOffset); + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given time offset + /// + /// Using a time offset is handy but imprecise. If you need an accurate + /// result, consider using the overload which takes a sample offset. + /// + /// If the given time exceeds to total duration, this function jumps + /// to the end of the sound file. + /// + /// \param timeOffset Time to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(Time timeOffset); + + //////////////////////////////////////////////////////////// + /// \brief Read audio samples from the open file + /// + /// \param samples Pointer to the sample array to fill + /// \param maxCount Maximum number of samples to read + /// + /// \return Number of samples actually read (may be less than \a maxCount) + /// + //////////////////////////////////////////////////////////// + Uint64 read(Int16* samples, Uint64 maxCount); + + private: + + //////////////////////////////////////////////////////////// + /// \brief Close the current file + /// + //////////////////////////////////////////////////////////// + void close(); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + SoundFileReader * mReader; ///< Reader that handles I/O on the file's format + IOStream* mStream; ///< Input stream used to access the file's data + bool mStreamOwned; ///< Is the stream internal or external? + Uint64 mSampleOffset; ///< Sample Read Position + Uint64 mSampleCount; ///< Total number of samples in the file + unsigned int mChannelCount; ///< Number of channels of the sound + unsigned int mSampleRate; ///< Number of samples per second +}; + +}} + +#endif + +//////////////////////////////////////////////////////////// +/// \class InputSoundFile +/// \ingroup audio +/// +/// This class decodes audio samples from a sound file. It is +/// used internally by higher-level classes such as SoundBuffer +/// and Music, but can also be useful if you want to process +/// or analyze audio files without playing them, or if you want to +/// implement your own version of Music with more specific +/// features. +/// +/// Usage example: +/// \code +/// // Open a sound file +/// InputSoundFile file; +/// if (!file.openFromFile("music.ogg")) +/// /* error */; +/// +/// // Print the sound attributes +/// std::cout << "duration: " << file.getDuration().asSeconds() << std::endl; +/// std::cout << "channels: " << file.getChannelCount() << std::endl; +/// std::cout << "sample rate: " << file.getSampleRate() << std::endl; +/// std::cout << "sample count: " << file.getSampleCount() << std::endl; +/// +/// // Read and process batches of samples until the end of file is reached +/// Int16 samples[1024]; +/// Uint64 count; +/// do +/// { +/// count = file.read(samples, 1024); +/// +/// // process, analyze, play, convert, or whatever +/// // you want to do with the samples... +/// } +/// while (count > 0); +/// \endcode +/// +/// \see SoundFileReader, OutputSoundFile +/// +//////////////////////////////////////////////////////////// diff --git a/include/eepp/audio/listener.hpp b/include/eepp/audio/listener.hpp new file mode 100644 index 000000000..d197dd101 --- /dev/null +++ b/include/eepp/audio/listener.hpp @@ -0,0 +1,201 @@ +#ifndef EE_AUDIO_LISTENER_HPP +#define EE_AUDIO_LISTENER_HPP + +#include +#include +using namespace EE::Math; + +namespace EE { namespace Audio { + +/// \brief The audio listener is the point in the scene +/// from where all the sounds are heard +class EE_API Listener { + public: + + //////////////////////////////////////////////////////////// + /// \brief Change the global volume of all the sounds and musics + /// + /// The volume is a number between 0 and 100; it is combined with + /// the individual volume of each sound / music. + /// The default value for the volume is 100 (maximum). + /// + /// \param volume New global volume, in the range [0, 100] + /// + /// \see getGlobalVolume + /// + //////////////////////////////////////////////////////////// + static void setGlobalVolume(float volume); + + //////////////////////////////////////////////////////////// + /// \brief Get the current value of the global volume + /// + /// \return Current global volume, in the range [0, 100] + /// + /// \see setGlobalVolume + /// + //////////////////////////////////////////////////////////// + static float getGlobalVolume(); + + //////////////////////////////////////////////////////////// + /// \brief Set the position of the listener in the scene + /// + /// The default listener's position is (0, 0, 0). + /// + /// \param x X coordinate of the listener's position + /// \param y Y coordinate of the listener's position + /// \param z Z coordinate of the listener's position + /// + /// \see getPosition, setDirection + /// + //////////////////////////////////////////////////////////// + static void setPosition(float x, float y, float z); + + //////////////////////////////////////////////////////////// + /// \brief Set the position of the listener in the scene + /// + /// The default listener's position is (0, 0, 0). + /// + /// \param position New listener's position + /// + /// \see getPosition, setDirection + /// + //////////////////////////////////////////////////////////// + static void setPosition(const Vector3f& position); + + //////////////////////////////////////////////////////////// + /// \brief Get the current position of the listener in the scene + /// + /// \return Listener's position + /// + /// \see setPosition + /// + //////////////////////////////////////////////////////////// + static Vector3f getPosition(); + + //////////////////////////////////////////////////////////// + /// \brief Set the forward vector of the listener in the scene + /// + /// The direction (also called "at vector") is the vector + /// pointing forward from the listener's perspective. Together + /// with the up vector, it defines the 3D orientation of the + /// listener in the scene. The direction vector doesn't + /// have to be normalized. + /// The default listener's direction is (0, 0, -1). + /// + /// \param x X coordinate of the listener's direction + /// \param y Y coordinate of the listener's direction + /// \param z Z coordinate of the listener's direction + /// + /// \see getDirection, setUpVector, setPosition + /// + //////////////////////////////////////////////////////////// + static void setDirection(float x, float y, float z); + + //////////////////////////////////////////////////////////// + /// \brief Set the forward vector of the listener in the scene + /// + /// The direction (also called "at vector") is the vector + /// pointing forward from the listener's perspective. Together + /// with the up vector, it defines the 3D orientation of the + /// listener in the scene. The direction vector doesn't + /// have to be normalized. + /// The default listener's direction is (0, 0, -1). + /// + /// \param direction New listener's direction + /// + /// \see getDirection, setUpVector, setPosition + /// + //////////////////////////////////////////////////////////// + static void setDirection(const Vector3f& direction); + + //////////////////////////////////////////////////////////// + /// \brief Get the current forward vector of the listener in the scene + /// + /// \return Listener's forward vector (not normalized) + /// + /// \see setDirection + /// + //////////////////////////////////////////////////////////// + static Vector3f getDirection(); + + //////////////////////////////////////////////////////////// + /// \brief Set the upward vector of the listener in the scene + /// + /// The up vector is the vector that points upward from the + /// listener's perspective. Together with the direction, it + /// defines the 3D orientation of the listener in the scene. + /// The up vector doesn't have to be normalized. + /// The default listener's up vector is (0, 1, 0). It is usually + /// not necessary to change it, especially in 2D scenarios. + /// + /// \param x X coordinate of the listener's up vector + /// \param y Y coordinate of the listener's up vector + /// \param z Z coordinate of the listener's up vector + /// + /// \see getUpVector, setDirection, setPosition + /// + //////////////////////////////////////////////////////////// + static void setUpVector(float x, float y, float z); + + //////////////////////////////////////////////////////////// + /// \brief Set the upward vector of the listener in the scene + /// + /// The up vector is the vector that points upward from the + /// listener's perspective. Together with the direction, it + /// defines the 3D orientation of the listener in the scene. + /// The up vector doesn't have to be normalized. + /// The default listener's up vector is (0, 1, 0). It is usually + /// not necessary to change it, especially in 2D scenarios. + /// + /// \param upVector New listener's up vector + /// + /// \see getUpVector, setDirection, setPosition + /// + //////////////////////////////////////////////////////////// + static void setUpVector(const Vector3f& upVector); + + //////////////////////////////////////////////////////////// + /// \brief Get the current upward vector of the listener in the scene + /// + /// \return Listener's upward vector (not normalized) + /// + /// \see setUpVector + /// + //////////////////////////////////////////////////////////// + static Vector3f getUpVector(); +}; + +}} + +#endif + +//////////////////////////////////////////////////////////// +/// \class Listener +/// \ingroup audio +/// +/// The audio listener defines the global properties of the +/// audio environment, it defines where and how sounds and musics +/// are heard. If View is the eyes of the user, then Listener +/// is his ears (by the way, they are often linked together -- +/// same position, orientation, etc.). +/// +/// Listener is a simple interface, which allows to setup the +/// listener in the 3D audio environment (position, direction and +/// up vector), and to adjust the global volume. +/// +/// Because the listener is unique in the scene, Listener only +/// contains static functions and doesn't have to be instantiated. +/// +/// Usage example: +/// \code +/// // Move the listener to the position (1, 0, -5) +/// Listener::setPosition(1, 0, -5); +/// +/// // Make it face the right axis (1, 0, 0) +/// Listener::setDirection(1, 0, 0); +/// +/// // Reduce the global volume +/// Listener::setGlobalVolume(50); +/// \endcode +/// +//////////////////////////////////////////////////////////// diff --git a/include/eepp/audio/music.hpp b/include/eepp/audio/music.hpp old mode 100755 new mode 100644 index 45a15de3e..0d8daf2e9 --- a/include/eepp/audio/music.hpp +++ b/include/eepp/audio/music.hpp @@ -1,45 +1,293 @@ -#ifndef EE_AUDIOCMUSIC_H -#define EE_AUDIOCMUSIC_H +#ifndef EE_AUDIO_MUSIC_HPP +#define EE_AUDIO_MUSIC_HPP -#include +#include #include +#include +#include +#include +#include +#include +#include + +namespace EE { namespace System { +class IOStream; +class Pack; +}} + +using namespace EE::System; namespace EE { namespace Audio { -class SoundFile; +/// \brief Streamed music played from an audio file +class EE_API Music : public SoundStream +{ + public: + /// \brief Structure defining a time range using the template type + template + struct Span + { + Span() + { -/** @brief Streamed music played from an audio file */ -class EE_API Music : public SoundStream { - public : - /** Construct the music with a buffer size */ - Music( std::size_t BufferSize = 48000 ); + } + + /// \brief Initialization constructor + /// \param off Initial Offset + /// \param len Initial Length + Span(T off, T len): + offset(off), + length(len) + { + + } + + T offset; ///< The beginning offset of the time range + T length; ///< The length of the time range + }; + + // Define the relevant Span types + typedef Span