gxaudio.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #include "std.h"
  2. #include "gxaudio.h"
  3. struct StaticChannel : public gxChannel{
  4. virtual void play()=0;
  5. };
  6. struct SoundChannel : public gxChannel{
  7. SoundChannel():channel(-1){
  8. }
  9. void set( int n ){
  10. channel=n;
  11. }
  12. void stop(){
  13. FSOUND_StopSound( channel );
  14. }
  15. void setPaused( bool paused ){
  16. FSOUND_SetPaused( channel,paused );
  17. }
  18. void setPitch( int pitch ){
  19. FSOUND_SetFrequency( channel,pitch );
  20. }
  21. void setVolume( float volume ){
  22. FSOUND_SetVolume( channel,volume * 255.0f );
  23. }
  24. void setPan( float pan ){
  25. FSOUND_SetPan( channel,(pan+1)*127.5f );
  26. }
  27. void set3d( const float pos[3],const float vel[3] ){
  28. FSOUND_3D_SetAttributes( channel,(float*)pos,(float*)vel );
  29. }
  30. bool isPlaying(){
  31. return FSOUND_IsPlaying( channel ) ? true : false;
  32. }
  33. private:
  34. int channel;
  35. };
  36. struct CDChannel : public gxChannel{
  37. void play( int track,int mode ){
  38. stop();
  39. int cd_mode=FSOUND_CD_PLAYONCE;
  40. if( mode==gxAudio::CD_MODE_LOOP ) cd_mode=FSOUND_CD_PLAYLOOPED;
  41. else if( mode==gxAudio::CD_MODE_ALL ) cd_mode=FSOUND_CD_PLAYCONTINUOUS;
  42. FSOUND_CD_SetPlayMode( 0,cd_mode );
  43. FSOUND_CD_Play( 0,track );
  44. }
  45. void stop(){
  46. FSOUND_CD_Stop(0 );
  47. }
  48. void setPaused( bool paused ){
  49. FSOUND_CD_SetPaused( 0,paused );
  50. }
  51. void setPitch( int pitch ){
  52. }
  53. void setVolume( float volume ){
  54. FSOUND_CD_SetVolume( 0,volume*255.0f );
  55. }
  56. void setPan( float pan ){
  57. }
  58. void set3d( const float pos[3],const float vel[3] ){
  59. }
  60. bool isPlaying(){
  61. return true;
  62. }
  63. };
  64. struct StreamChannel : public StaticChannel{
  65. StreamChannel( FSOUND_STREAM *s ):stream(s){
  66. channel=FSOUND_Stream_Play( FSOUND_FREE,stream );
  67. }
  68. ~StreamChannel(){
  69. FSOUND_Stream_Close( stream );
  70. }
  71. void play(){
  72. stop();
  73. channel=FSOUND_Stream_Play( FSOUND_FREE,stream );
  74. }
  75. void stop(){
  76. FSOUND_Stream_Stop( stream );
  77. channel=-1;
  78. }
  79. void setPaused( bool paused ){
  80. FSOUND_SetPaused( channel,paused );
  81. }
  82. void setPitch( int pitch ){
  83. FSOUND_SetFrequency( channel,pitch );
  84. }
  85. void setVolume( float volume ){
  86. FSOUND_SetVolume( channel,volume * 255.0f );
  87. }
  88. void setPan( float pan ){
  89. FSOUND_SetPan( channel,(pan+1)*127.5f );
  90. }
  91. void set3d( const float pos[3],const float vel[3] ){
  92. }
  93. bool isPlaying(){
  94. return FSOUND_IsPlaying( channel ) ? true : false;
  95. }
  96. private:
  97. FSOUND_STREAM *stream;
  98. int channel;
  99. };
  100. struct MusicChannel : public StaticChannel{
  101. MusicChannel( FMUSIC_MODULE *m ):module(m){
  102. play();
  103. }
  104. ~MusicChannel(){
  105. FMUSIC_FreeSong( module );
  106. }
  107. void play(){
  108. FMUSIC_PlaySong( module );
  109. }
  110. void stop(){
  111. FMUSIC_StopSong( module );
  112. }
  113. void setPaused( bool paused ){
  114. FMUSIC_SetPaused( module,paused );
  115. }
  116. void setPitch( int pitch ){
  117. }
  118. void setVolume( float volume ){
  119. FMUSIC_SetMasterVolume( module,volume*255.0f );
  120. }
  121. void setPan( float pan ){
  122. }
  123. void set3d( const float pos[3],const float vel[3] ){
  124. }
  125. bool isPlaying(){
  126. return FMUSIC_IsFinished( module ) ? false : true;
  127. }
  128. private:
  129. FMUSIC_MODULE *module;
  130. };
  131. static set<gxSound*> sound_set;
  132. static vector<gxChannel*> channels;
  133. static map<string,StaticChannel*> songs;
  134. static CDChannel *cdChannel;
  135. static int next_chan;
  136. static vector<SoundChannel*> soundChannels;
  137. static gxChannel *allocSoundChannel( int n ){
  138. SoundChannel *chan=0;
  139. for( int k=0;k<soundChannels.size();++k ){
  140. chan=soundChannels[next_chan];
  141. if( !chan ){
  142. chan=soundChannels[next_chan]=d_new SoundChannel();
  143. channels.push_back(chan);
  144. }else if( chan->isPlaying() ){
  145. chan=0;
  146. }
  147. if( ++next_chan==soundChannels.size() ) next_chan=0;
  148. if( chan ) break;
  149. }
  150. if( !chan ){
  151. next_chan=soundChannels.size();
  152. soundChannels.resize(soundChannels.size()*2);
  153. for( int k=next_chan;k<soundChannels.size();++k ) soundChannels[k]=0;
  154. chan=soundChannels[next_chan++]=d_new SoundChannel();
  155. channels.push_back( chan );
  156. }
  157. chan->set(n);
  158. return chan;
  159. }
  160. gxAudio::gxAudio( gxRuntime *r ):
  161. runtime(r){
  162. next_chan=0;
  163. soundChannels.resize( 4096 );
  164. for( int k=0;k<4096;++k ) soundChannels[k]=0;
  165. cdChannel=d_new CDChannel();
  166. channels.push_back( cdChannel );
  167. }
  168. gxAudio::~gxAudio(){
  169. //free all channels
  170. for( ;channels.size();channels.pop_back() ) delete channels.back();
  171. //free all sound_set
  172. while( sound_set.size() ) freeSound( *sound_set.begin() );
  173. soundChannels.clear();
  174. songs.clear();
  175. FSOUND_Close();
  176. }
  177. gxChannel *gxAudio::play( FSOUND_SAMPLE *sample ){
  178. int n=FSOUND_PlaySound( FSOUND_FREE,sample );
  179. return n>=0 ? allocSoundChannel( n ) : 0;
  180. }
  181. gxChannel *gxAudio::play3d( FSOUND_SAMPLE *sample,const float pos[3],const float vel[3] ){
  182. int n=FSOUND_PlaySoundEx( FSOUND_FREE,sample,0,true );
  183. if( n<0 ) return 0;
  184. FSOUND_3D_SetAttributes( n,(float*)pos,(float*)vel );
  185. FSOUND_SetPaused( n,false );
  186. return allocSoundChannel( n );
  187. }
  188. void gxAudio::pause(){
  189. }
  190. void gxAudio::resume(){
  191. }
  192. gxSound *gxAudio::loadSound( const string &f,bool use3d ){
  193. int flags=FSOUND_NORMAL | (use3d ? FSOUND_FORCEMONO : FSOUND_2D);
  194. FSOUND_SAMPLE *sample=FSOUND_Sample_Load( FSOUND_FREE,f.c_str(),flags,0,0 );
  195. if( !sample ) return 0;
  196. gxSound *sound=d_new gxSound( this,sample );
  197. sound_set.insert( sound );
  198. return sound;
  199. }
  200. gxSound *gxAudio::verifySound( gxSound *s ){
  201. return sound_set.count( s ) ? s : 0;
  202. }
  203. void gxAudio::freeSound( gxSound *s ){
  204. if( sound_set.erase( s ) ) delete s;
  205. }
  206. void gxAudio::setPaused( bool paused ){
  207. FSOUND_SetPaused( FSOUND_ALL,paused );
  208. }
  209. void gxAudio::setVolume( float volume ){
  210. }
  211. void gxAudio::set3dOptions( float roll,float dopp,float dist ){
  212. FSOUND_3D_SetRolloffFactor( roll );
  213. FSOUND_3D_SetDopplerFactor( dopp );
  214. FSOUND_3D_SetDistanceFactor( dist );
  215. }
  216. void gxAudio::set3dListener( const float pos[3],const float vel[3],const float forward[3],const float up[3] ){
  217. FSOUND_3D_Listener_SetAttributes( (float*)pos,(float*)vel,forward[0],forward[1],forward[2],up[0],up[1],up[2] );
  218. FSOUND_Update();
  219. }
  220. gxChannel *gxAudio::playFile( const string &t,bool use_3d ){
  221. string f=tolower( t );
  222. StaticChannel *chan=0;
  223. map<string,StaticChannel*>::iterator it=songs.find(f);
  224. if( it!=songs.end() ){
  225. chan=it->second;
  226. chan->play();
  227. return chan;
  228. }else if(
  229. f.find( ".raw" )!=string::npos ||
  230. f.find( ".wav" )!=string::npos ||
  231. f.find( ".mp2" )!=string::npos ||
  232. f.find( ".mp3" )!=string::npos ||
  233. f.find( ".ogg" )!=string::npos ||
  234. f.find( ".wma" )!=string::npos ||
  235. f.find( ".asf" )!=string::npos ){
  236. FSOUND_STREAM *stream=FSOUND_Stream_Open( f.c_str(),use_3d,0,0 );
  237. if( !stream ) return 0;
  238. chan=d_new StreamChannel( stream );
  239. }else{
  240. FMUSIC_MODULE *module=FMUSIC_LoadSong( f.c_str() );
  241. if( !module ) return 0;
  242. chan=d_new MusicChannel( module );
  243. }
  244. channels.push_back( chan );
  245. songs[f]=chan;
  246. return chan;
  247. }
  248. gxChannel *gxAudio::playCDTrack( int track,int mode ){
  249. cdChannel->play( track,mode );
  250. return cdChannel;
  251. }