sound.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  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 "common.h"
  23. #include "sound.h"
  24. #include "rixplay.h"
  25. #include "util.h"
  26. #ifdef PAL_HAS_NATIVEMIDI
  27. #include "midi.h"
  28. #endif
  29. #ifdef PAL_HAS_MP3
  30. #include "libmad/music_mad.h"
  31. #endif
  32. static BOOL gSndOpened = FALSE;
  33. BOOL g_fNoSound = FALSE;
  34. BOOL g_fNoMusic = FALSE;
  35. #ifdef PAL_HAS_NATIVEMIDI
  36. BOOL g_fUseMidi = FALSE;
  37. #endif
  38. static BOOL g_fUseWav = FALSE;
  39. #ifdef __SYMBIAN32__
  40. INT g_iVolume = SDL_MIX_MAXVOLUME * 0.1;
  41. #endif
  42. #ifdef PAL_CLASSIC
  43. int g_iCurrChannel = 0;
  44. #endif
  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. #ifdef PAL_HAS_CD
  53. SDL_CD *pCD;
  54. #endif
  55. #ifdef PAL_HAS_MP3
  56. mad_data *pMP3;
  57. BOOL fMP3Loop;
  58. INT iCurrentMP3;
  59. SDL_mutex *lock;
  60. #endif
  61. } SNDPLAYER;
  62. static SNDPLAYER gSndPlayer;
  63. static SDL_AudioSpec *
  64. SOUND_LoadVOCFromBuffer(
  65. LPCBYTE lpVOC,
  66. DWORD dwLen,
  67. SDL_AudioSpec *lpSpec,
  68. LPBYTE *lppBuffer
  69. )
  70. /*++
  71. Purpose:
  72. Load a VOC file in a buffer. Currently supports type 01 block only.
  73. Parameters:
  74. [IN] lpVOC - pointer to the buffer of the VOC file.
  75. [IN] dwLen - length of the buffer of the VOC file.
  76. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  77. some basic information about the VOC file.
  78. [OUT] lppBuffer - the output buffer.
  79. Return value:
  80. Pointer to the SDL_AudioSpec structure, NULL if failed.
  81. --*/
  82. {
  83. INT freq, len, x, i, l;
  84. SDL_RWops *rw;
  85. if (g_fUseWav)
  86. {
  87. rw = SDL_RWFromConstMem(lpVOC, dwLen);
  88. if (rw == NULL) return NULL;
  89. len = dwLen;
  90. SDL_LoadWAV_RW(rw, 1, lpSpec, lppBuffer, (Uint32 *)&len);
  91. lpSpec->size = len;
  92. return lpSpec;
  93. }
  94. else
  95. {
  96. //
  97. // Skip header
  98. //
  99. lpVOC += 0x1B;
  100. //
  101. // Length is 3 bytes long
  102. //
  103. len = (lpVOC[0] | (lpVOC[1] << 8) | (lpVOC[2] << 16)) - 2;
  104. lpVOC += 3;
  105. //
  106. // One byte for frequency
  107. //
  108. freq = 1000000 / (256 - *lpVOC);
  109. #if 1
  110. lpVOC += 2;
  111. //
  112. // Convert the sample manually, as SDL doesn't like "strange" sample rates.
  113. //
  114. x = (INT)(len * ((FLOAT)PAL_SAMPLE_RATE / freq));
  115. *lppBuffer = (LPBYTE)calloc(1, x);
  116. if (*lppBuffer == NULL)
  117. {
  118. return NULL;
  119. }
  120. for (i = 0; i < x; i++)
  121. {
  122. l = (INT)(i * (freq / (FLOAT)PAL_SAMPLE_RATE));
  123. if (l >= len)
  124. {
  125. l = len - 1;
  126. }
  127. (*lppBuffer)[i] = lpVOC[l];
  128. }
  129. lpSpec->channels = 1;
  130. lpSpec->format = AUDIO_U8;
  131. lpSpec->freq = PAL_SAMPLE_RATE;
  132. lpSpec->size = x;
  133. #else
  134. *lppBuffer = (unsigned char *)malloc(len);
  135. if (*lppBuffer == NULL)
  136. {
  137. return NULL;
  138. }
  139. lpSpec->channels = 1;
  140. lpSpec->format = AUDIO_U8;
  141. lpSpec->freq = freq;
  142. lpSpec->size = len;
  143. lpVOC += 2;
  144. memcpy(*lppBuffer, lpVOC, len);
  145. #endif
  146. return lpSpec;
  147. }
  148. }
  149. static VOID SDLCALL
  150. SOUND_FillAudio(
  151. LPVOID udata,
  152. LPBYTE stream,
  153. INT len
  154. )
  155. /*++
  156. Purpose:
  157. SDL sound callback function.
  158. Parameters:
  159. [IN] udata - pointer to user-defined parameters (Not used).
  160. [OUT] stream - pointer to the stream buffer.
  161. [IN] len - Length of the buffer.
  162. Return value:
  163. None.
  164. --*/
  165. {
  166. int i;
  167. #if SDL_VERSION_ATLEAST(2,0,0)
  168. memset(stream, 0, len);
  169. #endif
  170. //
  171. // Play music
  172. //
  173. if (!g_fNoMusic)
  174. {
  175. #ifdef PAL_HAS_MP3
  176. SDL_mutexP(gSndPlayer.lock);
  177. if (gSndPlayer.pMP3 != NULL)
  178. {
  179. mad_getSamples(gSndPlayer.pMP3, stream, len);
  180. if (!mad_isPlaying(gSndPlayer.pMP3) && gSndPlayer.fMP3Loop)
  181. {
  182. mad_seek(gSndPlayer.pMP3, 0);
  183. mad_start(gSndPlayer.pMP3);
  184. mad_getSamples(gSndPlayer.pMP3, stream, len);
  185. }
  186. }
  187. SDL_mutexV(gSndPlayer.lock);
  188. #endif
  189. RIX_FillBuffer(stream, len);
  190. }
  191. //
  192. // No current playing sound
  193. //
  194. if (g_fNoSound)
  195. {
  196. return;
  197. }
  198. SDL_mutexP(gSndPlayer.mtx);
  199. for (i = 0; i < 2; i++)
  200. {
  201. //
  202. // Only play if we have data left
  203. //
  204. if (gSndPlayer.buf[i] == NULL)
  205. {
  206. continue;
  207. }
  208. if (gSndPlayer.audio_len[i] == 0)
  209. {
  210. //
  211. // Delete the audio buffer from memory
  212. //
  213. free(gSndPlayer.buf[i]);
  214. gSndPlayer.buf[i] = NULL;
  215. continue;
  216. }
  217. //
  218. // Mix as much data as possible
  219. //
  220. len = (len > gSndPlayer.audio_len[i]) ? gSndPlayer.audio_len[i] : len;
  221. #ifdef __SYMBIAN32__
  222. SDL_MixAudio(stream, gSndPlayer.pos[i], len, g_iVolume);
  223. #else
  224. SDL_MixAudio(stream, gSndPlayer.pos[i], len, SDL_MIX_MAXVOLUME * 2 / 3);
  225. #endif
  226. gSndPlayer.pos[i] += len;
  227. gSndPlayer.audio_len[i] -= len;
  228. }
  229. SDL_mutexV(gSndPlayer.mtx);
  230. }
  231. INT
  232. SOUND_OpenAudio(
  233. VOID
  234. )
  235. /*++
  236. Purpose:
  237. Initialize the audio subsystem.
  238. Parameters:
  239. None.
  240. Return value:
  241. 0 if succeed, others if failed.
  242. --*/
  243. {
  244. SDL_AudioSpec spec;
  245. if (gSndOpened)
  246. {
  247. //
  248. // Already opened
  249. //
  250. return -1;
  251. }
  252. gSndOpened = FALSE;
  253. //
  254. // Load the MKF file.
  255. //
  256. gSndPlayer.mkf = UTIL_OpenFile("voc.mkf");
  257. if (gSndPlayer.mkf == NULL)
  258. {
  259. gSndPlayer.mkf = UTIL_OpenFile("sounds.mkf");
  260. if (gSndPlayer.mkf == NULL)
  261. {
  262. return -2;
  263. }
  264. g_fUseWav = TRUE;
  265. }
  266. else
  267. {
  268. g_fUseWav = FALSE;
  269. }
  270. //
  271. // Open the sound subsystem.
  272. //
  273. gSndPlayer.spec.freq = PAL_SAMPLE_RATE;
  274. gSndPlayer.spec.format = AUDIO_S16;
  275. gSndPlayer.spec.channels = PAL_CHANNELS;
  276. gSndPlayer.spec.samples = 1024;
  277. gSndPlayer.spec.callback = SOUND_FillAudio;
  278. if (SDL_OpenAudio(&gSndPlayer.spec, &spec) < 0)
  279. {
  280. //
  281. // Failed
  282. //
  283. return -3;
  284. }
  285. memcpy(&gSndPlayer.spec, &spec, sizeof(SDL_AudioSpec));
  286. gSndPlayer.buf[0] = NULL;
  287. gSndPlayer.pos[0] = NULL;
  288. gSndPlayer.audio_len[0] = 0;
  289. gSndPlayer.buf[1] = NULL;
  290. gSndPlayer.pos[1] = NULL;
  291. gSndPlayer.audio_len[1] = 0;
  292. gSndPlayer.mtx = SDL_CreateMutex();
  293. gSndOpened = TRUE;
  294. //
  295. // Initialize the music subsystem.
  296. //
  297. if (RIX_Init(va("%s%s", PAL_PREFIX, "mus.mkf")) < 0)
  298. {
  299. RIX_Init(va("%s%s", PAL_PREFIX, "MUS.MKF"));
  300. }
  301. #ifdef PAL_HAS_CD
  302. //
  303. // Initialize the CD audio.
  304. //
  305. {
  306. int i;
  307. gSndPlayer.pCD = NULL;
  308. for (i = 0; i < SDL_CDNumDrives(); i++)
  309. {
  310. gSndPlayer.pCD = SDL_CDOpen(i);
  311. if (gSndPlayer.pCD != NULL)
  312. {
  313. if (!CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
  314. {
  315. SDL_CDClose(gSndPlayer.pCD);
  316. gSndPlayer.pCD = NULL;
  317. }
  318. else
  319. {
  320. break;
  321. }
  322. }
  323. }
  324. }
  325. #endif
  326. #ifdef PAL_HAS_MP3
  327. gSndPlayer.iCurrentMP3 = -1;
  328. gSndPlayer.lock = SDL_CreateMutex();
  329. #endif
  330. //
  331. // Let the callback function run so that musics will be played.
  332. //
  333. SDL_PauseAudio(0);
  334. return 0;
  335. }
  336. #ifdef PSP
  337. void
  338. SOUND_ReloadVOC(
  339. void
  340. )
  341. {
  342. fclose(gSndPlayer.mkf);
  343. gSndPlayer.mkf = UTIL_OpenFile("voc.mkf");
  344. g_fUseWav = FALSE;
  345. }
  346. #endif
  347. VOID
  348. SOUND_CloseAudio(
  349. VOID
  350. )
  351. /*++
  352. Purpose:
  353. Close the audio subsystem.
  354. Parameters:
  355. None.
  356. Return value:
  357. None.
  358. --*/
  359. {
  360. SDL_mutexP(gSndPlayer.mtx);
  361. SDL_CloseAudio();
  362. if (gSndPlayer.buf[0] != NULL)
  363. {
  364. free(gSndPlayer.buf[0]);
  365. gSndPlayer.buf[0] = NULL;
  366. }
  367. if (gSndPlayer.buf[1] != NULL)
  368. {
  369. free(gSndPlayer.buf[1]);
  370. gSndPlayer.buf[1] = NULL;
  371. }
  372. if (gSndPlayer.mkf != NULL)
  373. {
  374. fclose(gSndPlayer.mkf);
  375. gSndPlayer.mkf = NULL;
  376. }
  377. SDL_DestroyMutex(gSndPlayer.mtx);
  378. #ifdef PAL_HAS_MP3
  379. SDL_mutexP(gSndPlayer.lock);
  380. if (gSndPlayer.pMP3 != NULL)
  381. {
  382. mad_stop(gSndPlayer.pMP3);
  383. mad_closeFile(gSndPlayer.pMP3);
  384. gSndPlayer.pMP3 = NULL;
  385. }
  386. SDL_DestroyMutex(gSndPlayer.lock);
  387. #endif
  388. RIX_Shutdown();
  389. #ifdef PAL_HAS_CD
  390. if (gSndPlayer.pCD != NULL)
  391. {
  392. SOUND_PlayCDA(-1);
  393. SDL_CDClose(gSndPlayer.pCD);
  394. }
  395. #endif
  396. #ifdef PAL_HAS_NATIVEMIDI
  397. MIDI_Play(0, FALSE);
  398. #endif
  399. }
  400. #ifdef __SYMBIAN32__
  401. VOID
  402. SOUND_AdjustVolume(
  403. INT iDirectory
  404. )
  405. /*++
  406. Purpose:
  407. SDL sound volume adjust function.
  408. Parameters:
  409. [IN] iDirectory - value, Increase (>0) or decrease (<=0) 3% volume.
  410. Return value:
  411. None.
  412. --*/
  413. {
  414. if (iDirectory > 0)
  415. {
  416. if (g_iVolume <= SDL_MIX_MAXVOLUME)
  417. {
  418. g_iVolume += SDL_MIX_MAXVOLUME * 0.03;
  419. }
  420. else
  421. {
  422. g_iVolume = SDL_MIX_MAXVOLUME;
  423. }
  424. }
  425. else
  426. {
  427. if (g_iVolume > 0)
  428. {
  429. g_iVolume -= SDL_MIX_MAXVOLUME * 0.03;
  430. }
  431. else
  432. {
  433. g_iVolume = 0;
  434. }
  435. }
  436. }
  437. #endif
  438. VOID
  439. SOUND_PlayChannel(
  440. INT iSoundNum,
  441. INT iChannel
  442. )
  443. /*++
  444. Purpose:
  445. Play a sound in voc.mkf file.
  446. Parameters:
  447. [IN] iSoundNum - number of the sound.
  448. [IN] iChannel - the number of channel (0 or 1).
  449. Return value:
  450. None.
  451. --*/
  452. {
  453. SDL_AudioCVT wavecvt;
  454. SDL_AudioSpec wavespec;
  455. LPBYTE buf, bufdec;
  456. UINT samplesize;
  457. int len;
  458. if (!gSndOpened || g_fNoSound)
  459. {
  460. return;
  461. }
  462. //
  463. // Stop playing current sound.
  464. //
  465. SDL_mutexP(gSndPlayer.mtx);
  466. if (gSndPlayer.buf[iChannel] != NULL)
  467. {
  468. LPBYTE p = gSndPlayer.buf[iChannel];
  469. gSndPlayer.buf[iChannel] = NULL;
  470. free(p);
  471. }
  472. SDL_mutexV(gSndPlayer.mtx);
  473. if (iSoundNum < 0)
  474. {
  475. return;
  476. }
  477. //
  478. // Get the length of the sound file.
  479. //
  480. len = PAL_MKFGetChunkSize(iSoundNum, gSndPlayer.mkf);
  481. if (len <= 0)
  482. {
  483. return;
  484. }
  485. buf = (LPBYTE)calloc(len, 1);
  486. if (buf == NULL)
  487. {
  488. return;
  489. }
  490. //
  491. // Read the sound file from the MKF archive.
  492. //
  493. PAL_MKFReadChunk(buf, len, iSoundNum, gSndPlayer.mkf);
  494. SOUND_LoadVOCFromBuffer(buf, len, &wavespec, &bufdec);
  495. free(buf);
  496. //
  497. // Build the audio converter and create conversion buffers
  498. //
  499. if (SDL_BuildAudioCVT(&wavecvt, wavespec.format, wavespec.channels, wavespec.freq,
  500. gSndPlayer.spec.format, gSndPlayer.spec.channels, gSndPlayer.spec.freq) < 0)
  501. {
  502. free(bufdec);
  503. return;
  504. }
  505. samplesize = ((wavespec.format & 0xFF) / 8) * wavespec.channels;
  506. wavecvt.len = wavespec.size & ~(samplesize - 1);
  507. wavecvt.buf = (LPBYTE)malloc(wavecvt.len * wavecvt.len_mult);
  508. if (wavecvt.buf == NULL)
  509. {
  510. free(bufdec);
  511. return;
  512. }
  513. memcpy(wavecvt.buf, bufdec, wavespec.size);
  514. if (g_fUseWav)
  515. {
  516. SDL_FreeWAV(bufdec);
  517. }
  518. else
  519. {
  520. free(bufdec);
  521. }
  522. //
  523. // Run the audio converter
  524. //
  525. if (SDL_ConvertAudio(&wavecvt) < 0)
  526. {
  527. return;
  528. }
  529. SDL_mutexP(gSndPlayer.mtx);
  530. if (gSndPlayer.buf[iChannel] != NULL)
  531. {
  532. LPBYTE p = gSndPlayer.buf[iChannel];
  533. gSndPlayer.buf[iChannel] = NULL;
  534. free(p);
  535. }
  536. gSndPlayer.buf[iChannel] = wavecvt.buf;
  537. gSndPlayer.audio_len[iChannel] = wavecvt.len * wavecvt.len_mult;
  538. gSndPlayer.pos[iChannel] = wavecvt.buf;
  539. SDL_mutexV(gSndPlayer.mtx);
  540. }
  541. VOID
  542. PAL_PlayMUS(
  543. INT iNumRIX,
  544. BOOL fLoop,
  545. FLOAT flFadeTime
  546. )
  547. {
  548. #ifdef PAL_HAS_NATIVEMIDI
  549. if (g_fUseMidi)
  550. {
  551. MIDI_Play(iNumRIX, fLoop);
  552. return;
  553. }
  554. #endif
  555. #ifdef PAL_HAS_MP3
  556. SDL_mutexP(gSndPlayer.lock);
  557. if (gSndPlayer.pMP3 != NULL)
  558. {
  559. if (iNumRIX == gSndPlayer.iCurrentMP3 && !g_fNoMusic)
  560. {
  561. SDL_mutexV(gSndPlayer.lock);
  562. return;
  563. }
  564. mad_stop(gSndPlayer.pMP3);
  565. mad_closeFile(gSndPlayer.pMP3);
  566. gSndPlayer.pMP3 = NULL;
  567. }
  568. SDL_mutexV(gSndPlayer.lock);
  569. gSndPlayer.iCurrentMP3 = -1;
  570. if (iNumRIX > 0)
  571. {
  572. SDL_mutexP(gSndPlayer.lock);
  573. gSndPlayer.pMP3 = mad_openFile(va("%s/mp3/%.2d.mp3", PAL_PREFIX, iNumRIX), &gSndPlayer.spec);
  574. if (gSndPlayer.pMP3 != NULL)
  575. {
  576. RIX_Play(0, FALSE, flFadeTime);
  577. mad_start(gSndPlayer.pMP3);
  578. gSndPlayer.fMP3Loop = fLoop;
  579. gSndPlayer.iCurrentMP3 = iNumRIX;
  580. SDL_mutexV(gSndPlayer.lock);
  581. return;
  582. }
  583. SDL_mutexV(gSndPlayer.lock);
  584. }
  585. #endif
  586. RIX_Play(iNumRIX, fLoop, flFadeTime);
  587. }
  588. BOOL
  589. SOUND_PlayCDA(
  590. INT iNumTrack
  591. )
  592. /*++
  593. Purpose:
  594. Play a CD Audio Track.
  595. Parameters:
  596. [IN] iNumTrack - number of the CD Audio Track.
  597. Return value:
  598. TRUE if the track can be played, FALSE if not.
  599. --*/
  600. {
  601. #ifdef PAL_HAS_CD
  602. if (gSndPlayer.pCD != NULL)
  603. {
  604. if (CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
  605. {
  606. SDL_CDStop(gSndPlayer.pCD);
  607. if (iNumTrack != -1)
  608. {
  609. PAL_PlayMUS(-1, FALSE, 0);
  610. if (SDL_CDPlayTracks(gSndPlayer.pCD, iNumTrack - 1, 0, 1, 0) == 0)
  611. {
  612. return TRUE;
  613. }
  614. }
  615. }
  616. }
  617. #endif
  618. return FALSE;
  619. }