sound.cpp
上传用户:maxiaolivb
上传日期:2022-06-07
资源大小:915k
文件大小:9k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. ** Haaf's Game Engine 1.5
  3. ** Copyright (C) 2003-2004, Relish Games
  4. ** hge.relishgames.com
  5. **
  6. ** Core functions implementation: audio routines
  7. */
  8. #include "hge_impl.h"
  9. #define BASSDEF(f) (WINAPI *f) // define the functions as pointers
  10. #include "BASSbass.h"
  11. #define LOADBASSFUNCTION(f) *((void**)&f)=(void*)GetProcAddress(hBass,#f)
  12. HEFFECT CALL HGE_Impl::Effect_Load(const char *filename, DWORD size)
  13. {
  14. DWORD _size, length, samples;
  15. HSAMPLE hs;
  16. HSTREAM hstrm;
  17. BASS_CHANNELINFO info;
  18. void *buffer, *data;
  19. if(hBass)
  20. {
  21. if(bSilent) return 1;
  22. if(size) { data=(void *)filename; _size=size; }
  23. else
  24. {
  25. data=Resource_Load(filename, &_size);
  26. if(!data) return NULL;
  27. }
  28. hs=BASS_SampleLoad(TRUE, data, 0, _size, 4, BASS_SAMPLE_OVER_VOL);
  29. if(!hs) {
  30. hstrm=BASS_StreamCreateFile(TRUE, data, 0, _size, BASS_STREAM_DECODE);
  31. if(hstrm) {
  32. length=(DWORD)BASS_ChannelGetLength(hstrm);
  33. BASS_ChannelGetInfo(hstrm, &info);
  34. samples=length;
  35. if(info.chans < 2) samples>>=1;
  36. if(info.flags & BASS_SAMPLE_8BITS == 0) samples>>=1;
  37. buffer=BASS_SampleCreate(samples, info.freq, 2, 4, info.flags | BASS_SAMPLE_OVER_VOL);
  38. if(!buffer)
  39. {
  40. BASS_StreamFree(hstrm);
  41. _PostError("Can't create sound effect: Not enough memory");
  42. }
  43. else
  44. {
  45. BASS_ChannelGetData(hstrm, buffer, length);
  46. hs=BASS_SampleCreateDone();
  47. BASS_StreamFree(hstrm);
  48. if(!hs) _PostError("Can't create sound effect");
  49. }
  50. }
  51. }
  52. if(!size) Resource_Free(data);
  53. return hs;
  54. }
  55. else return 0;
  56. }
  57. HCHANNEL CALL HGE_Impl::Effect_Play(HEFFECT eff)
  58. {
  59. if(hBass)
  60. {
  61. HCHANNEL chn;
  62. chn=BASS_SampleGetChannel(eff, FALSE);
  63. BASS_ChannelPlay(chn, TRUE);
  64. return chn;
  65. }
  66. else return 0;
  67. }
  68. HCHANNEL CALL HGE_Impl::Effect_PlayEx(HEFFECT eff, int volume, int pan, float pitch, bool loop)
  69. {
  70. if(hBass)
  71. {
  72. BASS_SAMPLE info;
  73. HCHANNEL chn;
  74. BASS_SampleGetInfo(eff, &info);
  75. chn=BASS_SampleGetChannel(eff, FALSE);
  76. BASS_ChannelSetAttributes(chn, (int)(pitch*info.freq), volume, pan);
  77. BASS_ChannelSetFlags(chn, loop ? BASS_SAMPLE_LOOP:0);
  78. BASS_ChannelPlay(chn, TRUE);
  79. return chn;
  80. }
  81. else return 0;
  82. }
  83. void CALL HGE_Impl::Effect_Free(HEFFECT eff)
  84. {
  85. if(hBass) BASS_SampleFree(eff);
  86. }
  87. HMUSIC CALL HGE_Impl::Music_Load(const char *filename, DWORD size)
  88. {
  89. void *data;
  90. DWORD _size;
  91. HMUSIC hm;
  92. if(hBass)
  93. {
  94. if(size) { data=(void *)filename; _size=size; }
  95. else
  96. {
  97. data=Resource_Load(filename, &_size);
  98. if(!data) return 0;
  99. }
  100. hm=BASS_MusicLoad(TRUE, data, 0, _size, (BASS_MUSIC_PRESCAN | BASS_MUSIC_POSRESET), 0);
  101. if(!hm) _PostError("Can't load music");
  102. if(!size) Resource_Free(data);
  103. return hm;
  104. }
  105. else return 0;
  106. }
  107. HCHANNEL CALL HGE_Impl::Music_Play(HMUSIC mus, bool loop)
  108. {
  109. if(hBass)
  110. {
  111. BASS_CHANNELINFO info;
  112. BASS_ChannelGetInfo(mus, &info);
  113. BASS_ChannelSetAttributes(mus, info.freq, 100, 0);
  114. BASS_ChannelSetFlags(mus, loop ? BASS_SAMPLE_LOOP:0);
  115. BASS_ChannelPlay(mus, TRUE);
  116. return mus;
  117. }
  118. else return 0;
  119. }
  120. void CALL HGE_Impl::Music_Free(HMUSIC mus)
  121. {
  122. if(hBass) BASS_MusicFree(mus);
  123. }
  124. HSTREAM CALL HGE_Impl::Stream_Load(const char *filename, DWORD size)
  125. {
  126. void *data;
  127. DWORD _size;
  128. HSTREAM hs;
  129. CStreamList *stmItem;
  130. if(hBass)
  131. {
  132. if(bSilent) return 1;
  133. if(size) { data=(void *)filename; _size=size; }
  134. else
  135. {
  136. data=Resource_Load(filename, &_size);
  137. if(!data) return 0;
  138. }
  139. hs=BASS_StreamCreateFile(TRUE, data, 0, _size, 0);
  140. if(!hs)
  141. {
  142. _PostError("Can't load stream");
  143. if(!size) Resource_Free(data);
  144. return 0;
  145. }
  146. if(!size)
  147. {
  148. stmItem=new CStreamList;
  149. stmItem->hstream=hs;
  150. stmItem->data=data;
  151. stmItem->next=streams;
  152. streams=stmItem;
  153. }
  154. return hs;
  155. }
  156. else return 0;
  157. }
  158. void CALL HGE_Impl::Stream_Free(HSTREAM stream)
  159. {
  160. CStreamList *stmItem=streams, *stmPrev=0;
  161. if(hBass)
  162. {
  163. while(stmItem)
  164. {
  165. if(stmItem->hstream==stream)
  166. {
  167. if(stmPrev) stmPrev->next=stmItem->next;
  168. else streams=stmItem->next;
  169. Resource_Free(stmItem->data);
  170. delete stmItem;
  171. break;
  172. }
  173. stmPrev=stmItem;
  174. stmItem=stmItem->next;
  175. }
  176. BASS_StreamFree(stream);
  177. }
  178. }
  179. HCHANNEL CALL HGE_Impl::Stream_Play(HSTREAM stream, bool loop, int volume)
  180. {
  181. if(hBass)
  182. {
  183. BASS_CHANNELINFO info;
  184. BASS_ChannelGetInfo(stream, &info);
  185. BASS_ChannelSetAttributes(stream, info.freq, volume, 0);
  186. BASS_ChannelSetFlags(stream, loop ? BASS_SAMPLE_LOOP:0);
  187. BASS_ChannelPlay(stream, TRUE);
  188. return stream;
  189. }
  190. else return 0;
  191. }
  192. void CALL HGE_Impl::Channel_SetPanning(HCHANNEL chn, int pan)
  193. {
  194. if(hBass) BASS_ChannelSetAttributes(chn, -1, -1, pan);
  195. }
  196. void CALL HGE_Impl::Channel_SetVolume(HCHANNEL chn, int volume)
  197. {
  198. if(hBass) BASS_ChannelSetAttributes(chn, -1, volume, -101);
  199. }
  200. void CALL HGE_Impl::Channel_SetPitch(HCHANNEL chn, float pitch)
  201. {
  202. if(hBass)
  203. {
  204. BASS_CHANNELINFO info;
  205. BASS_ChannelGetInfo(chn, &info);
  206. BASS_ChannelSetAttributes(chn, (int)(pitch*info.freq), -1, -101);
  207. }
  208. }
  209. void CALL HGE_Impl::Channel_Pause(HCHANNEL chn)
  210. {
  211. if(hBass) BASS_ChannelPause(chn);
  212. }
  213. void CALL HGE_Impl::Channel_Resume(HCHANNEL chn)
  214. {
  215. if(hBass) BASS_ChannelPlay(chn, FALSE);
  216. }
  217. void CALL HGE_Impl::Channel_Stop(HCHANNEL chn)
  218. {
  219. if(hBass) BASS_ChannelStop(chn);
  220. }
  221. void CALL HGE_Impl::Channel_StopAll()
  222. {
  223. if(hBass) { BASS_Stop();BASS_Start(); }
  224. }
  225. bool CALL HGE_Impl::Channel_IsPlaying(HCHANNEL chn)
  226. {
  227. if(hBass)
  228. {
  229. if(BASS_ChannelIsActive(chn)==BASS_ACTIVE_PLAYING) return true;
  230. else return false;
  231. }
  232. else return false;
  233. }
  234. float CALL HGE_Impl::Channel_GetLength(HCHANNEL chn) {
  235. if(hBass)
  236. {
  237. return BASS_ChannelBytes2Seconds(chn, BASS_ChannelGetLength(chn));
  238. }
  239. else return -1;
  240. }
  241. float CALL HGE_Impl::Channel_GetPos(HCHANNEL chn) {
  242. if(hBass)
  243. {
  244. return BASS_ChannelBytes2Seconds(chn, BASS_ChannelGetPosition(chn));
  245. }
  246. else return -1;
  247. }
  248. void CALL HGE_Impl::Channel_SetPos(HCHANNEL chn, float fSeconds) {
  249. if(hBass)
  250. {
  251. BASS_ChannelSetPosition(chn, BASS_ChannelSeconds2Bytes(chn, fSeconds));
  252. }
  253. }
  254. //////// Implementation ////////
  255. bool HGE_Impl::_SoundInit()
  256. {
  257. if(!bUseSound || hBass) return true;
  258. hBass=LoadLibrary("bass.dll");
  259. if (!hBass)
  260. {
  261. _PostError("Can't load BASS.DLL");
  262. return false;
  263. }
  264. LOADBASSFUNCTION(BASS_GetVersion);
  265. if (BASS_GetVersion()!=MAKELONG(2,2))
  266. {
  267. _PostError("Incorrect BASS.DLL version");
  268. return false;
  269. }
  270. LOADBASSFUNCTION(BASS_GetDeviceDescription);
  271. LOADBASSFUNCTION(BASS_Init);
  272. LOADBASSFUNCTION(BASS_Free);
  273. LOADBASSFUNCTION(BASS_Start);
  274. LOADBASSFUNCTION(BASS_Stop);
  275. LOADBASSFUNCTION(BASS_SetConfig);
  276. LOADBASSFUNCTION(BASS_SampleLoad);
  277. LOADBASSFUNCTION(BASS_SampleCreate);
  278. LOADBASSFUNCTION(BASS_SampleCreateDone);
  279. LOADBASSFUNCTION(BASS_SampleGetInfo);
  280. LOADBASSFUNCTION(BASS_SampleGetChannel);
  281. LOADBASSFUNCTION(BASS_SampleFree);
  282. LOADBASSFUNCTION(BASS_MusicLoad);
  283. LOADBASSFUNCTION(BASS_MusicFree);
  284. LOADBASSFUNCTION(BASS_StreamCreateFile);
  285. LOADBASSFUNCTION(BASS_StreamFree);
  286. LOADBASSFUNCTION(BASS_ChannelGetInfo);
  287. LOADBASSFUNCTION(BASS_ChannelGetAttributes);
  288. LOADBASSFUNCTION(BASS_ChannelSetAttributes);
  289. LOADBASSFUNCTION(BASS_ChannelSetFlags);
  290. LOADBASSFUNCTION(BASS_ChannelGetData);
  291. LOADBASSFUNCTION(BASS_ChannelPlay);
  292. LOADBASSFUNCTION(BASS_ChannelPause);
  293. LOADBASSFUNCTION(BASS_ChannelStop);
  294. LOADBASSFUNCTION(BASS_ChannelIsActive);
  295. LOADBASSFUNCTION(BASS_ChannelGetLength);
  296. LOADBASSFUNCTION(BASS_ChannelGetPosition);
  297. LOADBASSFUNCTION(BASS_ChannelSetPosition);
  298. LOADBASSFUNCTION(BASS_ChannelSeconds2Bytes);
  299. LOADBASSFUNCTION(BASS_ChannelBytes2Seconds);
  300. bSilent=false;
  301. if (!BASS_Init(1,nSampleRate,0,hwnd,NULL))
  302. {
  303. System_Log("BASS Init failed, using no sound");
  304. BASS_Init(0,nSampleRate,0,hwnd,NULL);
  305. bSilent=true;
  306. }
  307. else
  308. {
  309. System_Log("Sound Device: %s",BASS_GetDeviceDescription(1));
  310. System_Log("Sample rate: %ldn", nSampleRate);
  311. }
  312. _SetFXVolume(nFXVolume);
  313. _SetMusVolume(nMusVolume);
  314. return true;
  315. }
  316. void HGE_Impl::_SoundDone()
  317. {
  318. CStreamList *stmItem=streams, *stmNext;
  319. if(hBass)
  320. {
  321. BASS_Stop();
  322. BASS_Free();
  323. FreeLibrary(hBass);
  324. hBass=0;
  325. while(stmItem)
  326. {
  327. stmNext=stmItem->next;
  328. Resource_Free(stmItem->data);
  329. delete stmItem;
  330. stmItem=stmNext;
  331. }
  332. streams=0;
  333. }
  334. }
  335. void HGE_Impl::_SetMusVolume(int vol)
  336. {
  337. if(hBass) BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, vol);
  338. }
  339. void HGE_Impl::_SetFXVolume(int vol)
  340. {
  341. if(hBass) BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, vol);
  342. }