Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:58:13

0001 ////////////////////////////////////////////////////////////
0002 //
0003 // SFML - Simple and Fast Multimedia Library
0004 // Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
0005 //
0006 // This software is provided 'as-is', without any express or implied warranty.
0007 // In no event will the authors be held liable for any damages arising from the use of this software.
0008 //
0009 // Permission is granted to anyone to use this software for any purpose,
0010 // including commercial applications, and to alter it and redistribute it freely,
0011 // subject to the following restrictions:
0012 //
0013 // 1. The origin of this software must not be misrepresented;
0014 //    you must not claim that you wrote the original software.
0015 //    If you use this software in a product, an acknowledgment
0016 //    in the product documentation would be appreciated but is not required.
0017 //
0018 // 2. Altered source versions must be plainly marked as such,
0019 //    and must not be misrepresented as being the original software.
0020 //
0021 // 3. This notice may not be removed or altered from any source distribution.
0022 //
0023 ////////////////////////////////////////////////////////////
0024 
0025 #ifndef SFML_MUSIC_HPP
0026 #define SFML_MUSIC_HPP
0027 
0028 ////////////////////////////////////////////////////////////
0029 // Headers
0030 ////////////////////////////////////////////////////////////
0031 #include <SFML/Audio/Export.hpp>
0032 #include <SFML/Audio/SoundStream.hpp>
0033 #include <SFML/Audio/InputSoundFile.hpp>
0034 #include <SFML/System/Mutex.hpp>
0035 #include <SFML/System/Time.hpp>
0036 #include <string>
0037 #include <vector>
0038 
0039 
0040 namespace sf
0041 {
0042 class InputStream;
0043 
0044 ////////////////////////////////////////////////////////////
0045 /// \brief Streamed music played from an audio file
0046 ///
0047 ////////////////////////////////////////////////////////////
0048 class SFML_AUDIO_API Music : public SoundStream
0049 {
0050 public:
0051 
0052     ////////////////////////////////////////////////////////////
0053     /// \brief Structure defining a time range using the template type
0054     ///
0055     ////////////////////////////////////////////////////////////
0056     template <typename T>
0057     struct Span
0058     {
0059         ////////////////////////////////////////////////////////////
0060         /// \brief Default constructor
0061         ///
0062         ////////////////////////////////////////////////////////////
0063         Span()
0064         {
0065 
0066         }
0067 
0068         ////////////////////////////////////////////////////////////
0069         /// \brief Initialization constructor
0070         ///
0071         /// \param off Initial Offset
0072         /// \param len Initial Length
0073         ///
0074         ////////////////////////////////////////////////////////////
0075         Span(T off, T len):
0076         offset(off),
0077         length(len)
0078         {
0079 
0080         }
0081 
0082         T offset; //!< The beginning offset of the time range
0083         T length; //!< The length of the time range
0084     };
0085 
0086     // Define the relevant Span types
0087     typedef Span<Time> TimeSpan;
0088 
0089     ////////////////////////////////////////////////////////////
0090     /// \brief Default constructor
0091     ///
0092     ////////////////////////////////////////////////////////////
0093     Music();
0094 
0095     ////////////////////////////////////////////////////////////
0096     /// \brief Destructor
0097     ///
0098     ////////////////////////////////////////////////////////////
0099     ~Music();
0100 
0101     ////////////////////////////////////////////////////////////
0102     /// \brief Open a music from an audio file
0103     ///
0104     /// This function doesn't start playing the music (call play()
0105     /// to do so).
0106     /// See the documentation of sf::InputSoundFile for the list
0107     /// of supported formats.
0108     ///
0109     /// \warning Since the music is not loaded at once but rather
0110     /// streamed continuously, the file must remain accessible until
0111     /// the sf::Music object loads a new music or is destroyed.
0112     ///
0113     /// \param filename Path of the music file to open
0114     ///
0115     /// \return True if loading succeeded, false if it failed
0116     ///
0117     /// \see openFromMemory, openFromStream
0118     ///
0119     ////////////////////////////////////////////////////////////
0120     bool openFromFile(const std::string& filename);
0121 
0122     ////////////////////////////////////////////////////////////
0123     /// \brief Open a music from an audio file in memory
0124     ///
0125     /// This function doesn't start playing the music (call play()
0126     /// to do so).
0127     /// See the documentation of sf::InputSoundFile for the list
0128     /// of supported formats.
0129     ///
0130     /// \warning Since the music is not loaded at once but rather streamed
0131     /// continuously, the \a data buffer must remain accessible until
0132     /// the sf::Music object loads a new music or is destroyed. That is,
0133     /// you can't deallocate the buffer right after calling this function.
0134     ///
0135     /// \param data        Pointer to the file data in memory
0136     /// \param sizeInBytes Size of the data to load, in bytes
0137     ///
0138     /// \return True if loading succeeded, false if it failed
0139     ///
0140     /// \see openFromFile, openFromStream
0141     ///
0142     ////////////////////////////////////////////////////////////
0143     bool openFromMemory(const void* data, std::size_t sizeInBytes);
0144 
0145     ////////////////////////////////////////////////////////////
0146     /// \brief Open a music from an audio file in a custom stream
0147     ///
0148     /// This function doesn't start playing the music (call play()
0149     /// to do so).
0150     /// See the documentation of sf::InputSoundFile for the list
0151     /// of supported formats.
0152     ///
0153     /// \warning Since the music is not loaded at once but rather
0154     /// streamed continuously, the \a stream must remain accessible
0155     /// until the sf::Music object loads a new music or is destroyed.
0156     ///
0157     /// \param stream Source stream to read from
0158     ///
0159     /// \return True if loading succeeded, false if it failed
0160     ///
0161     /// \see openFromFile, openFromMemory
0162     ///
0163     ////////////////////////////////////////////////////////////
0164     bool openFromStream(InputStream& stream);
0165 
0166     ////////////////////////////////////////////////////////////
0167     /// \brief Get the total duration of the music
0168     ///
0169     /// \return Music duration
0170     ///
0171     ////////////////////////////////////////////////////////////
0172     Time getDuration() const;
0173 
0174     ////////////////////////////////////////////////////////////
0175     /// \brief Get the positions of the of the sound's looping sequence
0176     ///
0177     /// \return Loop Time position class.
0178     ///
0179     /// \warning Since setLoopPoints() performs some adjustments on the
0180     /// provided values and rounds them to internal samples, a call to
0181     /// getLoopPoints() is not guaranteed to return the same times passed
0182     /// into a previous call to setLoopPoints(). However, it is guaranteed
0183     /// to return times that will map to the valid internal samples of
0184     /// this Music if they are later passed to setLoopPoints().
0185     ///
0186     /// \see setLoopPoints
0187     ///
0188     ////////////////////////////////////////////////////////////
0189     TimeSpan getLoopPoints() const;
0190 
0191     ////////////////////////////////////////////////////////////
0192     /// \brief Sets the beginning and duration of the sound's looping sequence using sf::Time
0193     ///
0194     /// setLoopPoints() allows for specifying the beginning offset and the duration of the loop such that, when the music
0195     /// is enabled for looping, it will seamlessly seek to the beginning whenever it
0196     /// encounters the end of the duration. Valid ranges for timePoints.offset and timePoints.length are
0197     /// [0, Dur) and (0, Dur-offset] respectively, where Dur is the value returned by getDuration().
0198     /// Note that the EOF "loop point" from the end to the beginning of the stream is still honored,
0199     /// in case the caller seeks to a point after the end of the loop range. This function can be
0200     /// safely called at any point after a stream is opened, and will be applied to a playing sound
0201     /// without affecting the current playing offset.
0202     ///
0203     /// \warning Setting the loop points while the stream's status is Paused
0204     /// will set its status to Stopped. The playing offset will be unaffected.
0205     ///
0206     /// \param timePoints The definition of the loop. Can be any time points within the sound's length
0207     ///
0208     /// \see getLoopPoints
0209     ///
0210     ////////////////////////////////////////////////////////////
0211     void setLoopPoints(TimeSpan timePoints);
0212 
0213 protected:
0214 
0215     ////////////////////////////////////////////////////////////
0216     /// \brief Request a new chunk of audio samples from the stream source
0217     ///
0218     /// This function fills the chunk from the next samples
0219     /// to read from the audio file.
0220     ///
0221     /// \param data Chunk of data to fill
0222     ///
0223     /// \return True to continue playback, false to stop
0224     ///
0225     ////////////////////////////////////////////////////////////
0226     virtual bool onGetData(Chunk& data);
0227 
0228     ////////////////////////////////////////////////////////////
0229     /// \brief Change the current playing position in the stream source
0230     ///
0231     /// \param timeOffset New playing position, from the beginning of the music
0232     ///
0233     ////////////////////////////////////////////////////////////
0234     virtual void onSeek(Time timeOffset);
0235 
0236     ////////////////////////////////////////////////////////////
0237     /// \brief Change the current playing position in the stream source to the loop offset
0238     ///
0239     /// This is called by the underlying SoundStream whenever it needs us to reset
0240     /// the seek position for a loop. We then determine whether we are looping on a
0241     /// loop point or the end-of-file, perform the seek, and return the new position.
0242     ///
0243     /// \return The seek position after looping (or -1 if there's no loop)
0244     ///
0245     ////////////////////////////////////////////////////////////
0246     virtual Int64 onLoop();
0247 
0248 private:
0249 
0250     ////////////////////////////////////////////////////////////
0251     /// \brief Initialize the internal state after loading a new music
0252     ///
0253     ////////////////////////////////////////////////////////////
0254     void initialize();
0255 
0256     ////////////////////////////////////////////////////////////
0257     /// \brief Helper to convert an sf::Time to a sample position
0258     ///
0259     /// \param position Time to convert to samples
0260     ///
0261     /// \return The number of samples elapsed at the given time
0262     ///
0263     ////////////////////////////////////////////////////////////
0264     Uint64 timeToSamples(Time position) const;
0265 
0266     ////////////////////////////////////////////////////////////
0267     /// \brief Helper to convert a sample position to an sf::Time
0268     ///
0269     /// \param samples Sample count to convert to Time
0270     ///
0271     /// \return The Time position of the given sample
0272     ///
0273     ////////////////////////////////////////////////////////////
0274     Time samplesToTime(Uint64 samples) const;
0275 
0276     ////////////////////////////////////////////////////////////
0277     // Member data
0278     ////////////////////////////////////////////////////////////
0279     InputSoundFile     m_file;     //!< The streamed music file
0280     std::vector<Int16> m_samples;  //!< Temporary buffer of samples
0281     Mutex              m_mutex;    //!< Mutex protecting the data
0282     Span<Uint64>       m_loopSpan; //!< Loop Range Specifier
0283 };
0284 
0285 } // namespace sf
0286 
0287 
0288 #endif // SFML_MUSIC_HPP
0289 
0290 
0291 ////////////////////////////////////////////////////////////
0292 /// \class sf::Music
0293 /// \ingroup audio
0294 ///
0295 /// Musics are sounds that are streamed rather than completely
0296 /// loaded in memory. This is especially useful for compressed
0297 /// musics that usually take hundreds of MB when they are
0298 /// uncompressed: by streaming it instead of loading it entirely,
0299 /// you avoid saturating the memory and have almost no loading delay.
0300 /// This implies that the underlying resource (file, stream or
0301 /// memory buffer) must remain valid for the lifetime of the
0302 /// sf::Music object.
0303 ///
0304 /// Apart from that, a sf::Music has almost the same features as
0305 /// the sf::SoundBuffer / sf::Sound pair: you can play/pause/stop
0306 /// it, request its parameters (channels, sample rate), change
0307 /// the way it is played (pitch, volume, 3D position, ...), etc.
0308 ///
0309 /// As a sound stream, a music is played in its own thread in order
0310 /// not to block the rest of the program. This means that you can
0311 /// leave the music alone after calling play(), it will manage itself
0312 /// very well.
0313 ///
0314 /// Usage example:
0315 /// \code
0316 /// // Declare a new music
0317 /// sf::Music music;
0318 ///
0319 /// // Open it from an audio file
0320 /// if (!music.openFromFile("music.ogg"))
0321 /// {
0322 ///     // error...
0323 /// }
0324 ///
0325 /// // Change some parameters
0326 /// music.setPosition(0, 1, 10); // change its 3D position
0327 /// music.setPitch(2);           // increase the pitch
0328 /// music.setVolume(50);         // reduce the volume
0329 /// music.setLoop(true);         // make it loop
0330 ///
0331 /// // Play it
0332 /// music.play();
0333 /// \endcode
0334 ///
0335 /// \see sf::Sound, sf::SoundStream
0336 ///
0337 ////////////////////////////////////////////////////////////