Advertisement
Guest User

Untitled

a guest
Apr 17th, 2010
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.29 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////
  2. //
  3. // SFML - Simple and Fast Multimedia Library
  4. // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
  5. //
  6. // This software is provided 'as-is', without any express or implied warranty.
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it freely,
  11. // subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented;
  14. //    you must not claim that you wrote the original software.
  15. //    If you use this software in a product, an acknowledgment
  16. //    in the product documentation would be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such,
  19. //    and must not be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source distribution.
  22. //
  23. ////////////////////////////////////////////////////////////
  24.  
  25. ////////////////////////////////////////////////////////////
  26. // Headers
  27. ////////////////////////////////////////////////////////////
  28. #include <SFML/Audio/Music.hpp>
  29. #include <SFML/Audio/OpenAL.hpp>
  30. #include <SFML/Audio/SoundFile.hpp>
  31. #include "Music2.hpp"
  32. #include <fstream>
  33. #include <iostream>
  34.  
  35.  
  36. namespace sf
  37. {
  38. ////////////////////////////////////////////////////////////
  39. /// Construct the music with a buffer size
  40. ////////////////////////////////////////////////////////////
  41. Music2::Music2(std::size_t BufferSize) :
  42. myDuration(0.f),
  43. mySamples (BufferSize),
  44. myPhase   (false)
  45. {
  46.     myFiles[0] = NULL;
  47.     myFiles[1] = NULL;
  48. }
  49.  
  50.  
  51. ////////////////////////////////////////////////////////////
  52. /// Destructor
  53. ////////////////////////////////////////////////////////////
  54. Music2::~Music2()
  55. {
  56.     // We must stop before destroying the file :)
  57.     Stop();
  58.  
  59.     delete myFiles[0];
  60.     delete myFiles[1];
  61. }
  62.  
  63.  
  64. ////////////////////////////////////////////////////////////
  65. /// Open a music file (doesn't play it -- call Play() for that)
  66. ////////////////////////////////////////////////////////////
  67. bool Music2::OpenFromFile(const std::string& FilenameA,const std::string& FilenameB)
  68. {
  69.     // First stop the music if it was already running
  70.     Stop();
  71.  
  72.     // Create the sound file implementation, and open it in read mode
  73.     delete myFiles[0];
  74.     delete myFiles[1];
  75.     myFiles[0] = myFiles[1] = NULL;
  76.  
  77.     // load up the files
  78.     if(!FilenameA.empty())
  79.     {
  80.         myFiles[0] = priv::SoundFile::CreateRead(FilenameA);
  81.         if(!myFiles[0])
  82.             std::cerr << "Failed to open \"" << FilenameA << "\" for reading" << std::endl;
  83.     }
  84.     if(!FilenameB.empty())
  85.     {
  86.         myFiles[1] = priv::SoundFile::CreateRead(FilenameB);
  87.         if(!myFiles[1])
  88.             std::cerr << "Failed to open \"" << FilenameB << "\" for reading" << std::endl;
  89.     }
  90.  
  91.     if(myFiles[0] && myFiles[1])        // make sure they have matching mono/stereo and samplerate
  92.     {
  93.         if( (myFiles[0]->GetChannelsCount() != myFiles[1]->GetChannelsCount())  ||
  94.             (myFiles[0]->GetSampleRate() != myFiles[1]->GetSampleRate()) )
  95.         {
  96.             std::cerr << "Files \"" << FilenameA << "\" and \"" << FilenameB << "\" have mismatching formats" << std::endl;
  97.             delete myFiles[0];
  98.             delete myFiles[1];
  99.             myFiles[0] = myFiles[1] = NULL;
  100.             return false;
  101.         }
  102.     }
  103.  
  104.     // make sure at least one file was loaded
  105.     int loaded = -1;
  106.          if(myFiles[0])  loaded = 0;
  107.     else if(myFiles[1])  loaded = 1;
  108.  
  109.     if(loaded < 0)
  110.         return false;
  111.  
  112.     // calculate the dureation
  113.     myDuration  = 0;
  114.     for(int i = 0; i < 2; ++i)
  115.     {
  116.         if(myFiles[i])
  117.             myDuration += static_cast<float>(myFiles[i]->GetSamplesCount()) / myFiles[i]->GetSampleRate() / myFiles[i]->GetChannelsCount();
  118.     }
  119.  
  120.     // start on the appropriate phase
  121.     myPhase = (loaded == 1);
  122.  
  123.     // Lastly, initialize the stream
  124.     Initialize(myFiles[loaded]->GetChannelsCount(), myFiles[loaded]->GetSampleRate());
  125.  
  126.     return true;
  127. }
  128.  
  129. ////////////////////////////////////////////////////////////
  130. /// Open a music file from memory (doesn't play it -- call Play() for that)
  131. ////////////////////////////////////////////////////////////
  132. bool Music2::OpenFromMemory(const char* DataA, std::size_t SizeInBytesA,const char* DataB, std::size_t SizeInBytesB)
  133. {
  134.     // First stop the music if it was already running
  135.     Stop();
  136.  
  137.     // Create the sound file implementation, and open it in read mode
  138.     delete myFiles[0];
  139.     delete myFiles[1];
  140.     myFiles[0] = myFiles[1] = NULL;
  141.  
  142.     // load up the files
  143.     if(DataA && SizeInBytesA)
  144.     {
  145.         myFiles[0] = priv::SoundFile::CreateRead(DataA,SizeInBytesA);
  146.         if(!myFiles[0])
  147.             std::cerr << "Failed to open Intro file from memory for reading" << std::endl;
  148.     }
  149.     if(DataB && SizeInBytesB)
  150.     {
  151.         myFiles[1] = priv::SoundFile::CreateRead(DataB,SizeInBytesB);
  152.         if(!myFiles[1])
  153.             std::cerr << "Failed to open Loop file from memory for reading" << std::endl;
  154.     }
  155.  
  156.     if(myFiles[0] && myFiles[1])        // make sure they have matching mono/stereo and samplerate
  157.     {
  158.         if( (myFiles[0]->GetChannelsCount() != myFiles[1]->GetChannelsCount())  ||
  159.             (myFiles[0]->GetSampleRate() != myFiles[1]->GetSampleRate()) )
  160.         {
  161.             std::cerr << "Intro and Loop files have mismatching formats" << std::endl;
  162.             delete myFiles[0];
  163.             delete myFiles[1];
  164.             myFiles[0] = myFiles[1] = NULL;
  165.             return false;
  166.         }
  167.     }
  168.  
  169.     // make sure at least one file was loaded
  170.     int loaded = -1;
  171.          if(myFiles[0])  loaded = 0;
  172.     else if(myFiles[1])  loaded = 1;
  173.  
  174.     if(loaded < 0)
  175.         return false;
  176.  
  177.     // calculate the dureation
  178.     myDuration  = 0;
  179.     for(int i = 0; i < 2; ++i)
  180.     {
  181.         if(myFiles[i])
  182.             myDuration += static_cast<float>(myFiles[i]->GetSamplesCount()) / myFiles[i]->GetSampleRate() / myFiles[i]->GetChannelsCount();
  183.     }
  184.  
  185.     // start on the appropriate phase
  186.     myPhase = (loaded == 1);
  187.  
  188.     // Lastly, initialize the stream
  189.     Initialize(myFiles[loaded]->GetChannelsCount(), myFiles[loaded]->GetSampleRate());
  190.  
  191.     return true;
  192. }
  193.  
  194. ////////////////////////////////////////////////////////////
  195. /// /see SoundStream::OnStart
  196. ////////////////////////////////////////////////////////////
  197. bool Music2::OnStart()
  198. {
  199.     if(myFiles[0])
  200.     {
  201.         myPhase = false;
  202.         myFiles[0]->Restart();
  203.     }
  204.     else
  205.  
  206.         myPhase = true;
  207.        
  208.     if(myFiles[1])
  209.         myFiles[1]->Restart();
  210.  
  211.     return myFiles[0] || myFiles[1];
  212. }
  213.  
  214.  
  215. ////////////////////////////////////////////////////////////
  216. /// /see SoundStream::OnGetData
  217. ////////////////////////////////////////////////////////////
  218. bool Music2::OnGetData(SoundStream::Chunk& Data)
  219. {
  220.     if(!myFiles[myPhase])           // not loaded
  221.         return false;
  222.  
  223.     unsigned written = 0;
  224.     Data.Samples = &mySamples[0];
  225.     while(written < mySamples.size())
  226.     {
  227.         unsigned remain = mySamples.size() - written;
  228.         unsigned step = myFiles[myPhase]->Read(&mySamples[written],remain);
  229.         written += step;
  230.  
  231.         if(!step) // EOF
  232.         {
  233.             if(myPhase)         // if we're looping
  234.                 break;          // EOF for reals
  235.                                 // otherwise, just restart the loop portion
  236.         }
  237.         if(step < remain)
  238.         {
  239.             // not enough data remaining in the current portion to fill the buffer
  240.             //   switch to the loop portion and restart it
  241.             myPhase = true;
  242.  
  243.             if(!myFiles[1])     // no loop portion
  244.                 break;          // treat as EOF
  245.  
  246.             // otherwise restart and switch to the loop portion
  247.             myFiles[1]->Restart();
  248.         }
  249.     }
  250.  
  251.     Data.NbSamples = written;
  252.     return written == mySamples.size();
  253. }
  254.  
  255.  
  256. ////////////////////////////////////////////////////////////
  257. /// Get the sound duration
  258. ////////////////////////////////////////////////////////////
  259. float Music2::GetDuration() const
  260. {
  261.     return myDuration;
  262. }
  263.  
  264. } // namespace sf
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement