sound.c 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  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 __SYMBIAN32__
  38. INT g_iVolume = SDL_MIX_MAXVOLUME * 0.1;
  39. #endif
  40. #ifdef PAL_CLASSIC
  41. int g_iCurrChannel = 0;
  42. #endif
  43. #define PAL_CDTRACK_BASE 10000
  44. typedef LPCBYTE(*FNLoadSoundData)(LPCBYTE, DWORD, SDL_AudioSpec *);
  45. typedef struct tagSNDPLAYER
  46. {
  47. FILE *mkf;
  48. SDL_AudioSpec spec;
  49. SDL_mutex *mtx;
  50. LPBYTE buf[2], pos[2];
  51. INT audio_len[2];
  52. void *resampler;
  53. MUSICPLAYER *pMusPlayer;
  54. MUSICPLAYER *pCDPlayer;
  55. #if PAL_HAS_SDLCD
  56. SDL_CD *pCD;
  57. #endif
  58. FNLoadSoundData LoadSoundData;
  59. } SNDPLAYER;
  60. static SNDPLAYER gSndPlayer;
  61. typedef struct tagRIFFHEADER
  62. {
  63. DWORD riff_sig; /* 'RIFF' */
  64. DWORD data_length; /* Total length minus eight, little-endian */
  65. DWORD riff_type; /* 'WAVE' */
  66. } RIFFHEADER, *LPRIFFHEADER;
  67. typedef const RIFFHEADER *LPCRIFFHEADER;
  68. typedef struct tagRIFFCHUNK
  69. {
  70. DWORD chunk_type; /* 'fmt ' and so on */
  71. DWORD chunk_length; /* Total chunk length minus eight, little-endian */
  72. } RIFFCHUNK, *LPRIFFCHUNK;
  73. typedef const RIFFCHUNK *LPCRIFFCHUNK;
  74. typedef struct tagWAVEFORMATPCM
  75. {
  76. WORD wFormatTag; /* format type */
  77. WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */
  78. DWORD nSamplesPerSec; /* sample rate */
  79. DWORD nAvgBytesPerSec; /* for buffer estimation */
  80. WORD nBlockAlign; /* block size of data */
  81. WORD wBitsPerSample;
  82. } WAVEFORMATPCM, *LPWAVEFORMATPCM;
  83. typedef const WAVEFORMATPCM *LPCWAVEFORMATPCM;
  84. static LPCBYTE
  85. SOUND_LoadWAVEData(
  86. LPCBYTE lpData,
  87. DWORD dwLen,
  88. SDL_AudioSpec *lpSpec
  89. )
  90. /*++
  91. Purpose:
  92. Return the WAVE data pointer inside the input buffer.
  93. Parameters:
  94. [IN] lpData - pointer to the buffer of the WAVE file.
  95. [IN] dwLen - length of the buffer of the WAVE file.
  96. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  97. some basic information about the WAVE file.
  98. Return value:
  99. Pointer to the WAVE data inside the input buffer, NULL if failed.
  100. --*/
  101. {
  102. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  103. # define RIFF 'RIFF'
  104. # define WAVE 'WAVE'
  105. # define FMT 'fmt '
  106. # define DATA 'data'
  107. # define PCM 0x0100
  108. #else
  109. # define RIFF 'FFIR'
  110. # define WAVE 'EVAW'
  111. # define FMT ' tmf'
  112. # define DATA 'atad'
  113. # define PCM 0x0001
  114. #endif
  115. LPCRIFFHEADER lpRiff = (LPCRIFFHEADER)lpData;
  116. LPCRIFFCHUNK lpChunk;
  117. LPCWAVEFORMATPCM lpFormat = NULL;
  118. LPCBYTE lpWaveData = NULL;
  119. DWORD len;
  120. if (dwLen < sizeof(RIFFHEADER) || lpRiff->riff_sig != RIFF || lpRiff->riff_type != WAVE || dwLen < SDL_SwapLE32(lpRiff->data_length) + 8)
  121. {
  122. return NULL;
  123. }
  124. lpChunk = (LPCRIFFCHUNK)(lpRiff + 1); dwLen -= sizeof(RIFFHEADER);
  125. while (dwLen >= sizeof(RIFFCHUNK))
  126. {
  127. len = SDL_SwapLE32(lpChunk->chunk_length);
  128. if (dwLen >= sizeof(RIFFCHUNK) + len)
  129. dwLen -= sizeof(RIFFCHUNK) + len;
  130. else
  131. return NULL;
  132. switch (lpChunk->chunk_type)
  133. {
  134. case FMT:
  135. lpFormat = (LPCWAVEFORMATPCM)(lpChunk + 1);
  136. if (len != sizeof(WAVEFORMATPCM) || lpFormat->wFormatTag != PCM)
  137. {
  138. return NULL;
  139. }
  140. break;
  141. case DATA:
  142. lpWaveData = (LPCBYTE)(lpChunk + 1);
  143. dwLen = 0;
  144. break;
  145. }
  146. lpChunk = (LPCRIFFCHUNK)((LPCBYTE)(lpChunk + 1) + len);
  147. }
  148. if (lpFormat == NULL || lpWaveData == NULL)
  149. {
  150. return NULL;
  151. }
  152. lpSpec->channels = lpFormat->nChannels;
  153. lpSpec->format = (lpFormat->wBitsPerSample == 16) ? AUDIO_S16 : AUDIO_U8;
  154. lpSpec->freq = lpFormat->nSamplesPerSec;
  155. lpSpec->size = len;
  156. return lpWaveData;
  157. #undef RIFF
  158. #undef WAVE
  159. #undef FMT
  160. }
  161. typedef struct tagVOCHEADER
  162. {
  163. char signature[0x14]; /* "Creative Voice File\x1A" */
  164. WORD data_offset; /* little endian */
  165. WORD version;
  166. WORD version_checksum;
  167. } VOCHEADER, *LPVOCHEADER;
  168. typedef const VOCHEADER *LPCVOCHEADER;
  169. static LPCBYTE
  170. SOUND_LoadVOCData(
  171. LPCBYTE lpData,
  172. DWORD dwLen,
  173. SDL_AudioSpec *lpSpec
  174. )
  175. /*++
  176. Purpose:
  177. Return the VOC data pointer inside the input buffer. Currently supports type 01 block only.
  178. Parameters:
  179. [IN] lpData - pointer to the buffer of the VOC file.
  180. [IN] dwLen - length of the buffer of the VOC file.
  181. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  182. some basic information about the VOC file.
  183. Return value:
  184. Pointer to the WAVE data inside the input buffer, NULL if failed.
  185. Reference: http://sox.sourceforge.net/AudioFormats-11.html
  186. --*/
  187. {
  188. LPCVOCHEADER lpVOC = (LPCVOCHEADER)lpData;
  189. if (dwLen < sizeof(VOCHEADER) || memcmp(lpVOC->signature, "Creative Voice File\x1A", 0x14) || SDL_SwapLE16(lpVOC->data_offset) >= dwLen)
  190. {
  191. return NULL;
  192. }
  193. lpData += SDL_SwapLE16(lpVOC->data_offset);
  194. dwLen -= SDL_SwapLE16(lpVOC->data_offset);
  195. while (dwLen && *lpData)
  196. {
  197. DWORD len;
  198. if (dwLen >= 4)
  199. {
  200. len = lpData[1] | (lpData[2] << 8) | (lpData[3] << 16);
  201. if (dwLen >= len + 4)
  202. dwLen -= len + 4;
  203. else
  204. return NULL;
  205. }
  206. else
  207. {
  208. return NULL;
  209. }
  210. if (*lpData == 0x01)
  211. {
  212. if (lpData[5] != 0) return NULL; /* Only 8-bit is supported */
  213. lpSpec->format = AUDIO_U8;
  214. lpSpec->channels = 1;
  215. lpSpec->freq = ((1000000 / (256 - lpData[4]) + 99) / 100) * 100; /* Round to next 100Hz */
  216. lpSpec->size = len - 2;
  217. return lpData + 6;
  218. }
  219. else
  220. {
  221. lpData += len + 4;
  222. }
  223. }
  224. return NULL;
  225. }
  226. static void
  227. SOUND_ResampleU8(
  228. LPCBYTE lpData,
  229. const SDL_AudioSpec *lpSpec,
  230. LPBYTE lpBuffer,
  231. DWORD dwLen,
  232. void *resampler
  233. )
  234. /*++
  235. Purpose:
  236. Resample 8-bit unsigned PCM data into 16-bit signed (little-endian) PCM data.
  237. Parameters:
  238. [IN] lpData - pointer to the buffer of the input PCM data.
  239. [IN] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  240. some basic information about the input PCM data.
  241. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  242. [IN] dwLen - length of the buffer of the output PCM data, should be exactly
  243. the number of bytes needed of the resampled data.
  244. [IN] resampler - pointer of the resampler instance.
  245. Return value:
  246. None.
  247. --*/
  248. {
  249. int src_samples = lpSpec->size / lpSpec->channels, i;
  250. for (i = 0; i < lpSpec->channels; i++)
  251. {
  252. LPCBYTE src = lpData + i;
  253. short *dst = (short *)lpBuffer + i;
  254. int channel_len = dwLen / lpSpec->channels, total_bytes = 0;
  255. resampler_clear(resampler);
  256. while (total_bytes < channel_len && src_samples > 0)
  257. {
  258. int to_write, j;
  259. to_write = resampler_get_free_count(resampler);
  260. if (to_write > src_samples) to_write = src_samples;
  261. for (j = 0; j < to_write; j++)
  262. {
  263. resampler_write_sample(resampler, (*src ^ 0x80) << 8);
  264. src += lpSpec->channels;
  265. }
  266. src_samples -= to_write;
  267. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  268. {
  269. *dst = SDL_SwapLE16(resampler_get_and_remove_sample(resampler));
  270. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  271. }
  272. }
  273. /* Flush resampler's output buffer */
  274. while (total_bytes < channel_len)
  275. {
  276. int j, to_write = resampler_get_free_count(resampler);
  277. for (j = 0; j < to_write; j++)
  278. resampler_write_sample(resampler, (src[-lpSpec->channels] ^ 0x80) << 8);
  279. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  280. {
  281. *dst = SDL_SwapLE16(resampler_get_and_remove_sample(resampler));
  282. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  283. }
  284. }
  285. }
  286. }
  287. static void
  288. SOUND_ResampleS16(
  289. LPCBYTE lpData,
  290. const SDL_AudioSpec *lpSpec,
  291. LPBYTE lpBuffer,
  292. DWORD dwLen,
  293. void *resampler
  294. )
  295. /*++
  296. Purpose:
  297. Resample 16-bit signed (little-endian) PCM data into 16-bit signed (little-endian) PCM data.
  298. Parameters:
  299. [IN] lpData - pointer to the buffer of the input PCM data.
  300. [IN] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  301. some basic information about the input PCM data.
  302. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  303. [IN] dwLen - length of the buffer of the output PCM data, should be exactly
  304. the number of bytes needed of the resampled data.
  305. [IN] resampler - pointer of the resampler instance.
  306. Return value:
  307. None.
  308. --*/
  309. {
  310. int src_samples = lpSpec->size / lpSpec->channels / 2, i;
  311. for (i = 0; i < lpSpec->channels; i++)
  312. {
  313. const short *src = (short *)lpData + i;
  314. short *dst = (short *)lpBuffer + i;
  315. int channel_len = dwLen / lpSpec->channels, total_bytes = 0;
  316. resampler_clear(resampler);
  317. while (total_bytes < channel_len && src_samples > 0)
  318. {
  319. int to_write, j;
  320. to_write = resampler_get_free_count(resampler);
  321. if (to_write > src_samples) to_write = src_samples;
  322. for (j = 0; j < to_write; j++)
  323. {
  324. resampler_write_sample(resampler, SDL_SwapLE16(*src));
  325. src += lpSpec->channels;
  326. }
  327. src_samples -= to_write;
  328. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  329. {
  330. *dst = SDL_SwapLE16(resampler_get_and_remove_sample(resampler));
  331. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  332. }
  333. }
  334. /* Flush resampler's output buffer */
  335. while (total_bytes < channel_len)
  336. {
  337. int j, to_write = resampler_get_free_count(resampler);
  338. short val = SDL_SwapLE16(src[-lpSpec->channels]);
  339. for (j = 0; j < to_write; j++)
  340. resampler_write_sample(resampler, val);
  341. while (total_bytes < channel_len && resampler_get_sample_count(resampler) > 0)
  342. {
  343. *dst = SDL_SwapLE16(resampler_get_and_remove_sample(resampler));
  344. dst += lpSpec->channels; total_bytes += (SDL_AUDIO_BITSIZE(AUDIO_S16) >> 3);
  345. }
  346. }
  347. }
  348. }
  349. static VOID SDLCALL
  350. SOUND_FillAudio(
  351. LPVOID udata,
  352. LPBYTE stream,
  353. INT len
  354. )
  355. /*++
  356. Purpose:
  357. SDL sound callback function.
  358. Parameters:
  359. [IN] udata - pointer to user-defined parameters (Not used).
  360. [OUT] stream - pointer to the stream buffer.
  361. [IN] len - Length of the buffer.
  362. Return value:
  363. None.
  364. --*/
  365. {
  366. int i;
  367. #if SDL_VERSION_ATLEAST(2,0,0)
  368. memset(stream, 0, len);
  369. #endif
  370. //
  371. // Play music
  372. //
  373. if (!g_fNoMusic)
  374. {
  375. SDL_mutexP(gSndPlayer.mtx);
  376. if (gSndPlayer.pMusPlayer)
  377. {
  378. gSndPlayer.pMusPlayer->FillBuffer(gSndPlayer.pMusPlayer, stream, len);
  379. }
  380. if (gSndPlayer.pCDPlayer)
  381. {
  382. gSndPlayer.pCDPlayer->FillBuffer(gSndPlayer.pCDPlayer, stream, len);
  383. }
  384. SDL_mutexV(gSndPlayer.mtx);
  385. }
  386. //
  387. // No current playing sound
  388. //
  389. if (g_fNoSound)
  390. {
  391. return;
  392. }
  393. SDL_mutexP(gSndPlayer.mtx);
  394. for (i = 0; i < 2; i++)
  395. {
  396. //
  397. // Only play if we have data left
  398. //
  399. if (gSndPlayer.buf[i] == NULL)
  400. {
  401. continue;
  402. }
  403. if (gSndPlayer.audio_len[i] == 0)
  404. {
  405. //
  406. // Delete the audio buffer from memory
  407. //
  408. free(gSndPlayer.buf[i]);
  409. gSndPlayer.buf[i] = NULL;
  410. continue;
  411. }
  412. //
  413. // Mix as much data as possible
  414. //
  415. len = (len > gSndPlayer.audio_len[i]) ? gSndPlayer.audio_len[i] : len;
  416. #ifdef __SYMBIAN32__
  417. SDL_MixAudio(stream, gSndPlayer.pos[i], len, g_iVolume);
  418. #else
  419. SDL_MixAudio(stream, gSndPlayer.pos[i], len, SDL_MIX_MAXVOLUME * 2 / 3);
  420. #endif
  421. gSndPlayer.pos[i] += len;
  422. gSndPlayer.audio_len[i] -= len;
  423. }
  424. SDL_mutexV(gSndPlayer.mtx);
  425. }
  426. INT
  427. SOUND_OpenAudio(
  428. VOID
  429. )
  430. /*++
  431. Purpose:
  432. Initialize the audio subsystem.
  433. Parameters:
  434. None.
  435. Return value:
  436. 0 if succeed, others if failed.
  437. --*/
  438. {
  439. SDL_AudioSpec spec;
  440. char *mkfs[2];
  441. FNLoadSoundData func[2];
  442. int i;
  443. if (gSndOpened)
  444. {
  445. //
  446. // Already opened
  447. //
  448. return -1;
  449. }
  450. gSndOpened = FALSE;
  451. //
  452. // Load the MKF file.
  453. //
  454. if (gpGlobals->fIsWIN95)
  455. {
  456. mkfs[0] = "sounds.mkf"; func[0] = SOUND_LoadWAVEData;
  457. mkfs[1] = "voc.mkf"; func[1] = SOUND_LoadVOCData;
  458. }
  459. else
  460. {
  461. mkfs[0] = "voc.mkf"; func[0] = SOUND_LoadVOCData;
  462. mkfs[1] = "sounds.mkf"; func[1] = SOUND_LoadWAVEData;
  463. }
  464. for (i = 0; i < 2; i++)
  465. {
  466. gSndPlayer.mkf = UTIL_OpenFile(mkfs[i]);
  467. if (gSndPlayer.mkf)
  468. {
  469. gSndPlayer.LoadSoundData = func[i];
  470. break;
  471. }
  472. }
  473. if (gSndPlayer.mkf == NULL)
  474. {
  475. return -2;
  476. }
  477. //
  478. // Initialize the resampler
  479. //
  480. resampler_init();
  481. gSndPlayer.resampler = resampler_create();
  482. //
  483. // Open the sound subsystem.
  484. //
  485. gSndPlayer.spec.freq = gpGlobals->iSampleRate;
  486. gSndPlayer.spec.format = AUDIO_S16;
  487. gSndPlayer.spec.channels = gpGlobals->iAudioChannels;
  488. gSndPlayer.spec.samples = 1024;
  489. gSndPlayer.spec.callback = SOUND_FillAudio;
  490. if (SDL_OpenAudio(&gSndPlayer.spec, &spec) < 0)
  491. {
  492. //
  493. // Failed
  494. //
  495. return -3;
  496. }
  497. memcpy(&gSndPlayer.spec, &spec, sizeof(SDL_AudioSpec));
  498. gSndPlayer.buf[0] = NULL;
  499. gSndPlayer.pos[0] = NULL;
  500. gSndPlayer.audio_len[0] = 0;
  501. gSndPlayer.buf[1] = NULL;
  502. gSndPlayer.pos[1] = NULL;
  503. gSndPlayer.audio_len[1] = 0;
  504. gSndPlayer.mtx = SDL_CreateMutex();
  505. gSndOpened = TRUE;
  506. //
  507. // Initialize the music subsystem.
  508. //
  509. switch (gpGlobals->eMusicType)
  510. {
  511. case MUSIC_RIX:
  512. if (!(gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", PAL_PREFIX, "mus.mkf"))))
  513. {
  514. gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", PAL_PREFIX, "MUS.MKF"));
  515. }
  516. break;
  517. case MUSIC_MP3:
  518. #if PAL_HAS_MP3
  519. gSndPlayer.pMusPlayer = MP3_Init(NULL);
  520. #else
  521. gSndPlayer.pMusPlayer = NULL;
  522. #endif
  523. break;
  524. case MUSIC_OGG:
  525. #if PAL_HAS_OGG
  526. gSndPlayer.pMusPlayer = OGG_Init(NULL);
  527. #else
  528. gSndPlayer.pMusPlayer = NULL;
  529. #endif
  530. break;
  531. case MUSIC_MIDI:
  532. gSndPlayer.pMusPlayer = NULL;
  533. break;
  534. }
  535. //
  536. // Initialize the CD audio.
  537. //
  538. switch (gpGlobals->eCDType)
  539. {
  540. case MUSIC_SDLCD:
  541. {
  542. #if PAL_HAS_SDLCD
  543. int i;
  544. gSndPlayer.pCD = NULL;
  545. for (i = 0; i < SDL_CDNumDrives(); i++)
  546. {
  547. gSndPlayer.pCD = SDL_CDOpen(i);
  548. if (gSndPlayer.pCD != NULL)
  549. {
  550. if (!CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
  551. {
  552. SDL_CDClose(gSndPlayer.pCD);
  553. gSndPlayer.pCD = NULL;
  554. }
  555. else
  556. {
  557. break;
  558. }
  559. }
  560. }
  561. #endif
  562. gSndPlayer.pCDPlayer = NULL;
  563. break;
  564. }
  565. case MUSIC_MP3:
  566. #if PAL_HAS_MP3
  567. gSndPlayer.pCDPlayer = MP3_Init(NULL);
  568. #else
  569. gSndPlayer.pCDPlayer = NULL;
  570. #endif
  571. break;
  572. case MUSIC_OGG:
  573. #if PAL_HAS_OGG
  574. gSndPlayer.pCDPlayer = OGG_Init(NULL);
  575. #else
  576. gSndPlayer.pCDPlayer = NULL;
  577. #endif
  578. break;
  579. }
  580. //
  581. // Let the callback function run so that musics will be played.
  582. //
  583. SDL_PauseAudio(0);
  584. return 0;
  585. }
  586. VOID
  587. SOUND_CloseAudio(
  588. VOID
  589. )
  590. /*++
  591. Purpose:
  592. Close the audio subsystem.
  593. Parameters:
  594. None.
  595. Return value:
  596. None.
  597. --*/
  598. {
  599. SDL_mutexP(gSndPlayer.mtx);
  600. SDL_CloseAudio();
  601. if (gSndPlayer.buf[0] != NULL)
  602. {
  603. free(gSndPlayer.buf[0]);
  604. gSndPlayer.buf[0] = NULL;
  605. }
  606. if (gSndPlayer.buf[1] != NULL)
  607. {
  608. free(gSndPlayer.buf[1]);
  609. gSndPlayer.buf[1] = NULL;
  610. }
  611. if (gSndPlayer.mkf != NULL)
  612. {
  613. fclose(gSndPlayer.mkf);
  614. gSndPlayer.mkf = NULL;
  615. }
  616. if (gSndPlayer.pMusPlayer)
  617. {
  618. gSndPlayer.pMusPlayer->Shutdown(gSndPlayer.pMusPlayer);
  619. gSndPlayer.pMusPlayer = NULL;
  620. }
  621. if (gSndPlayer.pCDPlayer)
  622. {
  623. gSndPlayer.pCDPlayer->Shutdown(gSndPlayer.pCDPlayer);
  624. gSndPlayer.pCDPlayer = NULL;
  625. }
  626. #if PAL_HAS_SDLCD
  627. if (gSndPlayer.pCD != NULL)
  628. {
  629. SOUND_PlayCDA(-1);
  630. SDL_CDClose(gSndPlayer.pCD);
  631. }
  632. #endif
  633. #ifdef PAL_HAS_NATIVEMIDI
  634. MIDI_Play(0, FALSE);
  635. #endif
  636. if (gSndPlayer.resampler)
  637. {
  638. resampler_delete(gSndPlayer.resampler);
  639. gSndPlayer.resampler = NULL;
  640. }
  641. SDL_DestroyMutex(gSndPlayer.mtx);
  642. }
  643. SDL_AudioSpec*
  644. SOUND_GetAudioSpec(
  645. VOID
  646. )
  647. {
  648. return &gSndPlayer.spec;
  649. }
  650. #ifdef __SYMBIAN32__
  651. VOID
  652. SOUND_AdjustVolume(
  653. INT iDirectory
  654. )
  655. /*++
  656. Purpose:
  657. SDL sound volume adjust function.
  658. Parameters:
  659. [IN] iDirectory - value, Increase (>0) or decrease (<=0) 3% volume.
  660. Return value:
  661. None.
  662. --*/
  663. {
  664. if (iDirectory > 0)
  665. {
  666. if (g_iVolume <= SDL_MIX_MAXVOLUME)
  667. {
  668. g_iVolume += SDL_MIX_MAXVOLUME * 0.03;
  669. }
  670. else
  671. {
  672. g_iVolume = SDL_MIX_MAXVOLUME;
  673. }
  674. }
  675. else
  676. {
  677. if (g_iVolume > 0)
  678. {
  679. g_iVolume -= SDL_MIX_MAXVOLUME * 0.03;
  680. }
  681. else
  682. {
  683. g_iVolume = 0;
  684. }
  685. }
  686. }
  687. #endif
  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. }