sound.c 14 KB

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