|
|
|||
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 ////////////////////////////////////////////////////////////
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|