From 0211cae5a8192e1fdcbb7a65bb398178902e0121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Tue, 28 May 2013 17:39:23 -0300 Subject: [PATCH] Added a new example, it shows how to manage sounds and music. Changed ChannelsCount to ChannelCount, since it makes more sense. Now PlayOffset and Duration in sounds and music is returned in seconds, as float. --- .hgignore | 1 + include/eepp/audio/caudiodevice.hpp | 2 +- include/eepp/audio/cmusic.hpp | 2 +- include/eepp/audio/csound.hpp | 8 +-- include/eepp/audio/csoundbuffer.hpp | 12 ++-- include/eepp/audio/csoundstream.hpp | 17 +++-- include/eepp/audio/tsoundloader.hpp | 10 +-- include/eepp/audio/tsoundmanager.hpp | 11 ++-- include/eepp/ee.hpp | 2 +- premake4.lua | 21 ++++-- projects/linux/ee.creator.user | 97 ++++++++++++++++++++++++++-- projects/linux/ee.files | 1 + src/eepp/audio/caudiodevice.cpp | 4 +- src/eepp/audio/cmusic.cpp | 6 +- src/eepp/audio/csound.cpp | 9 +-- src/eepp/audio/csoundbuffer.cpp | 36 +++++------ src/eepp/audio/csoundfile.cpp | 28 ++++---- src/eepp/audio/csoundfile.hpp | 12 ++-- src/eepp/audio/csoundfiledefault.cpp | 20 +++--- src/eepp/audio/csoundfiledefault.hpp | 6 +- src/eepp/audio/csoundfileogg.cpp | 18 +++--- src/eepp/audio/csoundfileogg.hpp | 6 +- src/eepp/audio/csoundstream.cpp | 32 +++++---- src/examples/sound/sound.cpp | 71 ++++++++++++++++++++ 24 files changed, 309 insertions(+), 123 deletions(-) create mode 100644 src/examples/sound/sound.cpp diff --git a/.hgignore b/.hgignore index 6e00f898a..9934e9cfd 100644 --- a/.hgignore +++ b/.hgignore @@ -16,6 +16,7 @@ syntax: glob ./eees* ./eeew* ./eetest* +./eesound* ./docs ee.tag log.log diff --git a/include/eepp/audio/caudiodevice.hpp b/include/eepp/audio/caudiodevice.hpp index 71c75231c..8a5df5763 100755 --- a/include/eepp/audio/caudiodevice.hpp +++ b/include/eepp/audio/caudiodevice.hpp @@ -17,7 +17,7 @@ class EE_API cAudioDevice { ~cAudioDevice(); /** Get the OpenAL format that matches the given number of channels */ - static int GetFormatFromChannelsCount( unsigned int ChannelsCount ); + static int GetFormatFromChannelCount( unsigned int ChannelCount ); /** Checks if a AL or ALC extension is supported */ static bool IsExtensionSupported( const std::string& extension ); diff --git a/include/eepp/audio/cmusic.hpp b/include/eepp/audio/cmusic.hpp index 3f2f19652..93f6db371 100755 --- a/include/eepp/audio/cmusic.hpp +++ b/include/eepp/audio/cmusic.hpp @@ -25,7 +25,7 @@ class EE_API cMusic : public cSoundStream { /** Open a Music file from a file inside a pack file */ bool OpenFromPack( cPack * Pack, const std::string& FilePackPath ); - /** Get the Music Duration */ + /** Get the Music Duration in seconds */ float GetDuration() const; private : virtual bool OnStart(); diff --git a/include/eepp/audio/csound.hpp b/include/eepp/audio/csound.hpp index bc6ed06a2..d78c08952 100755 --- a/include/eepp/audio/csound.hpp +++ b/include/eepp/audio/csound.hpp @@ -87,13 +87,13 @@ class EE_API cSound { /** Get the Sound State */ Status State() const; - /** Get the current playing position of the sound */ - virtual Uint32 PlayingOffset() const; + /** Get the current playing position of the sound in seconds */ + virtual float PlayingOffset() const; /** Set the current playing position of the sound - * @param TimeOffset : New playing position, expressed in miliseconds + * @param TimeOffset : New playing position, expressed in seconds */ - virtual void PlayingOffset( const Uint32& TimeOffset ); + virtual void PlayingOffset( const float& TimeOffset ); /** Assignment operator */ cSound& operator =(const cSound& Other); diff --git a/include/eepp/audio/csoundbuffer.hpp b/include/eepp/audio/csoundbuffer.hpp index 6208e68df..f81be688a 100755 --- a/include/eepp/audio/csoundbuffer.hpp +++ b/include/eepp/audio/csoundbuffer.hpp @@ -28,7 +28,7 @@ class EE_API cSoundBuffer { bool LoadFromMemory( const char* Data, std::size_t SizeInBytes ); /** Load the Sound Buffer from an array of samples. Assumed format for samples is 16 bits signed integer */ - bool LoadFromSamples( const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate ); + bool LoadFromSamples( const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelCount, unsigned int SampleRate ); /** Save the Sound Buffer to a file */ bool SaveToFile( const std::string& Filename ) const; @@ -43,10 +43,10 @@ class EE_API cSoundBuffer { unsigned int GetSampleRate() const; /** Return the number of Channels */ - unsigned int GetChannelsCount() const; + unsigned int GetChannelCount() const; - /** Get the Sound Duration */ - Uint32 GetDuration() const; + /** Get the Sound Duration in seconds */ + float GetDuration() const; /** Assignment operator */ cSoundBuffer& operator =(const cSoundBuffer& Other); @@ -55,13 +55,13 @@ class EE_API cSoundBuffer { unsigned int mBuffer; ///< OpenAL buffer identifier std::vector mSamples; ///< Samples buffer - Uint32 mDuration; ///< Sound duration, in miliseconds + float mDuration; ///< Sound duration, in seconds typedef std::set SoundList; mutable SoundList mSounds; /** Update the internal buffer with the audio samples */ - bool Update( unsigned int ChannelsCount, unsigned int SampleRate ); + bool Update( unsigned int ChannelCount, unsigned int SampleRate ); void AttachSound( cSound* sound ) const; diff --git a/include/eepp/audio/csoundstream.hpp b/include/eepp/audio/csoundstream.hpp index 8a43fbf20..b350dde70 100755 --- a/include/eepp/audio/csoundstream.hpp +++ b/include/eepp/audio/csoundstream.hpp @@ -51,7 +51,7 @@ class EE_API cSoundStream : private cThread, private cSound { /** @brief Return the number of channels of the stream ** 1 channel means a mono sound, 2 means stereo, etc. ** @return Number of channels */ - unsigned int GetChannelsCount() const; + unsigned int GetChannelCount() const; /** @brief Get the stream sample rate of the stream ** The sample rate is the number of audio samples played per @@ -68,14 +68,13 @@ class EE_API cSoundStream : private cThread, private cSound { Status State() const ; /** @brief Get the current playing position of the stream - ** @return Current playing position, from the beginning of the stream. */ - Uint32 PlayingOffset() const; + ** @return Current playing position, from the beginning of the stream in seconds. */ + float PlayingOffset() const; /** @brief Change the current playing position of the stream - ** The playing position can be changed when the stream is - ** either paused or playing. - ** @param timeOffset New playing position, from the beginning of the stream */ - void PlayingOffset( const Uint32& timeOffset ); + ** The playing position can be changed when the stream is either paused or playing. + ** @param timeOffset New playing position, from the beginning of the stream ( in seconds ). */ + void PlayingOffset( const float &timeOffset ); /** Set the stream loop state. This parameter is disabled by default * @param Loop True to play in loop, false to play once @@ -90,7 +89,7 @@ class EE_API cSoundStream : private cThread, private cSound { protected: cSoundStream(); - void Initialize(unsigned int ChannelsCount, unsigned int SampleRate); + void Initialize(unsigned int ChannelCount, unsigned int SampleRate); private : virtual void Run(); @@ -117,7 +116,7 @@ class EE_API cSoundStream : private cThread, private cSound { bool mIsStreaming; ///< Streaming state (true = playing, false = stopped) unsigned int mBuffers[BuffersCount]; ///< Sound buffers used to store temporary audio data - unsigned int mChannelsCount; ///< Number of channels (1 = mono, 2 = stereo, ...) + unsigned int mChannelCount; ///< Number of channels (1 = mono, 2 = stereo, ...) unsigned int mSampleRate; ///< Frequency (samples / second) unsigned long mFormat; ///< Format of the internal sound buffers bool mLoop; ///< Loop flag (true to loop, false to play once) diff --git a/include/eepp/audio/tsoundloader.hpp b/include/eepp/audio/tsoundloader.hpp index a92340909..fc6cc6668 100644 --- a/include/eepp/audio/tsoundloader.hpp +++ b/include/eepp/audio/tsoundloader.hpp @@ -24,7 +24,7 @@ class tSoundLoader : public cObjectLoader { tSoundLoader( tSoundManager * SndMngr, const T& id, const char* Data, std::size_t SizeInBytes ); /** @brief Load the sound from an array of samples */ - tSoundLoader( tSoundManager * SndMngr, const T& id, const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate ); + tSoundLoader( tSoundManager * SndMngr, const T& id, const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelCount, unsigned int SampleRate ); /** @brief Load the sound from the Pack file */ tSoundLoader( tSoundManager * SndMngr, const T& id, cPack* Pack, const std::string& FilePackPath ); @@ -45,7 +45,7 @@ class tSoundLoader : public cObjectLoader { Uint32 mDataSize; const Int16 * mSamples; Uint32 mSamplesCount; - Uint32 mChannelsCount; + Uint32 mChannelCount; Uint32 mSampleRate; cPack * mPack; @@ -88,7 +88,7 @@ tSoundLoader::tSoundLoader( tSoundManager * SndMngr, const T& id, const Int16* Samples, std::size_t SamplesCount, - unsigned int ChannelsCount, + unsigned int ChannelCount, unsigned int SampleRate ) : cObjectLoader( cObjectLoader::SoundLoader ), mLoadType(SND_LT_SAMPLES), @@ -96,7 +96,7 @@ tSoundLoader::tSoundLoader( tSoundManager * SndMngr, mId(id), mSamples(Samples), mSamplesCount(SamplesCount), - mChannelsCount(ChannelsCount), + mChannelCount(ChannelCount), mSampleRate(SampleRate) { } @@ -153,7 +153,7 @@ void tSoundLoader::LoadFromPack() { template void tSoundLoader::LoadFromSamples() { - mSndMngr->LoadFromSamples( mId, mSamples, mSamplesCount, mChannelsCount, mSampleRate ); + mSndMngr->LoadFromSamples( mId, mSamples, mSamplesCount, mChannelCount, mSampleRate ); } template diff --git a/include/eepp/audio/tsoundmanager.hpp b/include/eepp/audio/tsoundmanager.hpp index 9c39984e0..c7ba9654d 100755 --- a/include/eepp/audio/tsoundmanager.hpp +++ b/include/eepp/audio/tsoundmanager.hpp @@ -27,9 +27,9 @@ class tSoundManager { ** @param id The sound id ** @param Samples Pointer to the array of samples in memory ** @param SamplesCount Number of samples in the array - ** @param ChannelsCount Number of channels (1 = mono, 2 = stereo, ...) + ** @param ChannelCount Number of channels (1 = mono, 2 = stereo, ...) ** @param SampleRate Sample rate (number of samples to play per second) */ - bool LoadFromSamples( const T& id, const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate ); + bool LoadFromSamples( const T& id, const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelCount, unsigned int SampleRate ); /** @brief Load the sound from a Pack file ** @param Pack The Pack file @@ -106,11 +106,11 @@ bool tSoundManager::LoadFromMemory( const T& id, const char* Data, std::size_ } template -bool tSoundManager::LoadFromSamples( const T& id, const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate ) { +bool tSoundManager::LoadFromSamples( const T& id, const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelCount, unsigned int SampleRate ) { if ( tSounds.find( id ) == tSounds.end() ) { // if id doesn't exists sSound * tSound = &tSounds[id]; - if ( tSound->Buf.LoadFromSamples( Samples, SamplesCount, ChannelsCount, SampleRate ) ) { + if ( tSound->Buf.LoadFromSamples( Samples, SamplesCount, ChannelCount, SampleRate ) ) { tSound->Snd.push_back( cSound( tSound->Buf ) ); return true; } @@ -123,6 +123,9 @@ template cSoundBuffer& tSoundManager::GetBuffer( const T& id ) { if ( tSounds.find( id ) != tSounds.end() ) return tSounds[id].Buf; + + static cSoundBuffer soundBuf; + return soundBuf; } template diff --git a/include/eepp/ee.hpp b/include/eepp/ee.hpp index 402070d36..0be94d76d 100755 --- a/include/eepp/ee.hpp +++ b/include/eepp/ee.hpp @@ -37,7 +37,7 @@ EE::Gaming Not documented at all. @TODO Add more commented examples, showing at least the basic usage of the engine ( 10 or more examples at least ). - STATE: 2 examples available. ( 20 % ) + STATE: 3 examples available. ( 30 % ) @TODO Improve the map editor ( add triggers, tiles selection to copy paste in other zones of the map, undo/redo actions ). STATE: Needs at least to reoffset tiles and objects for the map resizing. diff --git a/premake4.lua b/premake4.lua index 31a7ff1bf..306fa2635 100644 --- a/premake4.lua +++ b/premake4.lua @@ -99,7 +99,7 @@ newoption { trigger = "with-gles2", description = "Compile with GLES2 support" } newoption { trigger = "with-gles1", description = "Compile with GLES1 support" } newoption { trigger = "with-backend", - description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.\n\t\t\tIt's possible to build with more than one backend support.\n\t\t\t\tUse comma to separate the backends to build ( you can't mix SDL and SDL2, you'll get random crashes ).\n\t\t\t\tExample: --with-backend=SDL2,SFML2", + description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.\n\t\t\tIt's possible to build with more than one backend support.\n\t\t\t\tUse comma to separate the backends to build ( you can't mix SDL and SDL2, you'll get random crashes ).\n\t\t\t\tExample: --with-backend=SDL2,SFML", allowed = { { "SDL", "SDL 1.2" }, { "SDL2", "SDL2 (default and recommended)" }, @@ -257,7 +257,8 @@ function build_link_configuration( package_name ) elseif ( backend_is("allegro5") ) then links { get_backend_link_name( "allegro" ), "allegro_main" } elseif ( backend_is("SFML") ) then - links { get_backend_link_name( "SFML" ) } + links { get_backend_link_name( "sfml-system" ) } + links { get_backend_link_name( "sfml-window" ) } end else if ( os.is_real("macosx") ) then @@ -267,6 +268,9 @@ function build_link_configuration( package_name ) links { "SDL2main" } elseif ( backend_is("allegro5") ) then links { "allegro_main" } + elseif ( backend_is("SFML") ) then + links { get_backend_link_name( "sfml-system" ) } + links { get_backend_link_name( "sfml-window" ) } end end end @@ -416,9 +420,11 @@ function add_sfml() defines { "EE_BACKEND_SFML_ACTIVE" } if not can_add_static_backend("SFML") then - table.insert( link_list, get_backend_link_name( "SFML" ) ) + table.insert( link_list, get_backend_link_name( "sfml-system" ) ) + table.insert( link_list, get_backend_link_name( "sfml-window" ) ) else - insert_static_backend( "SFML" ) + insert_static_backend( "libsfml-system" ) + insert_static_backend( "libsfml-window" ) end end @@ -700,6 +706,7 @@ solution "eepp" files { "src/test/*.cpp" } build_link_configuration( "eetest" ) + -- Examples project "eepp-es" kind "WindowedApp" language "C++" @@ -711,3 +718,9 @@ solution "eepp" language "C++" files { "src/examples/empty_window/*.cpp" } build_link_configuration( "eeew" ) + + project "eepp-sound" + kind "WindowedApp" + language "C++" + files { "src/examples/sound/*.cpp" } + build_link_configuration( "eesound" ) diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 392177310..95016bdf3 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget @@ -48,9 +48,9 @@ Desktop Desktop {388e5431-b31b-42b3-b9ad-9002d279d75d} - 0 + 14 0 - 0 + 6 /home/programming/eepp/make/linux @@ -309,6 +309,46 @@ release-win-all GenericProjectManager.GenericBuildConfiguration + + /home/programming/eepp/make/linux + + + + false + -j4 eepp-sound + make + true + Make + + GenericProjectManager.GenericMakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + clean + make + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + debug-test + debug-sound + GenericProjectManager.GenericBuildConfiguration + /home/programming/eepp/make/linux @@ -629,7 +669,7 @@ release-es GenericProjectManager.GenericBuildConfiguration - 14 + 15 0 @@ -926,7 +966,54 @@ false true - 6 + + true + + false + false + false + false + true + 0.01 + 10 + true + 25 + + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 2 + /home/programming/eepp/eesound-debug + false + + %{buildDir} + Run /home/programming/eepp/eesound-debug + eesound-debug + ProjectExplorer.CustomExecutableRunConfiguration + 3768 + true + false + false + true + + 7 diff --git a/projects/linux/ee.files b/projects/linux/ee.files index defabaee0..ac1148f94 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -608,3 +608,4 @@ ../../src/eepp/audio/csoundfile.hpp ../../src/eepp/audio/openal.hpp ../../src/eepp/window/backend/SDL2/cbackendsdl2.cpp +../../src/examples/sound/sound.cpp diff --git a/src/eepp/audio/caudiodevice.cpp b/src/eepp/audio/caudiodevice.cpp index b8e3a75e4..f4abe9074 100755 --- a/src/eepp/audio/caudiodevice.cpp +++ b/src/eepp/audio/caudiodevice.cpp @@ -78,10 +78,10 @@ bool cAudioDevice::IsExtensionSupported( const std::string& extension ) { return alIsExtensionPresent( extension.c_str() ) != AL_FALSE; } -int cAudioDevice::GetFormatFromChannelsCount( unsigned int ChannelsCount ) { +int cAudioDevice::GetFormatFromChannelCount( unsigned int ChannelCount ) { EnsureALInit(); - switch ( ChannelsCount ) { + switch ( ChannelCount ) { case 1 : return AL_FORMAT_MONO16; case 2 : return AL_FORMAT_STEREO16; case 4 : return alGetEnumValue("AL_FORMAT_QUAD16"); diff --git a/src/eepp/audio/cmusic.cpp b/src/eepp/audio/cmusic.cpp index f4a1edf0b..265ccd81b 100755 --- a/src/eepp/audio/cmusic.cpp +++ b/src/eepp/audio/cmusic.cpp @@ -50,10 +50,10 @@ bool cMusic::OpenFromFile( const std::string& Filename ) { } // Compute the duration - mDuration = static_cast( mFile->GetSamplesCount() ) / mFile->GetSampleRate() / mFile->GetChannelsCount(); + mDuration = static_cast( mFile->GetSamplesCount() ) / mFile->GetSampleRate() / mFile->GetChannelCount(); // Initialize the stream - Initialize( mFile->GetChannelsCount(), mFile->GetSampleRate() ); + Initialize( mFile->GetChannelCount(), mFile->GetSampleRate() ); cLog::instance()->Write( "Music file " + Filename + " loaded." ); @@ -74,7 +74,7 @@ bool cMusic::OpenFromMemory( const char * Data, std::size_t SizeInBytes ) { mDuration = static_cast( mFile->GetSamplesCount() ) / mFile->GetSampleRate(); // Compute the duration - Initialize( mFile->GetChannelsCount(), mFile->GetSampleRate() ); // Initialize the stream + Initialize( mFile->GetChannelCount(), mFile->GetSampleRate() ); // Initialize the stream cLog::instance()->Write( "Music file loaded from memory." ); diff --git a/src/eepp/audio/csound.cpp b/src/eepp/audio/csound.cpp index 8fc386275..d3394717d 100755 --- a/src/eepp/audio/csound.cpp +++ b/src/eepp/audio/csound.cpp @@ -164,15 +164,16 @@ cSound::Status cSound::GetState() const { return cSound::Stopped; } -Uint32 cSound::PlayingOffset() const { +float cSound::PlayingOffset() const { float Seconds = 0.f; + ALCheck( alGetSourcef( mSource, AL_SEC_OFFSET, &Seconds ) ); - return static_cast ( Seconds * 1000 ); + return Seconds; } -void cSound::PlayingOffset( const Uint32& TimeOffset ) { - ALCheck( alSourcef( mSource, AL_SEC_OFFSET, TimeOffset / 1000.f ) ); +void cSound::PlayingOffset( const float &TimeOffset ) { + ALCheck( alSourcef( mSource, AL_SEC_OFFSET, TimeOffset ) ); } cSound& cSound::operator =( const cSound& Other ) { diff --git a/src/eepp/audio/csoundbuffer.cpp b/src/eepp/audio/csoundbuffer.cpp index 99bb61cdf..1a1419bfb 100755 --- a/src/eepp/audio/csoundbuffer.cpp +++ b/src/eepp/audio/csoundbuffer.cpp @@ -26,7 +26,7 @@ cSoundBuffer::cSoundBuffer(const cSoundBuffer& Copy) : EnsureALInit(); ALCheck( alGenBuffers( 1, &mBuffer ) ); - Update( Copy.GetChannelsCount(), Copy.GetSampleRate() ); + Update( Copy.GetChannelCount(), Copy.GetSampleRate() ); } cSoundBuffer::~cSoundBuffer() { @@ -60,7 +60,7 @@ bool cSoundBuffer::LoadFromFile(const std::string& Filename) { if ( NULL != File ) { // Get the sound parameters std::size_t NbSamples = File->GetSamplesCount(); - unsigned int ChannelsCount = File->GetChannelsCount(); + unsigned int ChannelCount = File->GetChannelCount(); unsigned int SampleRate = File->GetSampleRate(); // Read the samples from the opened file @@ -72,7 +72,7 @@ bool cSoundBuffer::LoadFromFile(const std::string& Filename) { // Update the internal buffer with the new samples eeDelete( File ); - return Update( ChannelsCount, SampleRate ); + return Update( ChannelCount, SampleRate ); } else { cLog::instance()->Write( "Failed to read audio data from file \"" + Filename + "\"" ); @@ -105,7 +105,7 @@ bool cSoundBuffer::LoadFromMemory( const char* Data, std::size_t SizeInBytes ) { if ( NULL != File ) { // Get the sound parameters std::size_t NbSamples = File->GetSamplesCount(); - unsigned int ChannelsCount = File->GetChannelsCount(); + unsigned int ChannelCount = File->GetChannelCount(); unsigned int SampleRate = File->GetSampleRate(); // Read the samples from the opened file @@ -117,7 +117,7 @@ bool cSoundBuffer::LoadFromMemory( const char* Data, std::size_t SizeInBytes ) { // Update the internal buffer with the new samples eeDelete( File ); - return Update( ChannelsCount, SampleRate ); + return Update( ChannelCount, SampleRate ); } else { cLog::instance()->Write( "Failed to read audio data from file in memory" ); @@ -131,15 +131,15 @@ bool cSoundBuffer::LoadFromMemory( const char* Data, std::size_t SizeInBytes ) { } } -bool cSoundBuffer::LoadFromSamples( const Int16 * Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate ) { - if ( Samples && SamplesCount && ChannelsCount && SampleRate ) { +bool cSoundBuffer::LoadFromSamples( const Int16 * Samples, std::size_t SamplesCount, unsigned int ChannelCount, unsigned int SampleRate ) { + if ( Samples && SamplesCount && ChannelCount && SampleRate ) { // Copy the new audio samples mSamples.assign( Samples, Samples + SamplesCount ); cLog::instance()->Write( "Sound file loaded from memory samples." ); // Update the internal buffer with the new samples - return Update( ChannelsCount, SampleRate ); + return Update( ChannelCount, SampleRate ); } else { // Error... cLog::instance()->Write( "Failed to load sound buffer from memory Samples" ); @@ -149,7 +149,7 @@ bool cSoundBuffer::LoadFromSamples( const Int16 * Samples, std::size_t SamplesCo bool cSoundBuffer::SaveToFile(const std::string& Filename) const { // Create the sound file in write mode - std::auto_ptr File( cSoundFile::CreateWrite( Filename, GetChannelsCount(), GetSampleRate() ) ); + std::auto_ptr File( cSoundFile::CreateWrite( Filename, GetChannelCount(), GetSampleRate() ) ); if ( File.get() ) { // Write the samples to the opened file @@ -176,13 +176,13 @@ unsigned int cSoundBuffer::GetSampleRate() const { return SampleRate; } -unsigned int cSoundBuffer::GetChannelsCount() const { - ALint ChannelsCount; - ALCheck( alGetBufferi( mBuffer, AL_CHANNELS, &ChannelsCount ) ); - return ChannelsCount; +unsigned int cSoundBuffer::GetChannelCount() const { + ALint ChannelCount; + ALCheck( alGetBufferi( mBuffer, AL_CHANNELS, &ChannelCount ) ); + return ChannelCount; } -Uint32 cSoundBuffer::GetDuration() const { +float cSoundBuffer::GetDuration() const { return mDuration; } @@ -197,13 +197,13 @@ cSoundBuffer& cSoundBuffer::operator =( const cSoundBuffer& Other ) { return *this; } -bool cSoundBuffer::Update( unsigned int ChannelsCount, unsigned int SampleRate ) { +bool cSoundBuffer::Update( unsigned int ChannelCount, unsigned int SampleRate ) { // Check parameters - if ( !SampleRate || !ChannelsCount || mSamples.empty() ) + if ( !SampleRate || !ChannelCount || mSamples.empty() ) return false; // Find the good format according to the number of channels - ALenum Format = cAudioDevice::GetFormatFromChannelsCount( ChannelsCount ); + ALenum Format = cAudioDevice::GetFormatFromChannelCount( ChannelCount ); // Check if the format is valid if ( Format == 0 ) { @@ -216,7 +216,7 @@ bool cSoundBuffer::Update( unsigned int ChannelsCount, unsigned int SampleRate ) ALCheck( alBufferData( mBuffer, Format, &mSamples[0], Size, SampleRate ) ); // Compute the duration - mDuration = static_cast( 1000 * mSamples.size() ) / SampleRate / ChannelsCount; + mDuration = (float)mSamples.size() / (float)SampleRate / (float)ChannelCount; return true; } diff --git a/src/eepp/audio/csoundfile.cpp b/src/eepp/audio/csoundfile.cpp index e2a484e3f..e47f39003 100755 --- a/src/eepp/audio/csoundfile.cpp +++ b/src/eepp/audio/csoundfile.cpp @@ -8,7 +8,7 @@ namespace EE { namespace Audio { cSoundFile::cSoundFile() : mNbSamples (0), - mChannelsCount(0), + mChannelCount(0), mSampleRate (0) { } @@ -29,15 +29,15 @@ cSoundFile * cSoundFile::CreateRead( const std::string& Filename ) { // Open it for reading if ( NULL != File ) { std::size_t SamplesCount; - unsigned int ChannelsCount; + unsigned int ChannelCount; unsigned int SampleRate; - if ( File->OpenRead( Filename, SamplesCount, ChannelsCount, SampleRate ) ) { + if ( File->OpenRead( Filename, SamplesCount, ChannelCount, SampleRate ) ) { File->mFilename = Filename; File->mData = NULL; File->mSize = 0; File->mNbSamples = SamplesCount; - File->mChannelsCount = ChannelsCount; + File->mChannelCount = ChannelCount; File->mSampleRate = SampleRate; } else { eeDelete( File ); @@ -60,15 +60,15 @@ cSoundFile * cSoundFile::CreateRead( const char* Data, std::size_t SizeInMemory // Open it for reading if ( NULL != File ) { std::size_t SamplesCount; - unsigned int ChannelsCount; + unsigned int ChannelCount; unsigned int SampleRate; - if ( File->OpenRead( Data, SizeInMemory, SamplesCount, ChannelsCount, SampleRate ) ) { + if ( File->OpenRead( Data, SizeInMemory, SamplesCount, ChannelCount, SampleRate ) ) { File->mFilename = ""; File->mData = Data; File->mSize = SizeInMemory; File->mNbSamples = SamplesCount; - File->mChannelsCount = ChannelsCount; + File->mChannelCount = ChannelCount; File->mSampleRate = SampleRate; } else { eeDelete( File ); @@ -79,7 +79,7 @@ cSoundFile * cSoundFile::CreateRead( const char* Data, std::size_t SizeInMemory return File; } -cSoundFile * cSoundFile::CreateWrite( const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate ) { +cSoundFile * cSoundFile::CreateWrite( const std::string& Filename, unsigned int ChannelCount, unsigned int SampleRate ) { // Create the file according to its type cSoundFile * File = NULL; @@ -90,12 +90,12 @@ cSoundFile * cSoundFile::CreateWrite( const std::string& Filename, unsigned int // Open it for writing if ( NULL != File ) { - if ( File->OpenWrite( Filename, ChannelsCount, SampleRate ) ) { + if ( File->OpenWrite( Filename, ChannelCount, SampleRate ) ) { File->mFilename = ""; File->mData = NULL; File->mSize = 0; File->mNbSamples = 0; - File->mChannelsCount = ChannelsCount; + File->mChannelCount = ChannelCount; File->mSampleRate = SampleRate; } else { eeDelete( File ); @@ -111,8 +111,8 @@ std::size_t cSoundFile::GetSamplesCount() const return mNbSamples; } -unsigned int cSoundFile::GetChannelsCount() const { - return mChannelsCount; +unsigned int cSoundFile::GetChannelCount() const { + return mChannelCount; } unsigned int cSoundFile::GetSampleRate() const { @@ -122,10 +122,10 @@ unsigned int cSoundFile::GetSampleRate() const { bool cSoundFile::Restart() { if ( mData ) { // Reopen from memory - return OpenRead( mData, mSize, mNbSamples, mChannelsCount, mSampleRate ); + return OpenRead( mData, mSize, mNbSamples, mChannelCount, mSampleRate ); } else if ( mFilename != "" ) { // Reopen from file - return OpenRead( mFilename, mNbSamples, mChannelsCount, mSampleRate ); + return OpenRead( mFilename, mNbSamples, mChannelCount, mSampleRate ); } else { cLog::instance()->Write( "Warning : trying to restart a sound opened in write mode, which is not allowed" ); return false; diff --git a/src/eepp/audio/csoundfile.hpp b/src/eepp/audio/csoundfile.hpp index d5ffdee48..fa0b3326a 100755 --- a/src/eepp/audio/csoundfile.hpp +++ b/src/eepp/audio/csoundfile.hpp @@ -15,7 +15,7 @@ class EE_API cSoundFile { static cSoundFile * CreateRead(const char* Data, std::size_t SizeInBytes); /** @brief Open a sound file for writing */ - static cSoundFile * CreateWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate); + static cSoundFile * CreateWrite(const std::string& Filename, unsigned int ChannelCount, unsigned int SampleRate); virtual ~cSoundFile(); @@ -25,7 +25,7 @@ class EE_API cSoundFile { /** @brief Get the number of channels used by the sound * @return Number of channels (1 = mono, 2 = stereo) */ - unsigned int GetChannelsCount() const; + unsigned int GetChannelCount() const; /** @brief Get the sample rate of the sound * @return Sample rate, in samples per second @@ -52,14 +52,14 @@ class EE_API cSoundFile { protected : cSoundFile(); - virtual bool OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate); + virtual bool OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate); - virtual bool OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate); + virtual bool OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate); - virtual bool OpenWrite(const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate); + virtual bool OpenWrite(const std::string& Filename, unsigned int ChannelCount, unsigned int SampleRate); std::size_t mNbSamples; - unsigned int mChannelsCount; + unsigned int mChannelCount; unsigned int mSampleRate; std::string mFilename; const char * mData; diff --git a/src/eepp/audio/csoundfiledefault.cpp b/src/eepp/audio/csoundfiledefault.cpp index d20db20a9..00bc74582 100755 --- a/src/eepp/audio/csoundfiledefault.cpp +++ b/src/eepp/audio/csoundfiledefault.cpp @@ -49,7 +49,7 @@ bool cSoundFileDefault::IsFileSupported( const char* Data, std::size_t SizeInByt return false; } -bool cSoundFileDefault::OpenRead( const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate ) { +bool cSoundFileDefault::OpenRead( const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate ) { // If the file is already opened, first close it if ( NULL != mFile ) sf_close( mFile ); @@ -64,18 +64,18 @@ bool cSoundFileDefault::OpenRead( const std::string& Filename, std::size_t& NbSa } // Set the sound parameters - mChannelsCount = fileInfos.channels; + mChannelCount = fileInfos.channels; mSampleRate = fileInfos.samplerate; - mNbSamples = static_cast(fileInfos.frames) * mChannelsCount; + mNbSamples = static_cast(fileInfos.frames) * mChannelCount; - ChannelsCount = mChannelsCount; + ChannelCount = mChannelCount; SampleRate = mSampleRate; NbSamples = mNbSamples; return true; } -bool cSoundFileDefault::OpenRead( const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate ) { +bool cSoundFileDefault::OpenRead( const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate ) { // If the file is already opened, first close it if ( NULL != mFile ) sf_close( mFile ); @@ -93,18 +93,18 @@ bool cSoundFileDefault::OpenRead( const char* Data, std::size_t SizeInBytes, std } // Set the sound parameters - mChannelsCount = fileInfos.channels; + mChannelCount = fileInfos.channels; mSampleRate = fileInfos.samplerate; - mNbSamples = static_cast(fileInfos.frames) * mChannelsCount; + mNbSamples = static_cast(fileInfos.frames) * mChannelCount; - ChannelsCount = mChannelsCount; + ChannelCount = mChannelCount; SampleRate = mSampleRate; NbSamples = mNbSamples; return true; } -bool cSoundFileDefault::OpenWrite( const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate ) { +bool cSoundFileDefault::OpenWrite( const std::string& Filename, unsigned int ChannelCount, unsigned int SampleRate ) { // If the file is already opened, first close it if ( NULL != mFile ) sf_close( mFile ); @@ -119,7 +119,7 @@ bool cSoundFileDefault::OpenWrite( const std::string& Filename, unsigned int Cha // Fill the sound infos with parameters SF_INFO fileInfos; - fileInfos.channels = ChannelsCount; + fileInfos.channels = ChannelCount; fileInfos.samplerate = SampleRate; fileInfos.format = Format | (Format == SF_FORMAT_OGG ? SF_FORMAT_VORBIS : SF_FORMAT_PCM_16); diff --git a/src/eepp/audio/csoundfiledefault.hpp b/src/eepp/audio/csoundfiledefault.hpp index af6db6656..7bc3eb833 100755 --- a/src/eepp/audio/csoundfiledefault.hpp +++ b/src/eepp/audio/csoundfiledefault.hpp @@ -28,11 +28,11 @@ class EE_API cSoundFileDefault : public cSoundFile { virtual void Seek( Uint32 timeOffset ); private : - virtual bool OpenRead( const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate ); + virtual bool OpenRead( const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate ); - virtual bool OpenRead( const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate ); + virtual bool OpenRead( const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate ); - virtual bool OpenWrite( const std::string& Filename, unsigned int ChannelsCount, unsigned int SampleRate ); + virtual bool OpenWrite( const std::string& Filename, unsigned int ChannelCount, unsigned int SampleRate ); static int GetFormatFromFilename(const std::string& Filename); diff --git a/src/eepp/audio/csoundfileogg.cpp b/src/eepp/audio/csoundfileogg.cpp index 6aac2fb8d..103bbc189 100755 --- a/src/eepp/audio/csoundfileogg.cpp +++ b/src/eepp/audio/csoundfileogg.cpp @@ -5,7 +5,7 @@ namespace EE { namespace Audio { cSoundFileOgg::cSoundFileOgg() : mStream (NULL), - mChannelsCount(0) + mChannelCount(0) { } @@ -42,7 +42,7 @@ bool cSoundFileOgg::IsFileSupported( const char* Data, std::size_t SizeInBytes ) return false; } -bool cSoundFileOgg::OpenRead( const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate ) { +bool cSoundFileOgg::OpenRead( const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate ) { // Close the file if already opened if ( NULL != mStream ) stb_vorbis_close( mStream ); @@ -57,14 +57,14 @@ bool cSoundFileOgg::OpenRead( const std::string& Filename, std::size_t& NbSample // Get the music parameters stb_vorbis_info Infos = stb_vorbis_get_info( mStream ); - ChannelsCount = mChannelsCount = Infos.channels; + ChannelCount = mChannelCount = Infos.channels; SampleRate = Infos.sample_rate; - NbSamples = static_cast( stb_vorbis_stream_length_in_samples( mStream ) * ChannelsCount ); + NbSamples = static_cast( stb_vorbis_stream_length_in_samples( mStream ) * ChannelCount ); return true; } -bool cSoundFileOgg::OpenRead( const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate ) { +bool cSoundFileOgg::OpenRead( const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate ) { // Close the file if already opened if ( NULL != mStream ) stb_vorbis_close( mStream ); @@ -82,18 +82,18 @@ bool cSoundFileOgg::OpenRead( const char* Data, std::size_t SizeInBytes, std::si // Get the music parameters stb_vorbis_info Infos = stb_vorbis_get_info( mStream ); - ChannelsCount = mChannelsCount = Infos.channels; + ChannelCount = mChannelCount = Infos.channels; SampleRate = Infos.sample_rate; - NbSamples = static_cast( stb_vorbis_stream_length_in_samples( mStream ) * ChannelsCount ); + NbSamples = static_cast( stb_vorbis_stream_length_in_samples( mStream ) * ChannelCount ); return true; } std::size_t cSoundFileOgg::Read( Int16 * Data, std::size_t NbSamples ) { if ( NULL != mStream && Data && NbSamples ) { - int Read = stb_vorbis_get_samples_short_interleaved( mStream, mChannelsCount, Data, static_cast( NbSamples ) ); + int Read = stb_vorbis_get_samples_short_interleaved( mStream, mChannelCount, Data, static_cast( NbSamples ) ); - std::size_t scount = Read * mChannelsCount; + std::size_t scount = Read * mChannelCount; return scount; } diff --git a/src/eepp/audio/csoundfileogg.hpp b/src/eepp/audio/csoundfileogg.hpp index a41ceaf23..d42b3b41b 100755 --- a/src/eepp/audio/csoundfileogg.hpp +++ b/src/eepp/audio/csoundfileogg.hpp @@ -23,12 +23,12 @@ class EE_API cSoundFileOgg : public cSoundFile { virtual void Seek( Uint32 timeOffset ); private : - virtual bool OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate); + virtual bool OpenRead(const std::string& Filename, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate); - virtual bool OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelsCount, unsigned int& SampleRate); + virtual bool OpenRead(const char* Data, std::size_t SizeInBytes, std::size_t& NbSamples, unsigned int& ChannelCount, unsigned int& SampleRate); stb_vorbis * mStream; ///< Vorbis stream - unsigned int mChannelsCount; ///< Number of channels (1 = mono, 2 = stereo) + unsigned int mChannelCount; ///< Number of channels (1 = mono, 2 = stereo) }; }} diff --git a/src/eepp/audio/csoundstream.cpp b/src/eepp/audio/csoundstream.cpp index 172ba503b..48b8a31f0 100755 --- a/src/eepp/audio/csoundstream.cpp +++ b/src/eepp/audio/csoundstream.cpp @@ -8,7 +8,7 @@ namespace EE { namespace Audio { cSoundStream::cSoundStream() : mIsStreaming(false), - mChannelsCount(0), + mChannelCount(0), mSampleRate (0), mFormat (0), mLoop(false), @@ -20,15 +20,15 @@ cSoundStream::~cSoundStream() { Stop(); // Stop the sound if it was playing } -void cSoundStream::Initialize(unsigned int ChannelsCount, unsigned int SampleRate) { - mChannelsCount = ChannelsCount; +void cSoundStream::Initialize(unsigned int ChannelCount, unsigned int SampleRate) { + mChannelCount = ChannelCount; mSampleRate = SampleRate; // Deduce the format from the number of channels - mFormat = cAudioDevice::GetFormatFromChannelsCount(ChannelsCount); + mFormat = cAudioDevice::GetFormatFromChannelCount(ChannelCount); if ( mFormat == 0 ) { // Check if the format is valid - mChannelsCount = 0; + mChannelCount = 0; mSampleRate = 0; cLog::instance()->Write( "Unsupported number of channels." ); } @@ -61,8 +61,8 @@ void cSoundStream::Stop() { Wait(); } -unsigned int cSoundStream::GetChannelsCount() const { - return mChannelsCount; +unsigned int cSoundStream::GetChannelCount() const { + return mChannelCount; } unsigned int cSoundStream::GetSampleRate() const { @@ -78,11 +78,21 @@ cSound::Status cSoundStream::GetState() const { return status; } -Uint32 cSoundStream::PlayingOffset() const { - return static_cast( cSound::PlayingOffset() ) * 1000 + 1000 * mSamplesProcessed / mSampleRate / mChannelsCount; +float cSoundStream::PlayingOffset() const { + //return static_cast( cSound::PlayingOffset() ) * 1000 + 1000 * mSamplesProcessed / mSampleRate / mChannelCount; + + if ( mSampleRate && mChannelCount ) { + float secs = 0.f; + + ALCheck( alGetSourcef( mSource, AL_SEC_OFFSET, &secs ) ); + + return secs + (float)mSamplesProcessed / (float)mSampleRate / (float)mChannelCount; + } else { + return 0; + } } -void cSoundStream::PlayingOffset( const Uint32& timeOffset ) { +void cSoundStream::PlayingOffset(const float &timeOffset ) { // Stop the stream Stop(); @@ -90,7 +100,7 @@ void cSoundStream::PlayingOffset( const Uint32& timeOffset ) { OnSeek( timeOffset ); // Restart streaming - mSamplesProcessed = static_cast( timeOffset ) * mSampleRate * mChannelsCount / 1000; + mSamplesProcessed = static_cast( timeOffset ) * mSampleRate * mChannelCount; mIsStreaming = true; diff --git a/src/examples/sound/sound.cpp b/src/examples/sound/sound.cpp new file mode 100644 index 000000000..08a548603 --- /dev/null +++ b/src/examples/sound/sound.cpp @@ -0,0 +1,71 @@ +#include + +// Get the process path to be used to load the sounds ( it is safer ) +std::string AppPath = Sys::GetProcessPath(); + +/// Play a sound +void playSound() { + // The sound manager class simplyfies the load of a SoundBuffer and the creation of the Sound + // It manages the sound playing, if the sound channel is already playing, it will open a new channel to play the sound + cSoundManager SoundManager; + + if ( SoundManager.LoadFromFile( "sound", AppPath + "assets/sounds/sound.ogg" ) ) { + // Get the sound buffer to display the buffer information + cSoundBuffer& buffer = SoundManager.GetBuffer( "sound" ); + + // Display sound informations + std::cout << "sound.ogg :" << std::endl; + std::cout << " " << buffer.GetDuration() << " seconds" << std::endl; + std::cout << " " << buffer.GetSampleRate() << " samples / sec" << std::endl; + std::cout << " " << buffer.GetChannelCount() << " channels" << std::endl; + + // Play the sound + SoundManager.Play( "sound" ); + } +} + +/// Play a music +void playMusic() { + // Load an ogg music file + cMusic music; + + if (!music.OpenFromFile( AppPath + "assets/sounds/music.ogg" ) ) + return; + + // Display music informations + std::cout << "music.ogg :" << std::endl; + std::cout << " " << music.GetDuration() << " seconds" << std::endl; + std::cout << " " << music.GetSampleRate() << " samples / sec" << std::endl; + std::cout << " " << music.GetChannelCount() << " channels" << std::endl; + + // Play it + music.Play(); + + // Loop while the music is playing + while ( music.State() == cSound::Playing ) { + // Leave some CPU time for other processes + Sys::Sleep( 100 ); + + // Display the playing position + std::cout << "\rPlaying... " << music.PlayingOffset() << " sec "; + std::cout << std::flush; + } + + std::cout << std::endl; +} + +/// Entry point of application +EE_MAIN_FUNC int main (int argc, char * argv []) +{ + // Play a sound + playSound(); + + // Play a music + playMusic(); + + // Wait until the user presses 'enter' key + std::cout << "Press enter to exit..." << std::endl; + std::cin.ignore(10000, '\n'); + + return EXIT_SUCCESS; +}