Buffer.h

Go to the documentation of this file.
00001 
00002 //Luke Lenhart, 2008
00003 //See /docs/License.txt for details on how this code may be used.
00004 
00005 #pragma once
00006 
00007 #include "../base/Setup.h"
00008 
00009 #ifdef MPMA_COMPILE_AUDIO
00010 
00011 #include <list>
00012 #include <vector>
00013 #include "Source.h"
00014 #include "../base/ReferenceCount.h"
00015 #include "../base/Locks.h"
00016 #include "AL_Include.h"
00017 
00018 namespace AUDIO_INTERNAL { class BackgroundProcessing; }
00019 
00021 namespace AUDIO
00022 {
00024     enum BufferBehavior
00025     {
00027         STATIC_DATA=0x100,
00029         STREAM_DATA
00030     };
00031 
00032     //internal data common to all buffer objects
00033     struct InternalSharedBufferData
00034     {
00035         inline InternalSharedBufferData(): isReal(true), isStatic(true), streamingSource(0), staticBuffer(0)
00036             {}
00037 
00038         bool isReal;
00039         bool isStatic;
00040         MPMA::RWSleepLock bufferLock;
00041 
00042         //these are used only for a streaming buffer
00043         std::list<Source*> readySources; //sources available to play
00044         Source *streamingSource; //original copy of the streaming source, from which we'll make any duplicates we need (also stored in readySources)
00045         float streamSeconds; //how big the total streaming buffers are
00046 
00047         struct PlayerBuffers
00048         {
00049             ALuint playerResource; //the player (openal source)
00050             ALuint *buffers; //buffers used by the player for streaming
00051             nuint buffersFinished; //how many buffers are done playing and not queued
00052             Source *source; //source used for this player
00053             class Player *player; //player that is playing this
00054             bool beingFreed; //whether this entry is in the process of being freed
00055             bool freeRequestAboutToOccur; //whether we were just asked to free it... in which case the bg thread should not touch it
00056 
00057             //temporary buffer used to hold data during streaming
00058             uint8 *streamingBufferData;
00059             nuint streamingBufferSize;
00060         };
00061         std::list<PlayerBuffers> players; //list of players currently using this buffer
00062 
00063         //used for static buffer only
00064         ALuint staticBuffer;
00065     };
00066 
00068     class Buffer: public MPMA::ReferenceCountedData<InternalSharedBufferData>
00069     {
00070     public:
00072         Buffer(Source &source, BufferBehavior bufferBehavior, float streamSizeInSeconds=0.2f);
00073 
00074         virtual ~Buffer();
00075 
00077         inline Buffer()
00078             { Data().isReal=false; }
00079 
00081         inline bool IsReal() const
00082             { return Data().isReal; }
00083 
00084     protected:
00085         //returns whether this buffer has static data
00086         inline bool IsStatic() const
00087             { return Data().isStatic; }
00088 
00089         //sets up the initial buffer or buffers needed to start playing and associates them with a player(what openal calls a source).
00090         bool SetupInitialPlayBuffers(ALuint playerResource, class Player *player);
00091 
00092         //the player has either stopped or destructed, so stop processing it
00093         void FreePlayer(ALuint playerResource, class Player *player);
00094 
00095     private:
00096         //attempts construction using a hardware static buffer.
00097         bool ConstructInHardwareBuffer(Source *source);
00098 
00099         //attempts construction using a system static buffer.
00100         bool ConstructInSystemBuffer(Source *source);
00101 
00102         //attempts construction using a hardware static buffer.
00103         bool ConstructInStreamingBuffer(Source *source, float streamSizeInSeconds);
00104 
00105         //called if we failed construction, so initialize us into an error state.
00106         void ConstructAsError(const char *msg);
00107 
00108         //reads all data from a static finite source.
00109         void ReadAllStaticSourceData(Source *source, std::vector<uint8> &data);
00110 
00111         //catches the streaming data up to date on a player/buffer set
00112         void UpdateStreamingPlayerBuffer(InternalSharedBufferData::PlayerBuffers &pb, bool isInitialRead=false);
00113 
00114         //frees the resources associated with a playerbuffer and removes it from the list
00115         void FreePlayerBuffer(InternalSharedBufferData::PlayerBuffers *pb);
00116 
00117         friend class Player;
00118         friend class AUDIO_INTERNAL::BackgroundProcessing;
00119     };
00120 
00121 }
00122 
00123 #endif //#ifdef MPMA_COMPILE_AUDIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends