diff --git a/CSFML/build/VC2005/csfml-audio-d.def b/CSFML/build/VC2005/csfml-audio-d.def index ebfb7f04e..1e7c9ba6f 100644 --- a/CSFML/build/VC2005/csfml-audio-d.def +++ b/CSFML/build/VC2005/csfml-audio-d.def @@ -24,6 +24,7 @@ EXPORTS sfMusic_SetRelativeToListener sfMusic_SetMinDistance sfMusic_SetAttenuation + sfMusic_SetPlayingOffset sfMusic_GetPitch sfMusic_GetVolume sfMusic_GetPosition @@ -91,6 +92,7 @@ EXPORTS sfSoundStream_SetRelativeToListener sfSoundStream_SetMinDistance sfSoundStream_SetAttenuation + sfSoundStream_SetPlayingOffset sfSoundStream_SetLoop sfSoundStream_GetPitch sfSoundStream_GetVolume diff --git a/CSFML/build/VC2005/csfml-audio.def b/CSFML/build/VC2005/csfml-audio.def index 3bf96b32d..b779a5abd 100644 --- a/CSFML/build/VC2005/csfml-audio.def +++ b/CSFML/build/VC2005/csfml-audio.def @@ -24,6 +24,7 @@ EXPORTS sfMusic_SetRelativeToListener sfMusic_SetMinDistance sfMusic_SetAttenuation + sfMusic_SetPlayingOffset sfMusic_GetPitch sfMusic_GetVolume sfMusic_GetPosition @@ -91,6 +92,7 @@ EXPORTS sfSoundStream_SetRelativeToListener sfSoundStream_SetMinDistance sfSoundStream_SetAttenuation + sfSoundStream_SetPlayingOffset sfSoundStream_SetLoop sfSoundStream_GetPitch sfSoundStream_GetVolume diff --git a/CSFML/build/VC2008/csfml-audio-d.def b/CSFML/build/VC2008/csfml-audio-d.def index ebfb7f04e..1e7c9ba6f 100644 --- a/CSFML/build/VC2008/csfml-audio-d.def +++ b/CSFML/build/VC2008/csfml-audio-d.def @@ -24,6 +24,7 @@ EXPORTS sfMusic_SetRelativeToListener sfMusic_SetMinDistance sfMusic_SetAttenuation + sfMusic_SetPlayingOffset sfMusic_GetPitch sfMusic_GetVolume sfMusic_GetPosition @@ -91,6 +92,7 @@ EXPORTS sfSoundStream_SetRelativeToListener sfSoundStream_SetMinDistance sfSoundStream_SetAttenuation + sfSoundStream_SetPlayingOffset sfSoundStream_SetLoop sfSoundStream_GetPitch sfSoundStream_GetVolume diff --git a/CSFML/build/VC2008/csfml-audio.def b/CSFML/build/VC2008/csfml-audio.def index 3bf96b32d..b779a5abd 100644 --- a/CSFML/build/VC2008/csfml-audio.def +++ b/CSFML/build/VC2008/csfml-audio.def @@ -24,6 +24,7 @@ EXPORTS sfMusic_SetRelativeToListener sfMusic_SetMinDistance sfMusic_SetAttenuation + sfMusic_SetPlayingOffset sfMusic_GetPitch sfMusic_GetVolume sfMusic_GetPosition @@ -91,6 +92,7 @@ EXPORTS sfSoundStream_SetRelativeToListener sfSoundStream_SetMinDistance sfSoundStream_SetAttenuation + sfSoundStream_SetPlayingOffset sfSoundStream_SetLoop sfSoundStream_GetPitch sfSoundStream_GetVolume diff --git a/CSFML/include/SFML/Audio/Music.h b/CSFML/include/SFML/Audio/Music.h index 1c79ba87d..cbf72749e 100644 --- a/CSFML/include/SFML/Audio/Music.h +++ b/CSFML/include/SFML/Audio/Music.h @@ -211,12 +211,21 @@ CSFML_API void sfMusic_SetMinDistance(sfMusic* Music, float MinDistance); /// more the sound will be attenuated with distance from listener. /// The default attenuation factor 1.0 /// -/// \param Sound : Sound to modify +/// \param Music : Music to modify /// \param Attenuation : New attenuation factor for the sound /// //////////////////////////////////////////////////////////// CSFML_API void sfMusic_SetAttenuation(sfMusic* Music, float Attenuation); +//////////////////////////////////////////////////////////// +/// Set the current playing position of a music +/// +/// \param Music : Music to modify +/// \param TimeOffset : New playing position, expressed in seconds +/// +//////////////////////////////////////////////////////////// +CSFML_API void sfMusic_SetPlayingOffset(sfMusic* Music, float TimeOffset); + //////////////////////////////////////////////////////////// /// Get the pitch of a music /// diff --git a/CSFML/include/SFML/Audio/SoundStream.h b/CSFML/include/SFML/Audio/SoundStream.h index 3142cfe34..cd0ac2a2f 100644 --- a/CSFML/include/SFML/Audio/SoundStream.h +++ b/CSFML/include/SFML/Audio/SoundStream.h @@ -43,15 +43,15 @@ typedef struct unsigned int NbSamples; ///< Number of samples pointed by Samples } sfSoundStreamChunk; -typedef sfBool (*sfSoundStreamStartCallback)(void*); ///< Type of the callback used to start a sound stream typedef sfBool (*sfSoundStreamGetDataCallback)(sfSoundStreamChunk*, void*); ///< Type of the callback used to get a sound stream data +typedef void (*sfSoundStreamSeekCallback)(float, void*); ///< Type of the callback used to seek in a sound stream //////////////////////////////////////////////////////////// /// Construct a new sound stream /// -/// \param OnStart : Function called when the stream starts (can be NULL) /// \param OnGetData : Function called when the stream needs more data (can't be NULL) +/// \param OnSeek : Function called when the stream seeks (can't be NULL) /// \param ChannelsCount : Number of channels to use (1 = mono, 2 = stereo) /// \param SampleRate : Sample rate of the sound (44100 = CD quality) /// \param UserData : Data to pass to the callback functions @@ -59,8 +59,8 @@ typedef sfBool (*sfSoundStreamGetDataCallback)(sfSoundStreamChunk*, void*); ///< /// \return A new sfSoundStream object (NULL if failed) /// //////////////////////////////////////////////////////////// -CSFML_API sfSoundStream* sfSoundStream_Create(sfSoundStreamStartCallback OnStart, - sfSoundStreamGetDataCallback OnGetData, +CSFML_API sfSoundStream* sfSoundStream_Create(sfSoundStreamGetDataCallback OnGetData, + sfSoundStreamSeekCallback OnSeek, unsigned int ChannelsCount, unsigned int SampleRate, void* UserData); @@ -190,6 +190,15 @@ CSFML_API void sfSoundStream_SetMinDistance(sfSoundStream* SoundStream, float Mi //////////////////////////////////////////////////////////// CSFML_API void sfSoundStream_SetAttenuation(sfSoundStream* SoundStream, float Attenuation); +//////////////////////////////////////////////////////////// +/// Set the current playing position of a stream +/// +/// \param SoundStream : Sound stream to modify +/// \param TimeOffset : New playing position, expressed in seconds +/// +//////////////////////////////////////////////////////////// +CSFML_API void sfSoundStream_SetPlayingOffset(sfSoundStream* SoundStream, float TimeOffset); + //////////////////////////////////////////////////////////// /// Set a stream loop state /// diff --git a/CSFML/src/SFML/Audio/Music.cpp b/CSFML/src/SFML/Audio/Music.cpp index 7a4d8682c..9c6d9a14f 100644 --- a/CSFML/src/SFML/Audio/Music.cpp +++ b/CSFML/src/SFML/Audio/Music.cpp @@ -231,6 +231,15 @@ void sfMusic_SetAttenuation(sfMusic* Music, float Attenuation) } +//////////////////////////////////////////////////////////// +/// Set the current playing position of a stream +//////////////////////////////////////////////////////////// +void sfMusic_SetPlayingOffset(sfMusic* Music, float TimeOffset) +{ + CSFML_CALL(Music, SetPlayingOffset(TimeOffset)); +} + + //////////////////////////////////////////////////////////// /// Get the pitch of a music //////////////////////////////////////////////////////////// diff --git a/CSFML/src/SFML/Audio/SoundStream.cpp b/CSFML/src/SFML/Audio/SoundStream.cpp index ed07bce65..e50cb047d 100644 --- a/CSFML/src/SFML/Audio/SoundStream.cpp +++ b/CSFML/src/SFML/Audio/SoundStream.cpp @@ -34,13 +34,13 @@ class sfSoundStreamImpl : public sf::SoundStream { public : - sfSoundStreamImpl(sfSoundStreamStartCallback OnStart, - sfSoundStreamGetDataCallback OnGetData, + sfSoundStreamImpl(sfSoundStreamGetDataCallback OnGetData, + sfSoundStreamSeekCallback OnSeek, unsigned int ChannelsCount, unsigned int SampleRate, void* UserData) : - myStartCallback (OnStart), myGetDataCallback(OnGetData), + mySeekCallback (OnSeek), myUserData (UserData) { Initialize(ChannelsCount, SampleRate); @@ -48,14 +48,6 @@ public : private : - virtual bool OnStart() - { - if (myStartCallback) - return myStartCallback(myUserData) == sfTrue; - else - return true; - } - virtual bool OnGetData(Chunk& Data) { sfSoundStreamChunk Chunk = {NULL, 0}; @@ -67,21 +59,26 @@ private : return Continue; } - sfSoundStreamStartCallback myStartCallback; + virtual void OnSeek(float TimeOffset) + { + if (mySeekCallback) + mySeekCallback(TimeOffset, myUserData); + } + sfSoundStreamGetDataCallback myGetDataCallback; + sfSoundStreamSeekCallback mySeekCallback; void* myUserData; }; struct sfSoundStream { - - sfSoundStream(sfSoundStreamStartCallback OnStart, - sfSoundStreamGetDataCallback OnGetData, + sfSoundStream(sfSoundStreamGetDataCallback OnGetData, + sfSoundStreamSeekCallback OnSeek, unsigned int ChannelsCount, unsigned int SampleRate, void* UserData) : - This(OnStart, OnGetData, ChannelsCount, SampleRate, UserData) + This(OnGetData, OnSeek, ChannelsCount, SampleRate, UserData) { } @@ -92,13 +89,13 @@ struct sfSoundStream //////////////////////////////////////////////////////////// /// Construct a new sound stream //////////////////////////////////////////////////////////// -sfSoundStream* sfSoundStream_Create(sfSoundStreamStartCallback OnStart, - sfSoundStreamGetDataCallback OnGetData, +sfSoundStream* sfSoundStream_Create(sfSoundStreamGetDataCallback OnGetData, + sfSoundStreamSeekCallback OnSeek, unsigned int ChannelsCount, unsigned int SampleRate, void* UserData) { - return new sfSoundStream(OnStart, OnGetData, ChannelsCount, SampleRate, UserData); + return new sfSoundStream(OnGetData, OnSeek, ChannelsCount, SampleRate, UserData); } @@ -228,6 +225,15 @@ void sfSoundStream_SetAttenuation(sfSoundStream* SoundStream, float Attenuation) } +//////////////////////////////////////////////////////////// +/// Set the current playing position of a stream +//////////////////////////////////////////////////////////// +void sfSoundStream_SetPlayingOffset(sfSoundStream* SoundStream, float TimeOffset) +{ + CSFML_CALL(SoundStream, SetPlayingOffset(TimeOffset)); +} + + //////////////////////////////////////////////////////////// /// Set a stream loop state //////////////////////////////////////////////////////////// diff --git a/dotnet/src/Audio/Music.cs b/dotnet/src/Audio/Music.cs index 41be7c6e1..ad6348aac 100644 --- a/dotnet/src/Audio/Music.cs +++ b/dotnet/src/Audio/Music.cs @@ -212,6 +212,7 @@ namespace SFML public float PlayingOffset { get {return sfMusic_GetPlayingOffset(This);} + set {sfMusic_SetPlayingOffset(This, value);} } //////////////////////////////////////////////////////////// @@ -276,6 +277,9 @@ namespace SFML [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] static extern void sfMusic_SetAttenuation(IntPtr Music, float Attenuation); + + [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] + static extern void sfMusic_SetPlayingOffset(IntPtr Music, float TimeOffset); [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] static extern bool sfMusic_GetLoop(IntPtr Music); diff --git a/dotnet/src/Audio/SoundStream.cs b/dotnet/src/Audio/SoundStream.cs index b0c4a8063..6a3debe0f 100644 --- a/dotnet/src/Audio/SoundStream.cs +++ b/dotnet/src/Audio/SoundStream.cs @@ -177,6 +177,7 @@ namespace SFML public float PlayingOffset { get {return sfSoundStream_GetPlayingOffset(This);} + set {sfSoundStream_SetPlayingOffset(This, value);} } //////////////////////////////////////////////////////////// @@ -188,21 +189,9 @@ namespace SFML //////////////////////////////////////////////////////////// protected void Initialize(uint channelsCount, uint sampleRate) { - myStartCallback = new StartCallbackType(Start); myGetDataCallback = new GetDataCallbackType(GetData); - SetThis(sfSoundStream_Create(myStartCallback, myGetDataCallback, channelsCount, sampleRate, IntPtr.Zero)); - } - - //////////////////////////////////////////////////////////// - /// - /// Virtual function called when the stream restarts - /// - /// If false is returned, the playback is aborted - //////////////////////////////////////////////////////////// - protected virtual bool OnStart() - { - // Does nothing by default - return true; + mySeekCallback = new SeekCallbackType(Seek); + SetThis(sfSoundStream_Create(myGetDataCallback, mySeekCallback, channelsCount, sampleRate, IntPtr.Zero)); } //////////////////////////////////////////////////////////// @@ -214,6 +203,14 @@ namespace SFML //////////////////////////////////////////////////////////// protected abstract bool OnGetData(out short[] samples); + //////////////////////////////////////////////////////////// + /// + /// Virtual function called to seek into the stream + /// + /// New position, expressed in seconds + //////////////////////////////////////////////////////////// + protected abstract void OnSeek(float timeOffset); + //////////////////////////////////////////////////////////// /// /// Handle the destruction of the object @@ -237,18 +234,6 @@ namespace SFML public uint samplesCount; } - //////////////////////////////////////////////////////////// - /// - /// Called when the stream restarts - /// - /// User data -- unused - /// If false is returned, the playback is aborted - //////////////////////////////////////////////////////////// - private bool Start(IntPtr userData) - { - return OnStart(); - } - //////////////////////////////////////////////////////////// /// /// Called each time new audio data is needed to feed the stream @@ -277,19 +262,33 @@ namespace SFML return false; } } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool StartCallbackType(IntPtr UserData); + + //////////////////////////////////////////////////////////// + /// + /// Called to seek in the stream + /// + /// New position, expressed in seconds + /// User data -- unused + /// If false is returned, the playback is aborted + //////////////////////////////////////////////////////////// + private void Seek(float timeOffset, IntPtr userData) + { + OnSeek(timeOffset); + } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool GetDataCallbackType(ref Chunk dataChunk, IntPtr UserData); - private StartCallbackType myStartCallback; + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void SeekCallbackType(float timeOffset, IntPtr UserData); + private GetDataCallbackType myGetDataCallback; + private SeekCallbackType mySeekCallback; private short[] myTempBuffer; #region Imports [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] - static extern IntPtr sfSoundStream_Create(StartCallbackType OnStart, GetDataCallbackType OnGetData, uint ChannelsCount, uint SampleRate, IntPtr UserData); + static extern IntPtr sfSoundStream_Create(GetDataCallbackType OnGetData, SeekCallbackType OnSeek, uint ChannelsCount, uint SampleRate, IntPtr UserData); [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] static extern void sfSoundStream_Destroy(IntPtr SoundStreamStream); @@ -332,6 +331,9 @@ namespace SFML [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] static extern void sfSoundStream_SetAttenuation(IntPtr SoundStream, float Attenuation); + + [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] + static extern void sfSoundStream_SetPlayingOffset(IntPtr SoundStream, float TimeOffset); [DllImport("csfml-audio"), SuppressUnmanagedCodeSecurity] static extern bool sfSoundStream_GetLoop(IntPtr SoundStream); diff --git a/include/SFML/Audio/Music.hpp b/include/SFML/Audio/Music.hpp index de74995c3..826a7f6ae 100644 --- a/include/SFML/Audio/Music.hpp +++ b/include/SFML/Audio/Music.hpp @@ -29,6 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include #include @@ -94,24 +95,25 @@ public : private : - //////////////////////////////////////////////////////////// - /// /see SoundStream::OnStart - /// - //////////////////////////////////////////////////////////// - virtual bool OnStart(); - //////////////////////////////////////////////////////////// /// /see SoundStream::OnGetData /// //////////////////////////////////////////////////////////// virtual bool OnGetData(Chunk& Data); + //////////////////////////////////////////////////////////// + /// /see SoundStream::OnSeek + /// + //////////////////////////////////////////////////////////// + virtual void OnSeek(float TimeOffset); + //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// priv::SoundFile* myFile; ///< Sound file float myDuration; ///< Music duration, in seconds std::vector mySamples; ///< Temporary buffer of samples + Mutex myMutex; ///< Mutex protecting the data }; } // namespace sf diff --git a/include/SFML/Audio/SoundStream.hpp b/include/SFML/Audio/SoundStream.hpp index 6df0c57bc..a5e79e00b 100644 --- a/include/SFML/Audio/SoundStream.hpp +++ b/include/SFML/Audio/SoundStream.hpp @@ -114,6 +114,14 @@ public : //////////////////////////////////////////////////////////// Status GetStatus() const; + //////////////////////////////////////////////////////////// + /// Set the current playing position of the stream + /// + /// \param TimeOffset : New playing position, expressed in seconds + /// + //////////////////////////////////////////////////////////// + void SetPlayingOffset(float TimeOffset); + //////////////////////////////////////////////////////////// /// Get the current playing position of the stream /// @@ -164,14 +172,6 @@ private : //////////////////////////////////////////////////////////// virtual void Run(); - //////////////////////////////////////////////////////////// - /// Called when the sound restarts - /// - /// \return If false is returned, the playback is aborted - /// - //////////////////////////////////////////////////////////// - virtual bool OnStart(); - //////////////////////////////////////////////////////////// /// Called each time new audio data is needed to feed the stream /// @@ -182,6 +182,14 @@ private : //////////////////////////////////////////////////////////// virtual bool OnGetData(Chunk& Data) = 0; + //////////////////////////////////////////////////////////// + /// Called to move the current reading position + /// + /// \param TimeOffset : New read position, expressed in seconds + /// + //////////////////////////////////////////////////////////// + virtual void OnSeek(float TimeOffset) = 0; + //////////////////////////////////////////////////////////// /// Fill a new buffer with audio data, and push it to the /// playing queue diff --git a/samples/voip/Server.cpp b/samples/voip/Server.cpp index 9a55a8ab6..6447d8cd4 100644 --- a/samples/voip/Server.cpp +++ b/samples/voip/Server.cpp @@ -76,18 +76,6 @@ public : private : - //////////////////////////////////////////////////////////// - /// /see SoundStream::OnStart - /// - //////////////////////////////////////////////////////////// - virtual bool OnStart() - { - // Reset the playing offset - myOffset = 0; - - return true; - } - //////////////////////////////////////////////////////////// /// /see SoundStream::OnGetData /// @@ -95,11 +83,11 @@ private : virtual bool OnGetData(sf::SoundStream::Chunk& Data) { // We have reached the end of the buffer and all audio data have been played : we can stop playback - if ((myOffset == mySamples.size()) && myHasFinished) + if ((myOffset >= mySamples.size()) && myHasFinished) return false; // No new data has arrived since last update : wait until we get some - while ((myOffset == mySamples.size()) && !myHasFinished) + while ((myOffset >= mySamples.size()) && !myHasFinished) sf::Sleep(0.01f); // Copy samples into a local buffer to avoid synchronization problems @@ -119,6 +107,15 @@ private : return true; } + //////////////////////////////////////////////////////////// + /// /see SoundStream::OnSeek + /// + //////////////////////////////////////////////////////////// + virtual void OnSeek(float TimeOffset) + { + myOffset = static_cast(TimeOffset * GetSampleRate() * GetChannelsCount()); + } + //////////////////////////////////////////////////////////// /// Get audio data from the client until playback is stopped /// diff --git a/src/SFML/Audio/Music.cpp b/src/SFML/Audio/Music.cpp index ef495d79a..ff769bdbe 100644 --- a/src/SFML/Audio/Music.cpp +++ b/src/SFML/Audio/Music.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -109,11 +110,11 @@ bool Music::OpenFromMemory(const char* Data, std::size_t SizeInBytes) //////////////////////////////////////////////////////////// -/// /see SoundStream::OnStart +/// Get the sound duration //////////////////////////////////////////////////////////// -bool Music::OnStart() +float Music::GetDuration() const { - return myFile && myFile->Restart(); + return myDuration; } @@ -122,28 +123,25 @@ bool Music::OnStart() //////////////////////////////////////////////////////////// bool Music::OnGetData(SoundStream::Chunk& Data) { - if (myFile) - { - // Fill the chunk parameters - Data.Samples = &mySamples[0]; - Data.NbSamples = myFile->Read(&mySamples[0], mySamples.size()); + sf::Lock Lock(myMutex); - // Check if we have reached the end of the audio file - return Data.NbSamples == mySamples.size(); - } - else - { - return false; - } + // Fill the chunk parameters + Data.Samples = &mySamples[0]; + Data.NbSamples = myFile->Read(&mySamples[0], mySamples.size()); + + // Check if we have reached the end of the audio file + return Data.NbSamples == mySamples.size(); } //////////////////////////////////////////////////////////// -/// Get the sound duration +/// /see SoundStream::OnSeek //////////////////////////////////////////////////////////// -float Music::GetDuration() const +void Music::OnSeek(float TimeOffset) { - return myDuration; + sf::Lock Lock(myMutex); + + myFile->Seek(TimeOffset); } } // namespace sf diff --git a/src/SFML/Audio/SoundFile.cpp b/src/SFML/Audio/SoundFile.cpp index c90ba7c5f..7432ae932 100644 --- a/src/SFML/Audio/SoundFile.cpp +++ b/src/SFML/Audio/SoundFile.cpp @@ -84,30 +84,6 @@ unsigned int SoundFile::GetSampleRate() const } -//////////////////////////////////////////////////////////// -/// Restart the sound from the beginning -//////////////////////////////////////////////////////////// -bool SoundFile::Restart() -{ - if (myData) - { - // Reopen from memory - return OpenRead(myData, mySize); - } - else if (myFilename != "") - { - // Reopen from file - return OpenRead(myFilename); - } - else - { - // Trying to reopen a file opened in write mode... error - std::cerr << "Warning : trying to restart a sound opened in write mode, which is not allowed" << std::endl; - return false; - } -} - - //////////////////////////////////////////////////////////// /// Open the sound file for reading //////////////////////////////////////////////////////////// @@ -130,9 +106,6 @@ bool SoundFile::OpenRead(const std::string& Filename) myChannelsCount = FileInfos.channels; mySampleRate = FileInfos.samplerate; myNbSamples = static_cast(FileInfos.frames) * myChannelsCount; - myFilename = Filename; - myData = NULL; - mySize = 0; return true; } @@ -173,9 +146,6 @@ bool SoundFile::OpenRead(const char* Data, std::size_t SizeInBytes) myChannelsCount = FileInfos.channels; mySampleRate = FileInfos.samplerate; myNbSamples = static_cast(FileInfos.frames) * myChannelsCount; - myFilename = ""; - myData = Data; - mySize = SizeInBytes; return true; } @@ -217,9 +187,6 @@ bool SoundFile::OpenWrite(const std::string& Filename, unsigned int ChannelsCoun myChannelsCount = ChannelsCount; mySampleRate = SampleRate; myNbSamples = 0; - myFilename = ""; - myData = NULL; - mySize = 0; return true; } @@ -257,6 +224,19 @@ void SoundFile::Write(const Int16* Data, std::size_t NbSamples) } +//////////////////////////////////////////////////////////// +/// Move the current reading position in the file +//////////////////////////////////////////////////////////// +void SoundFile::Seek(float TimeOffset) +{ + if (myFile) + { + sf_count_t FrameOffset = static_cast(TimeOffset * mySampleRate); + sf_seek(myFile, FrameOffset, SEEK_SET); + } +} + + //////////////////////////////////////////////////////////// /// Get the internal format of an audio file according to /// its filename extension diff --git a/src/SFML/Audio/SoundFile.hpp b/src/SFML/Audio/SoundFile.hpp index 81a2fd954..3d61fabe7 100644 --- a/src/SFML/Audio/SoundFile.hpp +++ b/src/SFML/Audio/SoundFile.hpp @@ -81,14 +81,6 @@ public : //////////////////////////////////////////////////////////// unsigned int GetSampleRate() const; - //////////////////////////////////////////////////////////// - /// Restart the sound from the beginning - /// - /// \return True if restart was successful - /// - //////////////////////////////////////////////////////////// - bool Restart(); - //////////////////////////////////////////////////////////// /// Open the sound file for reading /// @@ -142,6 +134,14 @@ public : //////////////////////////////////////////////////////////// void Write(const Int16* Data, std::size_t NbSamples); + //////////////////////////////////////////////////////////// + /// Move the current reading position in the file + /// + /// \param TimeOffset : New position, expressed in seconds + /// + //////////////////////////////////////////////////////////// + void Seek(float TimeOffset); + private : //////////////////////////////////////////////////////////// @@ -183,9 +183,6 @@ private : std::size_t myNbSamples; ///< Total number of samples in the file unsigned int myChannelsCount; ///< Number of channels used by the sound unsigned int mySampleRate; ///< Number of samples per second - std::string myFilename; ///< Path of the file (valid if loaded from a file) - const char* myData; ///< Pointer to the file in memory (valid if loaded from memory) - std::size_t mySize; ///< Size of the file in memory (valid if loaded from memory) }; } // namespace priv diff --git a/src/SFML/Audio/SoundStream.cpp b/src/SFML/Audio/SoundStream.cpp index 4fb2ff249..8642de86a 100644 --- a/src/SFML/Audio/SoundStream.cpp +++ b/src/SFML/Audio/SoundStream.cpp @@ -98,14 +98,13 @@ void SoundStream::Play() return; } - // Notify the derived class - if (OnStart()) - { - // Start updating the stream in a separate thread to avoid blocking the application - mySamplesProcessed = 0; - myIsStreaming = true; - Launch(); - } + // Move to the beginning + OnSeek(0); + + // Start updating the stream in a separate thread to avoid blocking the application + mySamplesProcessed = 0; + myIsStreaming = true; + Launch(); } @@ -153,6 +152,24 @@ Sound::Status SoundStream::GetStatus() const } +//////////////////////////////////////////////////////////// +/// Set the current playing position of the stream +//////////////////////////////////////////////////////////// +void SoundStream::SetPlayingOffset(float TimeOffset) +{ + // Stop the stream + Stop(); + + // Let the derived class update the current position + OnSeek(TimeOffset); + + // Restart streaming + mySamplesProcessed = static_cast(TimeOffset * mySampleRate * myChannelsCount); + myIsStreaming = true; + Launch(); +} + + //////////////////////////////////////////////////////////// /// Get the current playing position of the stream /// @@ -245,15 +262,16 @@ void SoundStream::Run() if (FillAndPushBuffer(Buffer)) { // User requested to stop: check if we must loop or really stop - if (myLoop && OnStart()) + if (myLoop) { - // Looping: mark the current buffer as the last one + // Looping: restart and mark the current buffer as the last one // (to know when to reset the sample count) + OnSeek(0); EndBuffer = Buffer; } else { - // Not looping or restart failed: request stop + // Not looping: request stop RequestStop = true; } } @@ -337,15 +355,4 @@ void SoundStream::ClearQueue() ALCheck(alSourceUnqueueBuffers(Sound::mySource, 1, &Buffer)); } - -//////////////////////////////////////////////////////////// -/// Called when the sound restarts -//////////////////////////////////////////////////////////// -bool SoundStream::OnStart() -{ - // Does nothing by default - - return true; -} - } // namespace sf