00001 /* RageSoundReader_Chain - Chain sounds together */ 00002 00003 #ifndef RAGE_SOUND_READER_CHAIN 00004 #define RAGE_SOUND_READER_CHAIN 00005 00006 #include "RageSoundReader.h" 00007 00008 #include <map> 00009 #include <set> 00010 00011 class RageSoundReader_Chain: public SoundReader 00012 { 00013 public: 00014 RageSoundReader_Chain(); 00015 ~RageSoundReader_Chain(); 00016 SoundReader *Copy() const; 00017 00018 /* Set the preferred sample rate. This will only be used if the source sounds 00019 * use different sample rates. */ 00020 void SetPreferredSampleRate( int iSampleRate ) { m_iPreferredSampleRate = iSampleRate; } 00021 00022 /* Add the given sound to play after fOffsetSecs seconds. Takes ownership 00023 * of pSound. */ 00024 bool AddSound( CString sPath, float fOffsetSecs, float fPan ); 00025 00026 /* Finish adding sounds. */ 00027 void Finish(); 00028 00029 int GetLength() const; 00030 int GetLength_Fast() const; 00031 int SetPosition_Accurate( int ms ); 00032 /* It rarely makes sense to set an approximate time for a chained sound, since any 00033 * error in overlap will become obvious. */ 00034 int SetPosition_Fast( int ms ) { return SetPosition_Accurate( ms ); } 00035 int Read( char *buf, unsigned len ); 00036 int GetSampleRate() const { return m_iActualSampleRate; } 00037 unsigned GetNumChannels() const { return m_iChannels; } 00038 bool IsStreamingFromDisk() const; 00039 00040 private: 00041 int ReadBlock( int16_t *pBuffer, int iFrames ); 00042 int GetSampleRateInternal() const; 00043 00044 int m_iPreferredSampleRate; 00045 int m_iActualSampleRate; 00046 unsigned m_iChannels; 00047 00048 map<CString, SoundReader *> m_apLoadedSounds; 00049 00050 struct sound 00051 { 00052 CString sPath; 00053 int iOffsetMS; 00054 float fPan; 00055 int GetOffsetFrame( int iSampleRate ) const { return int( int64_t(iOffsetMS) * iSampleRate / 1000 ); } 00056 bool operator<( const sound &rhs ) const { return iOffsetMS < rhs.iOffsetMS; } 00057 }; 00058 vector<sound> m_Sounds; 00059 unsigned GetNextSoundIndex() const; 00060 00061 /* Read state: */ 00062 int m_iCurrentFrame; 00063 unsigned m_iNextSound; 00064 struct ActiveSound 00065 { 00066 SoundReader *pSound; 00067 float fPan; 00068 bool operator< ( const ActiveSound &rhs ) const { return pSound < rhs.pSound; } 00069 }; 00070 vector<ActiveSound> m_apActiveSounds; 00071 unsigned ActivateSound( const sound &s ); 00072 void ReleaseSound( unsigned n ); 00073 }; 00074 00075 #endif 00076 00077 /* 00078 * Copyright (c) 2004 Glenn Maynard 00079 * All rights reserved. 00080 * 00081 * Permission is hereby granted, free of charge, to any person obtaining a 00082 * copy of this software and associated documentation files (the 00083 * "Software"), to deal in the Software without restriction, including 00084 * without limitation the rights to use, copy, modify, merge, publish, 00085 * distribute, and/or sell copies of the Software, and to permit persons to 00086 * whom the Software is furnished to do so, provided that the above 00087 * copyright notice(s) and this permission notice appear in all copies of 00088 * the Software and that both the above copyright notice(s) and this 00089 * permission notice appear in supporting documentation. 00090 * 00091 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00092 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00093 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 00094 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS 00095 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT 00096 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 00097 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00098 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00099 * PERFORMANCE OF THIS SOFTWARE. 00100 */