Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////////////////////////////////////////////
- //
- // SFML - Simple and Fast Multimedia Library
- // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
- //
- // This software is provided 'as-is', without any express or implied warranty.
- // In no event will the authors be held liable for any damages arising from the use of this software.
- //
- // Permission is granted to anyone to use this software for any purpose,
- // including commercial applications, and to alter it and redistribute it freely,
- // subject to the following restrictions:
- //
- // 1. The origin of this software must not be misrepresented;
- // you must not claim that you wrote the original software.
- // If you use this software in a product, an acknowledgment
- // in the product documentation would be appreciated but is not required.
- //
- // 2. Altered source versions must be plainly marked as such,
- // and must not be misrepresented as being the original software.
- //
- // 3. This notice may not be removed or altered from any source distribution.
- //
- ////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////
- // Headers
- ////////////////////////////////////////////////////////////
- #include <SFML/Audio/Music.hpp>
- #include <SFML/Audio/OpenAL.hpp>
- #include <SFML/Audio/SoundFile.hpp>
- #include "Music2.hpp"
- #include <fstream>
- #include <iostream>
- namespace sf
- {
- ////////////////////////////////////////////////////////////
- /// Construct the music with a buffer size
- ////////////////////////////////////////////////////////////
- Music2::Music2(std::size_t BufferSize) :
- myDuration(0.f),
- mySamples (BufferSize),
- myPhase (false)
- {
- myFiles[0] = NULL;
- myFiles[1] = NULL;
- }
- ////////////////////////////////////////////////////////////
- /// Destructor
- ////////////////////////////////////////////////////////////
- Music2::~Music2()
- {
- // We must stop before destroying the file :)
- Stop();
- delete myFiles[0];
- delete myFiles[1];
- }
- ////////////////////////////////////////////////////////////
- /// Open a music file (doesn't play it -- call Play() for that)
- ////////////////////////////////////////////////////////////
- bool Music2::OpenFromFile(const std::string& FilenameA,const std::string& FilenameB)
- {
- // First stop the music if it was already running
- Stop();
- // Create the sound file implementation, and open it in read mode
- delete myFiles[0];
- delete myFiles[1];
- myFiles[0] = myFiles[1] = NULL;
- // load up the files
- if(!FilenameA.empty())
- {
- myFiles[0] = priv::SoundFile::CreateRead(FilenameA);
- if(!myFiles[0])
- std::cerr << "Failed to open \"" << FilenameA << "\" for reading" << std::endl;
- }
- if(!FilenameB.empty())
- {
- myFiles[1] = priv::SoundFile::CreateRead(FilenameB);
- if(!myFiles[1])
- std::cerr << "Failed to open \"" << FilenameB << "\" for reading" << std::endl;
- }
- if(myFiles[0] && myFiles[1]) // make sure they have matching mono/stereo and samplerate
- {
- if( (myFiles[0]->GetChannelsCount() != myFiles[1]->GetChannelsCount()) ||
- (myFiles[0]->GetSampleRate() != myFiles[1]->GetSampleRate()) )
- {
- std::cerr << "Files \"" << FilenameA << "\" and \"" << FilenameB << "\" have mismatching formats" << std::endl;
- delete myFiles[0];
- delete myFiles[1];
- myFiles[0] = myFiles[1] = NULL;
- return false;
- }
- }
- // make sure at least one file was loaded
- int loaded = -1;
- if(myFiles[0]) loaded = 0;
- else if(myFiles[1]) loaded = 1;
- if(loaded < 0)
- return false;
- // calculate the dureation
- myDuration = 0;
- for(int i = 0; i < 2; ++i)
- {
- if(myFiles[i])
- myDuration += static_cast<float>(myFiles[i]->GetSamplesCount()) / myFiles[i]->GetSampleRate() / myFiles[i]->GetChannelsCount();
- }
- // start on the appropriate phase
- myPhase = (loaded == 1);
- // Lastly, initialize the stream
- Initialize(myFiles[loaded]->GetChannelsCount(), myFiles[loaded]->GetSampleRate());
- return true;
- }
- ////////////////////////////////////////////////////////////
- /// Open a music file from memory (doesn't play it -- call Play() for that)
- ////////////////////////////////////////////////////////////
- bool Music2::OpenFromMemory(const char* DataA, std::size_t SizeInBytesA,const char* DataB, std::size_t SizeInBytesB)
- {
- // First stop the music if it was already running
- Stop();
- // Create the sound file implementation, and open it in read mode
- delete myFiles[0];
- delete myFiles[1];
- myFiles[0] = myFiles[1] = NULL;
- // load up the files
- if(DataA && SizeInBytesA)
- {
- myFiles[0] = priv::SoundFile::CreateRead(DataA,SizeInBytesA);
- if(!myFiles[0])
- std::cerr << "Failed to open Intro file from memory for reading" << std::endl;
- }
- if(DataB && SizeInBytesB)
- {
- myFiles[1] = priv::SoundFile::CreateRead(DataB,SizeInBytesB);
- if(!myFiles[1])
- std::cerr << "Failed to open Loop file from memory for reading" << std::endl;
- }
- if(myFiles[0] && myFiles[1]) // make sure they have matching mono/stereo and samplerate
- {
- if( (myFiles[0]->GetChannelsCount() != myFiles[1]->GetChannelsCount()) ||
- (myFiles[0]->GetSampleRate() != myFiles[1]->GetSampleRate()) )
- {
- std::cerr << "Intro and Loop files have mismatching formats" << std::endl;
- delete myFiles[0];
- delete myFiles[1];
- myFiles[0] = myFiles[1] = NULL;
- return false;
- }
- }
- // make sure at least one file was loaded
- int loaded = -1;
- if(myFiles[0]) loaded = 0;
- else if(myFiles[1]) loaded = 1;
- if(loaded < 0)
- return false;
- // calculate the dureation
- myDuration = 0;
- for(int i = 0; i < 2; ++i)
- {
- if(myFiles[i])
- myDuration += static_cast<float>(myFiles[i]->GetSamplesCount()) / myFiles[i]->GetSampleRate() / myFiles[i]->GetChannelsCount();
- }
- // start on the appropriate phase
- myPhase = (loaded == 1);
- // Lastly, initialize the stream
- Initialize(myFiles[loaded]->GetChannelsCount(), myFiles[loaded]->GetSampleRate());
- return true;
- }
- ////////////////////////////////////////////////////////////
- /// /see SoundStream::OnStart
- ////////////////////////////////////////////////////////////
- bool Music2::OnStart()
- {
- if(myFiles[0])
- {
- myPhase = false;
- myFiles[0]->Restart();
- }
- else
- myPhase = true;
- if(myFiles[1])
- myFiles[1]->Restart();
- return myFiles[0] || myFiles[1];
- }
- ////////////////////////////////////////////////////////////
- /// /see SoundStream::OnGetData
- ////////////////////////////////////////////////////////////
- bool Music2::OnGetData(SoundStream::Chunk& Data)
- {
- if(!myFiles[myPhase]) // not loaded
- return false;
- unsigned written = 0;
- Data.Samples = &mySamples[0];
- while(written < mySamples.size())
- {
- unsigned remain = mySamples.size() - written;
- unsigned step = myFiles[myPhase]->Read(&mySamples[written],remain);
- written += step;
- if(!step) // EOF
- {
- if(myPhase) // if we're looping
- break; // EOF for reals
- // otherwise, just restart the loop portion
- }
- if(step < remain)
- {
- // not enough data remaining in the current portion to fill the buffer
- // switch to the loop portion and restart it
- myPhase = true;
- if(!myFiles[1]) // no loop portion
- break; // treat as EOF
- // otherwise restart and switch to the loop portion
- myFiles[1]->Restart();
- }
- }
- Data.NbSamples = written;
- return written == mySamples.size();
- }
- ////////////////////////////////////////////////////////////
- /// Get the sound duration
- ////////////////////////////////////////////////////////////
- float Music2::GetDuration() const
- {
- return myDuration;
- }
- } // namespace sf
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement