sound.c 22 KB

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