Music.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Audio/Music.hpp>
00029 #include <SFML/Audio/OpenAL.hpp>
00030 #include <SFML/Audio/SoundFile.hpp>
00031 #include <fstream>
00032 #include <iostream>
00033 
00034 
00038 sfMusic::sfMusic(std::size_t BufferSize) :
00039 myFile    (NULL),
00040 myLoop    (false),
00041 myDuration(0.f),
00042 mySamples (BufferSize)
00043 {
00044 
00045 }
00046 
00047 
00051 sfMusic::~sfMusic()
00052 {
00053     delete myFile;
00054 }
00055 
00056 
00060 bool sfMusic::Open(const std::string& Filename)
00061 {
00062     // Store the filename for later use
00063     myFilename = Filename;
00064 
00065     // Create the sound file implementation
00066     delete myFile;
00067     myFile = sf_private::sfSoundFile::Create(myFilename);
00068 
00069     // Open the music file in read mode
00070     std::size_t  NbSamples;
00071     unsigned int ChannelsCount;
00072     unsigned int Frequency;
00073     if (!myFile->OpenRead(myFilename, NbSamples, ChannelsCount, Frequency))
00074     {
00075         std::cerr << "Failed to open \"" << myFilename << "\" for reading" << std::endl;
00076         return false;
00077     }
00078 
00079     // Compute the duration
00080     myDuration = static_cast<float>(NbSamples) / Frequency;
00081 
00082     // Initialize the stream
00083     Initialize(ChannelsCount, Frequency);
00084 
00085     return true;
00086 }
00087 
00088 
00092 void sfMusic::SetLoop(bool Loop)
00093 {
00094     myLoop = Loop;
00095 }
00096 
00097 
00101 bool sfMusic::GetLoop() const
00102 {
00103     return myLoop;
00104 }
00105 
00106 
00110 bool sfMusic::OnStart()
00111 {
00112     // Re-open the music file to restart at the begining
00113 
00114     std::size_t  NbSamples;
00115     unsigned int ChannelsCount;
00116     unsigned int Frequency;
00117 
00118     return myFile->OpenRead(myFilename, NbSamples, ChannelsCount, Frequency);
00119 }
00120 
00121 
00125 bool sfMusic::OnGetData(sfSoundStream::Chunk& Data)
00126 {
00127     // Fill the chunk parameters
00128     Data.Samples   = &mySamples[0];
00129     Data.NbSamples = myFile->Read(&mySamples[0], mySamples.size());
00130 
00131     // Check if we have reached the end of the audio file
00132     if (Data.NbSamples < mySamples.size())
00133     {
00134         // Check if we must loop
00135         if (myLoop)
00136         {
00137             if (OnStart())
00138             {
00139                 // We succeeded to restart the audio playback
00140                 Data.NbSamples += myFile->Read(&mySamples[Data.NbSamples], mySamples.size() - Data.NbSamples);
00141                 return true;
00142             }
00143         }
00144 
00145         // No more audio samples to read : we stop the playback
00146         return false;
00147     }
00148 
00149     // End of audio file has not been reached, continue playback
00150     return true;
00151 }
00152 
00153 
00157 float sfMusic::GetDuration() const
00158 {
00159     return myDuration;
00160 }