sound.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169
  1. /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
  2. //
  3. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  4. // All rights reserved.
  5. //
  6. // This file is part of SDLPAL.
  7. //
  8. // SDLPAL is free software: you can redistribute it and/or modify
  9. // it under the terms of the GNU General Public License as published by
  10. // the Free Software Foundation, either version 3 of the License, or
  11. // (at your option) any later version.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU General Public License
  19. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. //
  21. #include "palcommon.h"
  22. #include "global.h"
  23. #include "palcfg.h"
  24. #include "sound.h"
  25. #include "players.h"
  26. #include "util.h"
  27. #include "resampler.h"
  28. #include "midi.h"
  29. #include <math.h>
  30. #if PAL_HAS_OGG
  31. #include <vorbis/codec.h>
  32. #endif
  33. #define PAL_CDTRACK_BASE 10000
  34. typedef LPCBYTE(*FNLoadSoundData)(LPCBYTE, DWORD, SDL_AudioSpec *);
  35. typedef struct tagWAVEPLAYER
  36. {
  37. FNLoadSoundData LoadSoundData;
  38. void *resampler;
  39. short *buf;
  40. int buf_len, pos, len;
  41. } WAVEPLAYER;
  42. typedef struct tagSNDPLAYER
  43. {
  44. FILE *mkf;
  45. SDL_AudioSpec spec;
  46. SDL_AudioCVT cvt;
  47. SDL_mutex *mtx;
  48. MUSICPLAYER *pMusPlayer;
  49. MUSICPLAYER *pCDPlayer;
  50. #if PAL_HAS_SDLCD
  51. SDL_CD *pCD;
  52. #endif
  53. WAVEPLAYER wavePlayer;
  54. INT iMusicVolume, iSoundVolume;
  55. BOOL fOpened;
  56. BOOL fMusicEnabled;
  57. BOOL fSoundEnabled;
  58. } SNDPLAYER;
  59. static SNDPLAYER gSndPlayer;
  60. PAL_FORCE_INLINE
  61. void
  62. AUDIO_MixNative(
  63. short *dst,
  64. short *src,
  65. int samples
  66. )
  67. {
  68. while (samples > 0)
  69. {
  70. int val = *src++ + *dst;
  71. if (val > SHRT_MAX)
  72. *dst++ = SHRT_MAX;
  73. else if (val < SHRT_MIN)
  74. *dst++ = SHRT_MIN;
  75. else
  76. *dst++ = (short)val;
  77. samples--;
  78. }
  79. }
  80. PAL_FORCE_INLINE
  81. void
  82. AUDIO_AdjustVolume(
  83. short *srcdst,
  84. int iVolume,
  85. int samples
  86. )
  87. {
  88. if (iVolume == SDL_MIX_MAXVOLUME) return;
  89. if (iVolume == 0) { memset(srcdst, 0, samples << 1); return; }
  90. while (samples > 0)
  91. {
  92. *srcdst = *srcdst * iVolume / SDL_MIX_MAXVOLUME;
  93. samples--; srcdst++;
  94. }
  95. }
  96. typedef struct tagRIFFHEADER
  97. {
  98. DWORD riff_sig; /* 'RIFF' */
  99. DWORD data_length; /* Total length minus eight, little-endian */
  100. DWORD riff_type; /* 'WAVE' */
  101. } RIFFHEADER, *LPRIFFHEADER;
  102. typedef const RIFFHEADER *LPCRIFFHEADER;
  103. typedef struct tagRIFFCHUNK
  104. {
  105. DWORD chunk_type; /* 'fmt ' and so on */
  106. DWORD chunk_length; /* Total chunk length minus eight, little-endian */
  107. } RIFFCHUNK, *LPRIFFCHUNK;
  108. typedef const RIFFCHUNK *LPCRIFFCHUNK;
  109. typedef struct tagWAVEFORMATPCM
  110. {
  111. WORD wFormatTag; /* format type */
  112. WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */
  113. DWORD nSamplesPerSec; /* sample rate */
  114. DWORD nAvgBytesPerSec; /* for buffer estimation */
  115. WORD nBlockAlign; /* block size of data */
  116. WORD wBitsPerSample;
  117. } WAVEFORMATPCM, *LPWAVEFORMATPCM;
  118. typedef const WAVEFORMATPCM *LPCWAVEFORMATPCM;
  119. static LPCBYTE
  120. SOUND_LoadWAVEData(
  121. LPCBYTE lpData,
  122. DWORD dwLen,
  123. SDL_AudioSpec *lpSpec
  124. )
  125. /*++
  126. Purpose:
  127. Return the WAVE data pointer inside the input buffer.
  128. Parameters:
  129. [IN] lpData - pointer to the buffer of the WAVE file.
  130. [IN] dwLen - length of the buffer of the WAVE file.
  131. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  132. some basic information about the WAVE file.
  133. Return value:
  134. Pointer to the WAVE data inside the input buffer, NULL if failed.
  135. --*/
  136. {
  137. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  138. # define RIFF 'RIFF'
  139. # define WAVE 'WAVE'
  140. # define FMT 'fmt '
  141. # define DATA 'data'
  142. # define PCM 0x0100
  143. #else
  144. # define RIFF 'FFIR'
  145. # define WAVE 'EVAW'
  146. # define FMT ' tmf'
  147. # define DATA 'atad'
  148. # define PCM 0x0001
  149. #endif
  150. LPCRIFFHEADER lpRiff = (LPCRIFFHEADER)lpData;
  151. LPCRIFFCHUNK lpChunk;
  152. LPCWAVEFORMATPCM lpFormat = NULL;
  153. LPCBYTE lpWaveData = NULL;
  154. DWORD len;
  155. if (dwLen < sizeof(RIFFHEADER) || lpRiff->riff_sig != RIFF || lpRiff->riff_type != WAVE || dwLen < SDL_SwapLE32(lpRiff->data_length) + 8)
  156. {
  157. return NULL;
  158. }
  159. lpChunk = (LPCRIFFCHUNK)(lpRiff + 1); dwLen -= sizeof(RIFFHEADER);
  160. while (dwLen >= sizeof(RIFFCHUNK))
  161. {
  162. len = SDL_SwapLE32(lpChunk->chunk_length);
  163. if (dwLen >= sizeof(RIFFCHUNK) + len)
  164. dwLen -= sizeof(RIFFCHUNK) + len;
  165. else
  166. return NULL;
  167. switch (lpChunk->chunk_type)
  168. {
  169. case FMT:
  170. lpFormat = (LPCWAVEFORMATPCM)(lpChunk + 1);
  171. if (len != sizeof(WAVEFORMATPCM) || lpFormat->wFormatTag != PCM)
  172. {
  173. return NULL;
  174. }
  175. break;
  176. case DATA:
  177. lpWaveData = (LPCBYTE)(lpChunk + 1);
  178. dwLen = 0;
  179. break;
  180. }
  181. lpChunk = (LPCRIFFCHUNK)((LPCBYTE)(lpChunk + 1) + len);
  182. }
  183. if (lpFormat == NULL || lpWaveData == NULL)
  184. {
  185. return NULL;
  186. }
  187. lpSpec->channels = lpFormat->nChannels;
  188. lpSpec->format = (lpFormat->wBitsPerSample == 16) ? AUDIO_S16 : AUDIO_U8;
  189. lpSpec->freq = lpFormat->nSamplesPerSec;
  190. lpSpec->size = len;
  191. return lpWaveData;
  192. #undef RIFF
  193. #undef WAVE
  194. #undef FMT
  195. }
  196. typedef struct tagVOCHEADER
  197. {
  198. char signature[0x14]; /* "Creative Voice File\x1A" */
  199. WORD data_offset; /* little endian */
  200. WORD version;
  201. WORD version_checksum;
  202. } VOCHEADER, *LPVOCHEADER;
  203. typedef const VOCHEADER *LPCVOCHEADER;
  204. static LPCBYTE
  205. SOUND_LoadVOCData(
  206. LPCBYTE lpData,
  207. DWORD dwLen,
  208. SDL_AudioSpec *lpSpec
  209. )
  210. /*++
  211. Purpose:
  212. Return the VOC data pointer inside the input buffer. Currently supports type 01 block only.
  213. Parameters:
  214. [IN] lpData - pointer to the buffer of the VOC file.
  215. [IN] dwLen - length of the buffer of the VOC file.
  216. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  217. some basic information about the VOC file.
  218. Return value:
  219. Pointer to the WAVE data inside the input buffer, NULL if failed.
  220. Reference: http://sox.sourceforge.net/AudioFormats-11.html
  221. --*/
  222. {
  223. LPCVOCHEADER lpVOC = (LPCVOCHEADER)lpData;
  224. if (dwLen < sizeof(VOCHEADER) || memcmp(lpVOC->signature, "Creative Voice File\x1A", 0x14) || SDL_SwapLE16(lpVOC->data_offset) >= dwLen)
  225. {
  226. return NULL;
  227. }
  228. lpData += SDL_SwapLE16(lpVOC->data_offset);
  229. dwLen -= SDL_SwapLE16(lpVOC->data_offset);
  230. while (dwLen && *lpData)
  231. {
  232. DWORD len;
  233. if (dwLen >= 4)
  234. {
  235. len = lpData[1] | (lpData[2] << 8) | (lpData[3] << 16);
  236. if (dwLen >= len + 4)
  237. dwLen -= len + 4;
  238. else
  239. return NULL;
  240. }
  241. else
  242. {
  243. return NULL;
  244. }
  245. if (*lpData == 0x01)
  246. {
  247. if (lpData[5] != 0) return NULL; /* Only 8-bit is supported */
  248. lpSpec->format = AUDIO_U8;
  249. lpSpec->channels = 1;
  250. lpSpec->freq = ((1000000 / (256 - lpData[4]) + 99) / 100) * 100; /* Round to next 100Hz */
  251. lpSpec->size = len - 2;
  252. return lpData + 6;
  253. }
  254. else
  255. {
  256. lpData += len + 4;
  257. }
  258. }
  259. return NULL;
  260. }
  261. static void
  262. SOUND_ResampleU8(
  263. LPCBYTE lpData,
  264. const SDL_AudioSpec *lpSpec,
  265. LPBYTE lpBuffer,
  266. DWORD dwLen,
  267. void *resampler
  268. )
  269. /*++
  270. Purpose:
  271. Resample 8-bit unsigned PCM data into 16-bit signed (little-endian) PCM data.
  272. Parameters:
  273. [IN] lpData - pointer to the buffer of the input PCM data.
  274. [IN] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  275. some basic information about the input PCM data.
  276. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  277. [IN] dwLen - length of the buffer of the output PCM data, should be exactly
  278. the number of bytes needed of the resampled data.
  279. [IN] resampler - pointer of the resampler instance.
  280. Return value:
  281. None.
  282. --*/
  283. {
  284. int src_samples = lpSpec->size / lpSpec->channels, i;
  285. for (i = 0; i < lpSpec->channels; i++)
  286. {
  287. LPCBYTE src = lpData + i;
  288. short *dst = (short *)lpBuffer + i;
  289. int channel_len = dwLen / lpSpec->channels, total_bytes = 0;
  290. resampler_clear(resampler);
  291. while (total_bytes < channel_len && src_samples > 0)
  292. {
  293. int to_write, j;
  294. to_write = resampler_get_free_count(resampler);
  295. if (to_write > src_samples) to_write = src_samples;
  296. for (j = 0; j < to_write; j++)
  297. {
  298. resampler_write_sample(resampler, (*src ^ 0x80) << 8);
  299. src += lpSpec->channels;
  300. }
  301. src_samples -= to_write;
  302. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  303. {
  304. *dst = resampler_get_and_remove_sample(resampler);
  305. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  306. }
  307. }
  308. /* Flush resampler's output buffer */
  309. while (total_bytes < channel_len)
  310. {
  311. int j, to_write = resampler_get_free_count(resampler);
  312. for (j = 0; j < to_write; j++)
  313. resampler_write_sample(resampler, (src[-lpSpec->channels] ^ 0x80) << 8);
  314. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  315. {
  316. *dst = resampler_get_and_remove_sample(resampler);
  317. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  318. }
  319. }
  320. }
  321. }
  322. static void
  323. SOUND_ResampleS16(
  324. LPCBYTE lpData,
  325. const SDL_AudioSpec *lpSpec,
  326. LPBYTE lpBuffer,
  327. DWORD dwLen,
  328. void *resampler
  329. )
  330. /*++
  331. Purpose:
  332. Resample 16-bit signed (little-endian) PCM data into 16-bit signed (little-endian) PCM data.
  333. Parameters:
  334. [IN] lpData - pointer to the buffer of the input PCM data.
  335. [IN] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  336. some basic information about the input PCM data.
  337. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  338. [IN] dwLen - length of the buffer of the output PCM data, should be exactly
  339. the number of bytes needed of the resampled data.
  340. [IN] resampler - pointer of the resampler instance.
  341. Return value:
  342. None.
  343. --*/
  344. {
  345. int src_samples = lpSpec->size / lpSpec->channels / 2, i;
  346. for (i = 0; i < lpSpec->channels; i++)
  347. {
  348. const short *src = (short *)lpData + i;
  349. short *dst = (short *)lpBuffer + i;
  350. int channel_len = dwLen / lpSpec->channels, total_bytes = 0;
  351. resampler_clear(resampler);
  352. while (total_bytes < channel_len && src_samples > 0)
  353. {
  354. int to_write, j;
  355. to_write = resampler_get_free_count(resampler);
  356. if (to_write > src_samples) to_write = src_samples;
  357. for (j = 0; j < to_write; j++)
  358. {
  359. resampler_write_sample(resampler, SDL_SwapLE16(*src));
  360. src += lpSpec->channels;
  361. }
  362. src_samples -= to_write;
  363. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  364. {
  365. *dst = resampler_get_and_remove_sample(resampler);
  366. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  367. }
  368. }
  369. /* Flush resampler's output buffer */
  370. while (total_bytes < channel_len)
  371. {
  372. int j, to_write = resampler_get_free_count(resampler);
  373. short val = SDL_SwapLE16(src[-lpSpec->channels]);
  374. for (j = 0; j < to_write; j++)
  375. resampler_write_sample(resampler, val);
  376. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  377. {
  378. *dst = resampler_get_and_remove_sample(resampler);
  379. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  380. }
  381. }
  382. }
  383. }
  384. static VOID SDLCALL
  385. AUDIO_FillBuffer(
  386. LPVOID udata,
  387. LPBYTE stream,
  388. INT len
  389. )
  390. /*++
  391. Purpose:
  392. SDL sound callback function.
  393. Parameters:
  394. [IN] udata - pointer to user-defined parameters (Not used).
  395. [OUT] stream - pointer to the stream buffer.
  396. [IN] len - Length of the buffer.
  397. Return value:
  398. None.
  399. --*/
  400. {
  401. #if SDL_VERSION_ATLEAST(2,0,0)
  402. memset(stream, 0, len);
  403. #endif
  404. SDL_mutexP(gSndPlayer.mtx);
  405. gSndPlayer.cvt.buf = stream;
  406. gSndPlayer.cvt.len = len;
  407. //
  408. // Play music
  409. //
  410. if (gSndPlayer.fMusicEnabled && gSndPlayer.iMusicVolume > 0)
  411. {
  412. if (gSndPlayer.pMusPlayer)
  413. {
  414. gSndPlayer.pMusPlayer->FillBuffer(gSndPlayer.pMusPlayer, stream, len);
  415. }
  416. if (gSndPlayer.pCDPlayer)
  417. {
  418. gSndPlayer.pCDPlayer->FillBuffer(gSndPlayer.pCDPlayer, stream, len);
  419. }
  420. //
  421. // Adjust volume for music
  422. //
  423. AUDIO_AdjustVolume((short *)stream, gSndPlayer.iMusicVolume, len >> 1);
  424. }
  425. //
  426. // Play sound
  427. //
  428. if (gSndPlayer.fSoundEnabled && gSndPlayer.wavePlayer.len > 0 && gSndPlayer.iSoundVolume > 0)
  429. {
  430. //
  431. // Mix as much sound data as possible
  432. //
  433. WAVEPLAYER *player = &gSndPlayer.wavePlayer;
  434. int mixlen = min(player->len, len >> 1);
  435. if (player->pos + mixlen > player->buf_len)
  436. {
  437. AUDIO_MixNative((short *)stream, player->buf + player->pos, player->buf_len - player->pos);
  438. stream += (player->buf_len - player->pos) << 1; memset(player->buf + player->pos, 0, (player->buf_len - player->pos) << 1);
  439. AUDIO_MixNative((short *)stream, player->buf, player->pos + mixlen - player->buf_len);
  440. stream += (player->pos + mixlen - player->buf_len) << 1; memset(player->buf, 0, (player->pos + mixlen - player->buf_len) << 1);
  441. }
  442. else
  443. {
  444. AUDIO_MixNative((short *)stream, player->buf + player->pos, mixlen);
  445. stream += mixlen << 1; memset(player->buf + player->pos, 0, mixlen << 1);
  446. }
  447. player->pos = (player->pos + mixlen) % player->buf_len; player->len -= mixlen; len -= (mixlen << 1);
  448. }
  449. //
  450. // Convert audio from native byte-order to actual byte-order
  451. //
  452. SDL_ConvertAudio(&gSndPlayer.cvt);
  453. SDL_mutexV(gSndPlayer.mtx);
  454. }
  455. static VOID
  456. SOUND_LoadMKF(
  457. VOID
  458. )
  459. /*++
  460. Purpose:
  461. Load MKF contents into memory.
  462. Parameters:
  463. None.
  464. Return value:
  465. None.
  466. --*/
  467. {
  468. char *mkfs[2];
  469. FNLoadSoundData func[2];
  470. int i;
  471. if (gConfig.fIsWIN95)
  472. {
  473. mkfs[0] = "sounds.mkf"; func[0] = SOUND_LoadWAVEData;
  474. mkfs[1] = "voc.mkf"; func[1] = SOUND_LoadVOCData;
  475. }
  476. else
  477. {
  478. mkfs[0] = "voc.mkf"; func[0] = SOUND_LoadVOCData;
  479. mkfs[1] = "sounds.mkf"; func[1] = SOUND_LoadWAVEData;
  480. }
  481. for (i = 0; i < 2; i++)
  482. {
  483. gSndPlayer.mkf = UTIL_OpenFile(mkfs[i]);
  484. if (gSndPlayer.mkf)
  485. {
  486. gSndPlayer.wavePlayer.LoadSoundData = func[i];
  487. break;
  488. }
  489. }
  490. }
  491. INT
  492. AUDIO_OpenDevice(
  493. VOID
  494. )
  495. /*++
  496. Purpose:
  497. Initialize the audio subsystem.
  498. Parameters:
  499. None.
  500. Return value:
  501. 0 if succeed, others if failed.
  502. --*/
  503. {
  504. SDL_AudioSpec spec;
  505. if (gSndPlayer.fOpened)
  506. {
  507. //
  508. // Already opened
  509. //
  510. return -1;
  511. }
  512. gSndPlayer.fOpened = FALSE;
  513. gSndPlayer.fMusicEnabled = TRUE;
  514. gSndPlayer.fSoundEnabled = TRUE;
  515. gSndPlayer.iMusicVolume = gConfig.iMusicVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
  516. gSndPlayer.iSoundVolume = gConfig.iSoundVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
  517. //
  518. // Load the MKF file.
  519. //
  520. SOUND_LoadMKF();
  521. if (gSndPlayer.mkf == NULL)
  522. {
  523. return -2;
  524. }
  525. //
  526. // Initialize the resampler
  527. //
  528. resampler_init();
  529. gSndPlayer.wavePlayer.resampler = resampler_create();
  530. //
  531. // Open the sound subsystem.
  532. //
  533. gSndPlayer.spec.freq = gConfig.iSampleRate;
  534. gSndPlayer.spec.format = AUDIO_S16;
  535. gSndPlayer.spec.channels = gConfig.iAudioChannels;
  536. gSndPlayer.spec.samples = gConfig.wAudioBufferSize;
  537. gSndPlayer.spec.callback = AUDIO_FillBuffer;
  538. if (SDL_OpenAudio(&gSndPlayer.spec, &spec) < 0)
  539. {
  540. //
  541. // Failed
  542. //
  543. return -3;
  544. }
  545. else
  546. gSndPlayer.spec = spec;
  547. SDL_BuildAudioCVT(&gSndPlayer.cvt, AUDIO_S16SYS, spec.channels, spec.freq, spec.format, spec.channels, spec.freq);
  548. gSndPlayer.wavePlayer.buf = NULL;
  549. gSndPlayer.wavePlayer.buf_len = 0;
  550. gSndPlayer.wavePlayer.pos = 0;
  551. gSndPlayer.wavePlayer.len = 0;
  552. gSndPlayer.mtx = SDL_CreateMutex();
  553. gSndPlayer.fOpened = TRUE;
  554. //
  555. // Initialize the music subsystem.
  556. //
  557. switch (gConfig.eMusicType)
  558. {
  559. case MUSIC_RIX:
  560. if (!(gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", gConfig.pszGamePath, "mus.mkf"))))
  561. {
  562. gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", gConfig.pszGamePath, "MUS.MKF"));
  563. }
  564. break;
  565. case MUSIC_MP3:
  566. #if PAL_HAS_MP3
  567. gSndPlayer.pMusPlayer = MP3_Init(NULL);
  568. #else
  569. gSndPlayer.pMusPlayer = NULL;
  570. #endif
  571. break;
  572. case MUSIC_OGG:
  573. #if PAL_HAS_OGG
  574. gSndPlayer.pMusPlayer = OGG_Init(NULL);
  575. #else
  576. gSndPlayer.pMusPlayer = NULL;
  577. #endif
  578. break;
  579. case MUSIC_MIDI:
  580. gSndPlayer.pMusPlayer = NULL;
  581. break;
  582. }
  583. //
  584. // Initialize the CD audio.
  585. //
  586. switch (gConfig.eCDType)
  587. {
  588. case MUSIC_SDLCD:
  589. {
  590. #if PAL_HAS_SDLCD
  591. int i;
  592. gSndPlayer.pCD = NULL;
  593. for (i = 0; i < SDL_CDNumDrives(); i++)
  594. {
  595. gSndPlayer.pCD = SDL_CDOpen(i);
  596. if (gSndPlayer.pCD != NULL)
  597. {
  598. if (!CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
  599. {
  600. SDL_CDClose(gSndPlayer.pCD);
  601. gSndPlayer.pCD = NULL;
  602. }
  603. else
  604. {
  605. break;
  606. }
  607. }
  608. }
  609. #endif
  610. gSndPlayer.pCDPlayer = NULL;
  611. break;
  612. }
  613. case MUSIC_MP3:
  614. #if PAL_HAS_MP3
  615. gSndPlayer.pCDPlayer = MP3_Init(NULL);
  616. #else
  617. gSndPlayer.pCDPlayer = NULL;
  618. #endif
  619. break;
  620. case MUSIC_OGG:
  621. #if PAL_HAS_OGG
  622. gSndPlayer.pCDPlayer = OGG_Init(NULL);
  623. #else
  624. gSndPlayer.pCDPlayer = NULL;
  625. #endif
  626. break;
  627. }
  628. //
  629. // Let the callback function run so that musics will be played.
  630. //
  631. SDL_PauseAudio(0);
  632. return 0;
  633. }
  634. VOID
  635. AUDIO_CloseDevice(
  636. VOID
  637. )
  638. /*++
  639. Purpose:
  640. Close the audio subsystem.
  641. Parameters:
  642. None.
  643. Return value:
  644. None.
  645. --*/
  646. {
  647. SDL_CloseAudio();
  648. SDL_mutexP(gSndPlayer.mtx);
  649. if (gSndPlayer.wavePlayer.buf != NULL)
  650. {
  651. free(gSndPlayer.wavePlayer.buf);
  652. gSndPlayer.wavePlayer.buf = NULL;
  653. gSndPlayer.wavePlayer.buf_len = 0;
  654. gSndPlayer.wavePlayer.pos = 0;
  655. gSndPlayer.wavePlayer.len = 0;
  656. }
  657. if (gSndPlayer.mkf != NULL)
  658. {
  659. fclose(gSndPlayer.mkf);
  660. gSndPlayer.mkf = NULL;
  661. }
  662. if (gSndPlayer.pMusPlayer)
  663. {
  664. gSndPlayer.pMusPlayer->Shutdown(gSndPlayer.pMusPlayer);
  665. gSndPlayer.pMusPlayer = NULL;
  666. }
  667. if (gSndPlayer.pCDPlayer)
  668. {
  669. gSndPlayer.pCDPlayer->Shutdown(gSndPlayer.pCDPlayer);
  670. gSndPlayer.pCDPlayer = NULL;
  671. }
  672. #if PAL_HAS_SDLCD
  673. if (gSndPlayer.pCD != NULL)
  674. {
  675. AUDIO_PlayCDTrack(-1);
  676. SDL_CDClose(gSndPlayer.pCD);
  677. }
  678. #endif
  679. if (gConfig.eMusicType == MUSIC_MIDI) MIDI_Play(0, FALSE);
  680. if (gSndPlayer.wavePlayer.resampler)
  681. {
  682. resampler_delete(gSndPlayer.wavePlayer.resampler);
  683. gSndPlayer.wavePlayer.resampler = NULL;
  684. }
  685. SDL_mutexV(gSndPlayer.mtx);
  686. SDL_DestroyMutex(gSndPlayer.mtx);
  687. }
  688. SDL_AudioSpec*
  689. AUDIO_GetDeviceSpec(
  690. VOID
  691. )
  692. {
  693. return &gSndPlayer.spec;
  694. }
  695. static INT
  696. AUDIO_ChangeVolumeByValue(
  697. INT *iVolume,
  698. INT iValue
  699. )
  700. {
  701. *iVolume += iValue;
  702. if (*iVolume > PAL_MAX_VOLUME)
  703. *iVolume = PAL_MAX_VOLUME;
  704. else if (*iVolume < 0)
  705. *iVolume = 0;
  706. return *iVolume;
  707. }
  708. VOID
  709. AUDIO_IncreaseVolume(
  710. VOID
  711. )
  712. /*++
  713. Purpose:
  714. Increase global volume by 3%.
  715. Parameters:
  716. None.
  717. Return value:
  718. None.
  719. --*/
  720. {
  721. AUDIO_ChangeVolumeByValue(&gConfig.iMusicVolume, 3);
  722. AUDIO_ChangeVolumeByValue(&gConfig.iSoundVolume, 3);
  723. gSndPlayer.iMusicVolume = gConfig.iMusicVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
  724. gSndPlayer.iSoundVolume = gConfig.iSoundVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
  725. }
  726. VOID
  727. AUDIO_DecreaseVolume(
  728. VOID
  729. )
  730. /*++
  731. Purpose:
  732. Decrease global volume by 3%.
  733. Parameters:
  734. None.
  735. Return value:
  736. None.
  737. --*/
  738. {
  739. AUDIO_ChangeVolumeByValue(&gConfig.iMusicVolume, -3);
  740. AUDIO_ChangeVolumeByValue(&gConfig.iSoundVolume, -3);
  741. gSndPlayer.iMusicVolume = gConfig.iMusicVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
  742. gSndPlayer.iSoundVolume = gConfig.iSoundVolume * SDL_MIX_MAXVOLUME / PAL_MAX_VOLUME;
  743. }
  744. VOID
  745. AUDIO_PlaySound(
  746. INT iSoundNum
  747. )
  748. /*++
  749. Purpose:
  750. Play a sound in voc.mkf/sounds.mkf file.
  751. Parameters:
  752. [IN] iSoundNum - number of the sound; the absolute value is used.
  753. Return value:
  754. None.
  755. --*/
  756. {
  757. SDL_AudioCVT wavecvt;
  758. SDL_AudioSpec wavespec;
  759. LPBYTE buf, bufdec;
  760. LPCBYTE bufsrc;
  761. int len;
  762. if (!gSndPlayer.fOpened || !gSndPlayer.fSoundEnabled)
  763. {
  764. return;
  765. }
  766. if (iSoundNum < 0)
  767. {
  768. iSoundNum = -iSoundNum;
  769. }
  770. //
  771. // Get the length of the sound file.
  772. //
  773. len = PAL_MKFGetChunkSize(iSoundNum, gSndPlayer.mkf);
  774. if (len <= 0)
  775. {
  776. return;
  777. }
  778. buf = (LPBYTE)malloc(len);
  779. if (buf == NULL)
  780. {
  781. return;
  782. }
  783. //
  784. // Read the sound file from the MKF archive.
  785. //
  786. PAL_MKFReadChunk(buf, len, iSoundNum, gSndPlayer.mkf);
  787. bufsrc = gSndPlayer.wavePlayer.LoadSoundData(buf, len, &wavespec);
  788. if (bufsrc == NULL)
  789. {
  790. free(buf);
  791. return;
  792. }
  793. if (wavespec.freq != gSndPlayer.spec.freq)
  794. {
  795. /* Resampler is needed */
  796. resampler_set_quality(gSndPlayer.wavePlayer.resampler, AUDIO_IsIntegerConversion(wavespec.freq) ? RESAMPLER_QUALITY_MIN : gConfig.iResampleQuality);
  797. resampler_set_rate(gSndPlayer.wavePlayer.resampler, (double)wavespec.freq / (double)gSndPlayer.spec.freq);
  798. len = (int)ceil(wavespec.size * (double)gSndPlayer.spec.freq / (double)wavespec.freq) * (SDL_AUDIO_BITSIZE(AUDIO_S16SYS) / SDL_AUDIO_BITSIZE(wavespec.format));
  799. if (len >= wavespec.channels * 2 && (bufdec = malloc(len)))
  800. {
  801. if (wavespec.format == AUDIO_S16)
  802. SOUND_ResampleS16(bufsrc, &wavespec, bufdec, len, gSndPlayer.wavePlayer.resampler);
  803. else
  804. SOUND_ResampleU8(bufsrc, &wavespec, bufdec, len, gSndPlayer.wavePlayer.resampler);
  805. /* Free the original buffer and reset the pointer for simpler later operations */
  806. free(buf); buf = bufdec;
  807. wavespec.format = AUDIO_S16SYS;
  808. wavespec.freq = gSndPlayer.spec.freq;
  809. }
  810. else
  811. {
  812. free(buf);
  813. return;
  814. }
  815. }
  816. else
  817. {
  818. bufdec = (LPBYTE)bufsrc;
  819. len = wavespec.size;
  820. }
  821. //
  822. // Build the audio converter and create conversion buffers
  823. //
  824. if (SDL_BuildAudioCVT(&wavecvt, wavespec.format, wavespec.channels, wavespec.freq,
  825. AUDIO_S16SYS, gSndPlayer.spec.channels, gSndPlayer.spec.freq) < 0)
  826. {
  827. free(buf);
  828. return;
  829. }
  830. wavecvt.len = len & ~((SDL_AUDIO_BITSIZE(wavespec.format) >> 3) * wavespec.channels - 1);
  831. wavecvt.buf = (LPBYTE)malloc(wavecvt.len * wavecvt.len_mult);
  832. if (wavecvt.buf == NULL)
  833. {
  834. free(buf);
  835. return;
  836. }
  837. memcpy(wavecvt.buf, bufdec, len);
  838. free(buf);
  839. //
  840. // Run the audio converter
  841. //
  842. if (SDL_ConvertAudio(&wavecvt) == 0)
  843. {
  844. WAVEPLAYER *player = &gSndPlayer.wavePlayer;
  845. wavecvt.len = (int)(wavecvt.len * wavecvt.len_ratio) >> 1;
  846. AUDIO_AdjustVolume((short *)wavecvt.buf, gSndPlayer.iSoundVolume, wavecvt.len);
  847. SDL_mutexP(gSndPlayer.mtx);
  848. //
  849. // Check if the current sound buffer is large enough
  850. //
  851. if (gSndPlayer.wavePlayer.buf_len < wavecvt.len)
  852. {
  853. if (player->pos + player->len > player->buf_len)
  854. {
  855. short *old_buf = player->buf;
  856. player->buf = (short *)malloc(wavecvt.len << 1);
  857. memcpy(player->buf, old_buf + player->pos, (player->buf_len - player->pos) << 1);
  858. memcpy(player->buf + player->buf_len - player->pos, old_buf, (player->pos + player->len - player->buf_len) << 1);
  859. player->pos = 0; free(old_buf);
  860. }
  861. else
  862. player->buf = (short *)realloc(player->buf, wavecvt.len << 1);
  863. memset(player->buf + player->pos + player->len, 0, ((player->buf_len = wavecvt.len) - player->pos - player->len) << 1);
  864. }
  865. //
  866. // Mix the current sound buffer with newly played sound and adjust the length of valid data
  867. //
  868. if (player->pos + wavecvt.len > player->buf_len)
  869. {
  870. AUDIO_MixNative(player->buf + player->pos, (short *)wavecvt.buf, player->buf_len - player->pos);
  871. AUDIO_MixNative(player->buf, (short *)wavecvt.buf + player->buf_len - player->pos, player->pos + wavecvt.len - player->buf_len);
  872. }
  873. else
  874. AUDIO_MixNative(player->buf + player->pos, (short *)wavecvt.buf, wavecvt.len);
  875. player->len = max(player->len, wavecvt.len);
  876. SDL_mutexV(gSndPlayer.mtx);
  877. }
  878. free(wavecvt.buf);
  879. }
  880. VOID
  881. AUDIO_PlayMusic(
  882. INT iNumRIX,
  883. BOOL fLoop,
  884. FLOAT flFadeTime
  885. )
  886. {
  887. SDL_mutexP(gSndPlayer.mtx);
  888. if (gConfig.eMusicType == MUSIC_MIDI)
  889. {
  890. MIDI_Play(iNumRIX, fLoop);
  891. }
  892. else if (gSndPlayer.pMusPlayer)
  893. {
  894. gSndPlayer.pMusPlayer->Play(gSndPlayer.pMusPlayer, iNumRIX, fLoop, flFadeTime);
  895. }
  896. SDL_mutexV(gSndPlayer.mtx);
  897. }
  898. BOOL
  899. AUDIO_PlayCDTrack(
  900. INT iNumTrack
  901. )
  902. /*++
  903. Purpose:
  904. Play a CD Audio Track.
  905. Parameters:
  906. [IN] iNumTrack - number of the CD Audio Track.
  907. Return value:
  908. TRUE if the track can be played, FALSE if not.
  909. --*/
  910. {
  911. BOOL ret = FALSE;
  912. #if PAL_HAS_SDLCD
  913. if (gSndPlayer.pCD != NULL)
  914. {
  915. if (CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
  916. {
  917. SDL_CDStop(gSndPlayer.pCD);
  918. if (iNumTrack != -1)
  919. {
  920. AUDIO_PlayMusic(-1, FALSE, 0);
  921. if (SDL_CDPlayTracks(gSndPlayer.pCD, iNumTrack - 1, 0, 1, 0) == 0)
  922. {
  923. return TRUE;
  924. }
  925. }
  926. }
  927. }
  928. #endif
  929. SDL_mutexP(gSndPlayer.mtx);
  930. if (gSndPlayer.pCDPlayer)
  931. {
  932. if (iNumTrack != -1)
  933. {
  934. AUDIO_PlayMusic(-1, FALSE, 0);
  935. ret = gSndPlayer.pCDPlayer->Play(gSndPlayer.pCDPlayer, PAL_CDTRACK_BASE + iNumTrack, TRUE, 0);
  936. }
  937. else
  938. {
  939. ret = gSndPlayer.pCDPlayer->Play(gSndPlayer.pCDPlayer, -1, FALSE, 0);
  940. }
  941. }
  942. SDL_mutexV(gSndPlayer.mtx);
  943. return ret;
  944. }
  945. VOID
  946. AUDIO_EnableMusic(
  947. BOOL fEnable
  948. )
  949. {
  950. gSndPlayer.fMusicEnabled = fEnable;
  951. }
  952. BOOL
  953. AUDIO_MusicEnabled(
  954. VOID
  955. )
  956. {
  957. return gSndPlayer.fMusicEnabled;
  958. }
  959. VOID
  960. AUDIO_EnableSound(
  961. BOOL fEnable
  962. )
  963. {
  964. gSndPlayer.fSoundEnabled = fEnable;
  965. }
  966. BOOL
  967. AUDIO_SoundEnabled(
  968. VOID
  969. )
  970. {
  971. return gSndPlayer.fSoundEnabled;
  972. }
  973. #ifdef PSP
  974. void
  975. SOUND_Reload(
  976. void
  977. )
  978. {
  979. fclose(gSndPlayer.mkf);
  980. SOUND_LoadMKF();
  981. }
  982. #endif