sound.cpp
上传用户:jnfxsk
上传日期:2022-06-16
资源大小:3675k
文件大小:12k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. ** Haaf's Game Engine 1.8
  3. ** Copyright (C) 2003-2007, 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. info.flags &= ~BASS_SAMPLE_LOOP;
  78. if(loop) info.flags |= BASS_SAMPLE_LOOP;
  79. BASS_ChannelSetFlags(chn, info.flags);
  80. BASS_ChannelPlay(chn, TRUE);
  81. return chn;
  82. }
  83. else return 0;
  84. }
  85. void CALL HGE_Impl::Effect_Free(HEFFECT eff)
  86. {
  87. if(hBass) BASS_SampleFree(eff);
  88. }
  89. HMUSIC CALL HGE_Impl::Music_Load(const char *filename, DWORD size)
  90. {
  91. void *data;
  92. DWORD _size;
  93. HMUSIC hm;
  94. if(hBass)
  95. {
  96. if(size)
  97. {
  98. data=(void *)filename;
  99. _size=size;
  100. }
  101. else
  102. {
  103. data=Resource_Load(filename, &_size);
  104. if(!data) return 0;
  105. }
  106. hm=BASS_MusicLoad(TRUE, data, 0, 0, BASS_MUSIC_PRESCAN | BASS_MUSIC_POSRESETEX | BASS_MUSIC_RAMP, 0);
  107. if(!hm) _PostError("Can't load music");
  108. if(!size) Resource_Free(data);
  109. return hm;
  110. }
  111. else return 0;
  112. }
  113. HCHANNEL CALL HGE_Impl::Music_Play(HMUSIC mus, bool loop, int volume, int order, int row)
  114. {
  115. if(hBass)
  116. {
  117. DWORD pos = BASS_MusicGetOrderPosition(mus);
  118. if(order == -1) order = LOWORD(pos);
  119. if(row == -1) row = HIWORD(pos);
  120. BASS_ChannelSetPosition(mus, MAKEMUSICPOS(order, row));
  121. BASS_CHANNELINFO info;
  122. BASS_ChannelGetInfo(mus, &info);
  123. BASS_ChannelSetAttributes(mus, info.freq, volume, 0);
  124. info.flags &= ~BASS_SAMPLE_LOOP;
  125. if(loop) info.flags |= BASS_SAMPLE_LOOP;
  126. BASS_ChannelSetFlags(mus, info.flags);
  127. BASS_ChannelPlay(mus, FALSE);
  128. return mus;
  129. }
  130. else return 0;
  131. }
  132. void CALL HGE_Impl::Music_Free(HMUSIC mus)
  133. {
  134. if(hBass) BASS_MusicFree(mus);
  135. }
  136. void CALL HGE_Impl::Music_SetAmplification(HMUSIC music, int ampl)
  137. {
  138. if(hBass) BASS_MusicSetAttribute(music, BASS_MUSIC_ATTRIB_AMPLIFY, ampl);
  139. }
  140. int CALL HGE_Impl::Music_GetAmplification(HMUSIC music)
  141. {
  142. if(hBass) return BASS_MusicGetAttribute(music, BASS_MUSIC_ATTRIB_AMPLIFY);
  143. else return -1;
  144. }
  145. int CALL HGE_Impl::Music_GetLength(HMUSIC music)
  146. {
  147. if(hBass)
  148. {
  149. return BASS_MusicGetOrders(music);
  150. }
  151. else return -1;
  152. }
  153. void CALL HGE_Impl::Music_SetPos(HMUSIC music, int order, int row)
  154. {
  155. if(hBass)
  156. {
  157. BASS_ChannelSetPosition(music, MAKEMUSICPOS(order, row));
  158. }
  159. }
  160. bool CALL HGE_Impl::Music_GetPos(HMUSIC music, int *order, int *row)
  161. {
  162. if(hBass)
  163. {
  164. DWORD pos;
  165. pos = BASS_MusicGetOrderPosition(music);
  166. if(pos == -1) return false;
  167. *order = LOWORD(pos);
  168. *row = HIWORD(pos);
  169. return true;
  170. }
  171. else return false;
  172. }
  173. void CALL HGE_Impl::Music_SetInstrVolume(HMUSIC music, int instr, int volume)
  174. {
  175. if(hBass)
  176. {
  177. BASS_MusicSetAttribute(music, BASS_MUSIC_ATTRIB_VOL_INST + instr, volume);
  178. }
  179. }
  180. int CALL HGE_Impl::Music_GetInstrVolume(HMUSIC music, int instr)
  181. {
  182. if(hBass)
  183. {
  184. return BASS_MusicGetAttribute(music, BASS_MUSIC_ATTRIB_VOL_INST + instr);
  185. }
  186. else return -1;
  187. }
  188. void CALL HGE_Impl::Music_SetChannelVolume(HMUSIC music, int channel, int volume)
  189. {
  190. if(hBass)
  191. {
  192. BASS_MusicSetAttribute(music, BASS_MUSIC_ATTRIB_VOL_CHAN + channel, volume);
  193. }
  194. }
  195. int CALL HGE_Impl::Music_GetChannelVolume(HMUSIC music, int channel)
  196. {
  197. if(hBass)
  198. {
  199. return BASS_MusicGetAttribute(music, BASS_MUSIC_ATTRIB_VOL_CHAN + channel);
  200. }
  201. else return -1;
  202. }
  203. HSTREAM CALL HGE_Impl::Stream_Load(const char *filename, DWORD size)
  204. {
  205. void *data;
  206. DWORD _size;
  207. HSTREAM hs;
  208. CStreamList *stmItem;
  209. if(hBass)
  210. {
  211. if(bSilent) return 1;
  212. if(size) { data=(void *)filename; _size=size; }
  213. else
  214. {
  215. data=Resource_Load(filename, &_size);
  216. if(!data) return 0;
  217. }
  218. hs=BASS_StreamCreateFile(TRUE, data, 0, _size, 0);
  219. if(!hs)
  220. {
  221. _PostError("Can't load stream");
  222. if(!size) Resource_Free(data);
  223. return 0;
  224. }
  225. if(!size)
  226. {
  227. stmItem=new CStreamList;
  228. stmItem->hstream=hs;
  229. stmItem->data=data;
  230. stmItem->next=streams;
  231. streams=stmItem;
  232. }
  233. return hs;
  234. }
  235. else return 0;
  236. }
  237. void CALL HGE_Impl::Stream_Free(HSTREAM stream)
  238. {
  239. CStreamList *stmItem=streams, *stmPrev=0;
  240. if(hBass)
  241. {
  242. while(stmItem)
  243. {
  244. if(stmItem->hstream==stream)
  245. {
  246. if(stmPrev) stmPrev->next=stmItem->next;
  247. else streams=stmItem->next;
  248. Resource_Free(stmItem->data);
  249. delete stmItem;
  250. break;
  251. }
  252. stmPrev=stmItem;
  253. stmItem=stmItem->next;
  254. }
  255. BASS_StreamFree(stream);
  256. }
  257. }
  258. HCHANNEL CALL HGE_Impl::Stream_Play(HSTREAM stream, bool loop, int volume)
  259. {
  260. if(hBass)
  261. {
  262. BASS_CHANNELINFO info;
  263. BASS_ChannelGetInfo(stream, &info);
  264. BASS_ChannelSetAttributes(stream, info.freq, volume, 0);
  265. info.flags &= ~BASS_SAMPLE_LOOP;
  266. if(loop) info.flags |= BASS_SAMPLE_LOOP;
  267. BASS_ChannelSetFlags(stream, info.flags);
  268. BASS_ChannelPlay(stream, TRUE);
  269. return stream;
  270. }
  271. else return 0;
  272. }
  273. void CALL HGE_Impl::Channel_SetPanning(HCHANNEL chn, int pan)
  274. {
  275. if(hBass) BASS_ChannelSetAttributes(chn, -1, -1, pan);
  276. }
  277. void CALL HGE_Impl::Channel_SetVolume(HCHANNEL chn, int volume)
  278. {
  279. if(hBass) BASS_ChannelSetAttributes(chn, -1, volume, -101);
  280. }
  281. void CALL HGE_Impl::Channel_SetPitch(HCHANNEL chn, float pitch)
  282. {
  283. if(hBass)
  284. {
  285. BASS_CHANNELINFO info;
  286. BASS_ChannelGetInfo(chn, &info);
  287. BASS_ChannelSetAttributes(chn, (int)(pitch*info.freq), -1, -101);
  288. }
  289. }
  290. void CALL HGE_Impl::Channel_Pause(HCHANNEL chn)
  291. {
  292. if(hBass) BASS_ChannelPause(chn);
  293. }
  294. void CALL HGE_Impl::Channel_Resume(HCHANNEL chn)
  295. {
  296. if(hBass) BASS_ChannelPlay(chn, FALSE);
  297. }
  298. void CALL HGE_Impl::Channel_Stop(HCHANNEL chn)
  299. {
  300. if(hBass) BASS_ChannelStop(chn);
  301. }
  302. void CALL HGE_Impl::Channel_PauseAll()
  303. {
  304. if(hBass) BASS_Pause();
  305. }
  306. void CALL HGE_Impl::Channel_ResumeAll()
  307. {
  308. if(hBass) BASS_Start();
  309. }
  310. void CALL HGE_Impl::Channel_StopAll()
  311. {
  312. if(hBass)
  313. {
  314. BASS_Stop();
  315. BASS_Start();
  316. }
  317. }
  318. bool CALL HGE_Impl::Channel_IsPlaying(HCHANNEL chn)
  319. {
  320. if(hBass)
  321. {
  322. if(BASS_ChannelIsActive(chn)==BASS_ACTIVE_PLAYING) return true;
  323. else return false;
  324. }
  325. else return false;
  326. }
  327. float CALL HGE_Impl::Channel_GetLength(HCHANNEL chn) {
  328. if(hBass)
  329. {
  330. return BASS_ChannelBytes2Seconds(chn, BASS_ChannelGetLength(chn));
  331. }
  332. else return -1;
  333. }
  334. float CALL HGE_Impl::Channel_GetPos(HCHANNEL chn) {
  335. if(hBass)
  336. {
  337. return BASS_ChannelBytes2Seconds(chn, BASS_ChannelGetPosition(chn));
  338. }
  339. else return -1;
  340. }
  341. void CALL HGE_Impl::Channel_SetPos(HCHANNEL chn, float fSeconds) {
  342. if(hBass)
  343. {
  344. BASS_ChannelSetPosition(chn, BASS_ChannelSeconds2Bytes(chn, fSeconds));
  345. }
  346. }
  347. void CALL HGE_Impl::Channel_SlideTo(HCHANNEL channel, float time, int volume, int pan, float pitch)
  348. {
  349. if(hBass)
  350. {
  351. BASS_CHANNELINFO info;
  352. BASS_ChannelGetInfo(channel, &info);
  353. int freq;
  354. if(pitch == -1) freq = -1;
  355. else freq = (int)(pitch*info.freq);
  356. BASS_ChannelSlideAttributes(channel, freq, volume, pan, DWORD(time*1000));
  357. }
  358. }
  359. bool CALL HGE_Impl::Channel_IsSliding(HCHANNEL channel)
  360. {
  361. if(hBass)
  362. {
  363. if(BASS_ChannelIsSliding(channel)) return true;
  364. else return false;
  365. }
  366. else return false;
  367. }
  368. //////// Implementation ////////
  369. bool HGE_Impl::_SoundInit()
  370. {
  371. if(!bUseSound || hBass) return true;
  372. hBass=LoadLibrary("bass.dll");
  373. if (!hBass)
  374. {
  375. _PostError("Can't load BASS.DLL");
  376. return false;
  377. }
  378. LOADBASSFUNCTION(BASS_GetVersion);
  379. if (HIWORD(BASS_GetVersion()) != BASSVERSION)
  380. {
  381. _PostError("Incorrect BASS.DLL version");
  382. return false;
  383. }
  384. LOADBASSFUNCTION(BASS_GetDeviceDescription);
  385. LOADBASSFUNCTION(BASS_Init);
  386. LOADBASSFUNCTION(BASS_Free);
  387. LOADBASSFUNCTION(BASS_Start);
  388. LOADBASSFUNCTION(BASS_Pause);
  389. LOADBASSFUNCTION(BASS_Stop);
  390. LOADBASSFUNCTION(BASS_SetConfig);
  391. //LOADBASSFUNCTION(BASS_ErrorGetCode);
  392. LOADBASSFUNCTION(BASS_SampleLoad);
  393. LOADBASSFUNCTION(BASS_SampleCreate);
  394. LOADBASSFUNCTION(BASS_SampleCreateDone);
  395. LOADBASSFUNCTION(BASS_SampleGetInfo);
  396. LOADBASSFUNCTION(BASS_SampleGetChannel);
  397. LOADBASSFUNCTION(BASS_SampleFree);
  398. LOADBASSFUNCTION(BASS_MusicLoad);
  399. LOADBASSFUNCTION(BASS_MusicFree);
  400. LOADBASSFUNCTION(BASS_MusicGetOrders);
  401. LOADBASSFUNCTION(BASS_MusicGetOrderPosition);
  402. LOADBASSFUNCTION(BASS_MusicSetAttribute);
  403. LOADBASSFUNCTION(BASS_MusicGetAttribute);
  404. LOADBASSFUNCTION(BASS_StreamCreateFile);
  405. LOADBASSFUNCTION(BASS_StreamFree);
  406. LOADBASSFUNCTION(BASS_ChannelGetInfo);
  407. LOADBASSFUNCTION(BASS_ChannelGetAttributes);
  408. LOADBASSFUNCTION(BASS_ChannelSetAttributes);
  409. LOADBASSFUNCTION(BASS_ChannelSlideAttributes);
  410. LOADBASSFUNCTION(BASS_ChannelIsSliding);
  411. LOADBASSFUNCTION(BASS_ChannelSetFlags);
  412. LOADBASSFUNCTION(BASS_ChannelGetData);
  413. LOADBASSFUNCTION(BASS_ChannelPlay);
  414. LOADBASSFUNCTION(BASS_ChannelPause);
  415. LOADBASSFUNCTION(BASS_ChannelStop);
  416. LOADBASSFUNCTION(BASS_ChannelIsActive);
  417. LOADBASSFUNCTION(BASS_ChannelGetLength);
  418. LOADBASSFUNCTION(BASS_ChannelGetPosition);
  419. LOADBASSFUNCTION(BASS_ChannelSetPosition);
  420. LOADBASSFUNCTION(BASS_ChannelSeconds2Bytes);
  421. LOADBASSFUNCTION(BASS_ChannelBytes2Seconds);
  422. bSilent=false;
  423. if (!BASS_Init(-1,nSampleRate,0,hwnd,NULL))
  424. {
  425. System_Log("BASS Init failed, using no sound");
  426. BASS_Init(0,nSampleRate,0,hwnd,NULL);
  427. bSilent=true;
  428. }
  429. else
  430. {
  431. System_Log("Sound Device: %s",BASS_GetDeviceDescription(1));
  432. System_Log("Sample rate: %ldn", nSampleRate);
  433. }
  434. //BASS_SetConfig(BASS_CONFIG_BUFFER, 5000);
  435. //BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 50);
  436. _SetFXVolume(nFXVolume);
  437. _SetMusVolume(nMusVolume);
  438. _SetStreamVolume(nStreamVolume);
  439. return true;
  440. }
  441. void HGE_Impl::_SoundDone()
  442. {
  443. CStreamList *stmItem=streams, *stmNext;
  444. if(hBass)
  445. {
  446. BASS_Stop();
  447. BASS_Free();
  448. //int err = BASS_ErrorGetCode(); 
  449. FreeLibrary(hBass);
  450. hBass=0;
  451. while(stmItem)
  452. {
  453. stmNext=stmItem->next;
  454. Resource_Free(stmItem->data);
  455. delete stmItem;
  456. stmItem=stmNext;
  457. }
  458. streams=0;
  459. }
  460. }
  461. void HGE_Impl::_SetMusVolume(int vol)
  462. {
  463. if(hBass) BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, vol);
  464. }
  465. void HGE_Impl::_SetStreamVolume(int vol)
  466. {
  467. if(hBass) BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, vol);
  468. }
  469. void HGE_Impl::_SetFXVolume(int vol)
  470. {
  471. if(hBass) BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, vol);
  472. }