sound.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. /* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
  2. //
  3. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  4. // All rights reserved.
  5. //
  6. // This file is part of SDLPAL.
  7. //
  8. // SDLPAL is free software: you can redistribute it and/or modify
  9. // it under the terms of the GNU General Public License as published by
  10. // the Free Software Foundation, either version 3 of the License, or
  11. // (at your option) any later version.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU General Public License
  19. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. //
  21. #include "palcommon.h"
  22. #include "global.h"
  23. #include "palcfg.h"
  24. #include "audio.h"
  25. #include "players.h"
  26. #include "util.h"
  27. #include "resampler.h"
  28. #include "midi.h"
  29. #include <math.h>
  30. #if PAL_HAS_OGG
  31. #include <vorbis/codec.h>
  32. #endif
  33. #define PAL_CDTRACK_BASE 10000
  34. typedef struct tagWAVESPEC
  35. {
  36. int size;
  37. int freq;
  38. SDL_AudioFormat format;
  39. uint8_t channels;
  40. uint8_t align;
  41. } WAVESPEC;
  42. typedef const void * (*SoundLoader)(LPCBYTE, DWORD, WAVESPEC *);
  43. typedef int(*ResampleMixer)(void *[2], const void *, const WAVESPEC *, void *, int, const void **);
  44. typedef struct tagWAVEDATA
  45. {
  46. struct tagWAVEDATA *next;
  47. void *resampler[2]; /* The resampler used for sound data */
  48. ResampleMixer ResampleMix;
  49. const void *base;
  50. const void *current;
  51. const void *end;
  52. WAVESPEC spec;
  53. } WAVEDATA;
  54. typedef struct tagSOUNDPLAYER
  55. {
  56. AUDIOPLAYER_COMMONS;
  57. FILE *mkf; /* File pointer to the MKF file */
  58. SoundLoader LoadSound; /* The function pointer for load WAVE/VOC data */
  59. WAVEDATA soundlist;
  60. int cursounds;
  61. } SOUNDPLAYER, *LPSOUNDPLAYER;
  62. typedef struct tagRIFFHEADER
  63. {
  64. DWORD riff_sig; /* 'RIFF' */
  65. DWORD data_length; /* Total length minus eight, little-endian */
  66. DWORD riff_type; /* 'WAVE' */
  67. } RIFFHEADER, *LPRIFFHEADER;
  68. typedef const RIFFHEADER *LPCRIFFHEADER;
  69. typedef struct tagRIFFCHUNK
  70. {
  71. DWORD chunk_type; /* 'fmt ' and so on */
  72. DWORD chunk_length; /* Total chunk length minus eight, little-endian */
  73. } RIFFCHUNK, *LPRIFFCHUNK;
  74. typedef const RIFFCHUNK *LPCRIFFCHUNK;
  75. typedef struct tagWAVEFORMATPCM
  76. {
  77. WORD wFormatTag; /* format type */
  78. WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */
  79. DWORD nSamplesPerSec; /* sample rate */
  80. DWORD nAvgBytesPerSec; /* for buffer estimation */
  81. WORD nBlockAlign; /* block size of data */
  82. WORD wBitsPerSample;
  83. } WAVEFORMATPCM, *LPWAVEFORMATPCM;
  84. typedef const WAVEFORMATPCM *LPCWAVEFORMATPCM;
  85. static const void *
  86. SOUND_LoadWAVEData(
  87. LPCBYTE lpData,
  88. DWORD dwLen,
  89. WAVESPEC *lpSpec
  90. )
  91. /*++
  92. Purpose:
  93. Return the WAVE data pointer inside the input buffer.
  94. Parameters:
  95. [IN] lpData - pointer to the buffer of the WAVE file.
  96. [IN] dwLen - length of the buffer of the WAVE file.
  97. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  98. some basic information about the WAVE file.
  99. Return value:
  100. Pointer to the WAVE data inside the input buffer, NULL if failed.
  101. --*/
  102. {
  103. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  104. # define RIFF 'RIFF'
  105. # define WAVE 'WAVE'
  106. # define FMT 'fmt '
  107. # define DATA 'data'
  108. # define PCM 0x0100
  109. #else
  110. # define RIFF 'FFIR'
  111. # define WAVE 'EVAW'
  112. # define FMT ' tmf'
  113. # define DATA 'atad'
  114. # define PCM 0x0001
  115. #endif
  116. LPCRIFFHEADER lpRiff = (LPCRIFFHEADER)lpData;
  117. LPCRIFFCHUNK lpChunk;
  118. LPCWAVEFORMATPCM lpFormat = NULL;
  119. LPCBYTE lpWaveData = NULL;
  120. DWORD len;
  121. if (dwLen < sizeof(RIFFHEADER) || lpRiff->riff_sig != RIFF || lpRiff->riff_type != WAVE || dwLen < SDL_SwapLE32(lpRiff->data_length) + 8)
  122. {
  123. return NULL;
  124. }
  125. lpChunk = (LPCRIFFCHUNK)(lpRiff + 1); dwLen -= sizeof(RIFFHEADER);
  126. while (dwLen >= sizeof(RIFFCHUNK))
  127. {
  128. len = SDL_SwapLE32(lpChunk->chunk_length);
  129. if (dwLen >= sizeof(RIFFCHUNK) + len)
  130. dwLen -= sizeof(RIFFCHUNK) + len;
  131. else
  132. return NULL;
  133. switch (lpChunk->chunk_type)
  134. {
  135. case FMT:
  136. lpFormat = (LPCWAVEFORMATPCM)(lpChunk + 1);
  137. if (len != sizeof(WAVEFORMATPCM) || lpFormat->wFormatTag != PCM)
  138. {
  139. return NULL;
  140. }
  141. break;
  142. case DATA:
  143. lpWaveData = (LPCBYTE)(lpChunk + 1);
  144. dwLen = 0;
  145. break;
  146. }
  147. lpChunk = (LPCRIFFCHUNK)((LPCBYTE)(lpChunk + 1) + len);
  148. }
  149. if (lpFormat == NULL || lpWaveData == NULL)
  150. {
  151. return NULL;
  152. }
  153. lpSpec->channels = lpFormat->nChannels;
  154. lpSpec->format = (lpFormat->wBitsPerSample == 16) ? AUDIO_S16 : AUDIO_U8;
  155. lpSpec->freq = lpFormat->nSamplesPerSec;
  156. lpSpec->size = len;
  157. lpSpec->align = lpFormat->nChannels * lpFormat->wBitsPerSample >> 1;
  158. return lpWaveData;
  159. #undef RIFF
  160. #undef WAVE
  161. #undef FMT
  162. }
  163. typedef struct tagVOCHEADER
  164. {
  165. char signature[0x14]; /* "Creative Voice File\x1A" */
  166. WORD data_offset; /* little endian */
  167. WORD version;
  168. WORD version_checksum;
  169. } VOCHEADER, *LPVOCHEADER;
  170. typedef const VOCHEADER *LPCVOCHEADER;
  171. static const void *
  172. SOUND_LoadVOCData(
  173. LPCBYTE lpData,
  174. DWORD dwLen,
  175. WAVESPEC *lpSpec
  176. )
  177. /*++
  178. Purpose:
  179. Return the VOC data pointer inside the input buffer. Currently supports type 01 block only.
  180. Parameters:
  181. [IN] lpData - pointer to the buffer of the VOC file.
  182. [IN] dwLen - length of the buffer of the VOC file.
  183. [OUT] lpSpec - pointer to the SDL_AudioSpec structure, which contains
  184. some basic information about the VOC file.
  185. Return value:
  186. Pointer to the WAVE data inside the input buffer, NULL if failed.
  187. Reference: http://sox.sourceforge.net/AudioFormats-11.html
  188. --*/
  189. {
  190. LPCVOCHEADER lpVOC = (LPCVOCHEADER)lpData;
  191. if (dwLen < sizeof(VOCHEADER) || memcmp(lpVOC->signature, "Creative Voice File\x1A", 0x14) || SDL_SwapLE16(lpVOC->data_offset) >= dwLen)
  192. {
  193. return NULL;
  194. }
  195. lpData += SDL_SwapLE16(lpVOC->data_offset);
  196. dwLen -= SDL_SwapLE16(lpVOC->data_offset);
  197. while (dwLen && *lpData)
  198. {
  199. DWORD len;
  200. if (dwLen >= 4)
  201. {
  202. len = lpData[1] | (lpData[2] << 8) | (lpData[3] << 16);
  203. if (dwLen >= len + 4)
  204. dwLen -= len + 4;
  205. else
  206. return NULL;
  207. }
  208. else
  209. {
  210. return NULL;
  211. }
  212. if (*lpData == 0x01)
  213. {
  214. if (lpData[5] != 0) return NULL; /* Only 8-bit is supported */
  215. lpSpec->format = AUDIO_U8;
  216. lpSpec->channels = 1;
  217. lpSpec->freq = ((1000000 / (256 - lpData[4]) + 99) / 100) * 100; /* Round to next 100Hz */
  218. lpSpec->size = len - 2;
  219. lpSpec->align = 1;
  220. return lpData + 6;
  221. }
  222. else
  223. {
  224. lpData += len + 4;
  225. }
  226. }
  227. return NULL;
  228. }
  229. static int
  230. SOUND_ResampleMix_U8_Mono_Mono(
  231. void *resampler[2],
  232. const void *lpData,
  233. const WAVESPEC *lpSpec,
  234. void *lpBuffer,
  235. int iBufLen,
  236. const void **llpData
  237. )
  238. /*++
  239. Purpose:
  240. Resample 8-bit unsigned mono PCM data into 16-bit signed (native-endian) mono PCM data.
  241. Parameters:
  242. [IN] resampler - array of pointers to the resampler instance.
  243. [IN] lpData - pointer to the buffer of the input PCM data.
  244. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  245. some basic information about the input PCM data.
  246. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  247. [IN] iBufLen - length of the buffer of the output PCM data.
  248. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  249. Return value:
  250. The number of output buffer used, in bytes.
  251. --*/
  252. {
  253. int src_samples = lpSpec->size;
  254. const uint8_t * src = (const uint8_t *)lpData;
  255. short *dst = (short *)lpBuffer;
  256. int channel_len = iBufLen, total_bytes = 0;
  257. while (total_bytes < channel_len && src_samples > 0)
  258. {
  259. int j, to_write = resampler_get_free_count(resampler[0]);
  260. if (to_write > src_samples) to_write = src_samples;
  261. for (j = 0; j < to_write; j++)
  262. resampler_write_sample(resampler[0], (*src++ ^ 0x80) << 8);
  263. src_samples -= to_write;
  264. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  265. {
  266. int sample = (resampler_get_sample(resampler[0]) >> 8) + *dst;
  267. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  268. total_bytes += sizeof(short);
  269. resampler_remove_sample(resampler[0]);
  270. }
  271. }
  272. if (llpData) *llpData = src;
  273. return total_bytes;
  274. }
  275. static int
  276. SOUND_ResampleMix_U8_Mono_Stereo(
  277. void *resampler[2],
  278. const void *lpData,
  279. const WAVESPEC *lpSpec,
  280. void *lpBuffer,
  281. int iBufLen,
  282. const void **llpData
  283. )
  284. /*++
  285. Purpose:
  286. Resample 8-bit unsigned mono PCM data into 16-bit signed (native-endian) stereo PCM data.
  287. Parameters:
  288. [IN] resampler - array of pointers to the resampler instance.
  289. [IN] lpData - pointer to the buffer of the input PCM data.
  290. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  291. some basic information about the input PCM data.
  292. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  293. [IN] iBufLen - length of the buffer of the output PCM data.
  294. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  295. Return value:
  296. The number of output buffer used, in bytes.
  297. --*/
  298. {
  299. int src_samples = lpSpec->size;
  300. const uint8_t * src = (const uint8_t *)lpData;
  301. short *dst = (short *)lpBuffer;
  302. int channel_len = iBufLen >> 1, total_bytes = 0;
  303. while (total_bytes < channel_len && src_samples > 0)
  304. {
  305. int j, to_write = resampler_get_free_count(resampler[0]);
  306. if (to_write > src_samples) to_write = src_samples;
  307. for (j = 0; j < to_write; j++)
  308. resampler_write_sample(resampler[0], (*src++ ^ 0x80) << 8);
  309. src_samples -= to_write;
  310. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  311. {
  312. int sample = (resampler_get_sample(resampler[0]) >> 8) + *dst;
  313. dst[0] = dst[1] = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  314. total_bytes += sizeof(short); dst += 2;
  315. resampler_remove_sample(resampler[0]);
  316. }
  317. }
  318. if (llpData) *llpData = src;
  319. return total_bytes;
  320. }
  321. static int
  322. SOUND_ResampleMix_U8_Stereo_Mono(
  323. void *resampler[2],
  324. const void *lpData,
  325. const WAVESPEC *lpSpec,
  326. void *lpBuffer,
  327. int iBufLen,
  328. const void **llpData
  329. )
  330. /*++
  331. Purpose:
  332. Resample 8-bit unsigned stereo PCM data into 16-bit signed (native-endian) mono PCM data.
  333. Parameters:
  334. [IN] resampler - array of pointers to the resampler instance.
  335. [IN] lpData - pointer to the buffer of the input PCM data.
  336. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  337. some basic information about the input PCM data.
  338. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  339. [IN] iBufLen - length of the buffer of the output PCM data.
  340. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  341. Return value:
  342. The number of output buffer used, in bytes.
  343. --*/
  344. {
  345. int src_samples = lpSpec->size >> 1;
  346. const uint8_t * src = (const uint8_t *)lpData;
  347. short *dst = (short *)lpBuffer;
  348. int channel_len = iBufLen, total_bytes = 0;
  349. while (total_bytes < channel_len && src_samples > 0)
  350. {
  351. int j, to_write = resampler_get_free_count(resampler[0]);
  352. if (to_write > src_samples) to_write = src_samples;
  353. for (j = 0; j < to_write; j++)
  354. {
  355. resampler_write_sample(resampler[0], (*src++ ^ 0x80) << 8);
  356. resampler_write_sample(resampler[1], (*src++ ^ 0x80) << 8);
  357. }
  358. src_samples -= to_write;
  359. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  360. {
  361. int sample = (((resampler_get_sample(resampler[0]) >> 8) + (resampler_get_sample(resampler[1]) >> 8)) >> 1) + *dst;
  362. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  363. total_bytes += sizeof(short);
  364. resampler_remove_sample(resampler[0]);
  365. resampler_remove_sample(resampler[1]);
  366. }
  367. }
  368. if (llpData) *llpData = src;
  369. return total_bytes;
  370. }
  371. static int
  372. SOUND_ResampleMix_U8_Stereo_Stereo(
  373. void *resampler[2],
  374. const void *lpData,
  375. const WAVESPEC *lpSpec,
  376. void *lpBuffer,
  377. int iBufLen,
  378. const void **llpData
  379. )
  380. /*++
  381. Purpose:
  382. Resample 8-bit unsigned stereo PCM data into 16-bit signed (native-endian) stereo PCM data.
  383. Parameters:
  384. [IN] resampler - array of pointers to the resampler instance.
  385. [IN] lpData - pointer to the buffer of the input PCM data.
  386. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  387. some basic information about the input PCM data.
  388. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  389. [IN] iBufLen - length of the buffer of the output PCM data.
  390. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  391. Return value:
  392. The number of output buffer used, in bytes.
  393. --*/
  394. {
  395. int src_samples = lpSpec->size >> 1;
  396. const uint8_t * src = (const uint8_t *)lpData;
  397. short *dst = (short *)lpBuffer;
  398. int channel_len = iBufLen >> 1, total_bytes = 0;
  399. while (total_bytes < channel_len && src_samples > 0)
  400. {
  401. int j, to_write = resampler_get_free_count(resampler[0]);
  402. if (to_write > src_samples) to_write = src_samples;
  403. for (j = 0; j < to_write; j++)
  404. {
  405. resampler_write_sample(resampler[0], (*src++ ^ 0x80) << 8);
  406. resampler_write_sample(resampler[1], (*src++ ^ 0x80) << 8);
  407. }
  408. src_samples -= to_write;
  409. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  410. {
  411. int sample;
  412. sample = (resampler_get_sample(resampler[0]) >> 8) + *dst;
  413. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  414. sample = (resampler_get_sample(resampler[1]) >> 8) + *dst;
  415. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  416. total_bytes += sizeof(short);
  417. resampler_remove_sample(resampler[0]);
  418. resampler_remove_sample(resampler[1]);
  419. }
  420. }
  421. if (llpData) *llpData = src;
  422. return total_bytes;
  423. }
  424. static int
  425. SOUND_ResampleMix_S16_Mono_Mono(
  426. void *resampler[2],
  427. const void *lpData,
  428. const WAVESPEC *lpSpec,
  429. void *lpBuffer,
  430. int iBufLen,
  431. const void **llpData
  432. )
  433. /*++
  434. Purpose:
  435. Resample 16-bit signed (little-endian) mono PCM data into 16-bit signed (native-endian) mono PCM data.
  436. Parameters:
  437. [IN] resampler - array of pointers to the resampler instance.
  438. [IN] lpData - pointer to the buffer of the input PCM data.
  439. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  440. some basic information about the input PCM data.
  441. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  442. [IN] iBufLen - length of the buffer of the output PCM data.
  443. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  444. Return value:
  445. The number of output buffer used, in bytes.
  446. --*/
  447. {
  448. int src_samples = lpSpec->size >> 1;
  449. const short * src = (const short *)lpData;
  450. short *dst = (short *)lpBuffer;
  451. int channel_len = iBufLen, total_bytes = 0;
  452. while (total_bytes < channel_len && src_samples > 0)
  453. {
  454. int j, to_write = resampler_get_free_count(resampler[0]);
  455. if (to_write > src_samples) to_write = src_samples;
  456. for (j = 0; j < to_write; j++)
  457. resampler_write_sample(resampler[0], SDL_SwapLE16(*src++));
  458. src_samples -= to_write;
  459. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  460. {
  461. int sample = (resampler_get_sample(resampler[0]) >> 8) + *dst;
  462. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  463. total_bytes += sizeof(short);
  464. resampler_remove_sample(resampler[0]);
  465. }
  466. }
  467. if (llpData) *llpData = src;
  468. return total_bytes;
  469. }
  470. static int
  471. SOUND_ResampleMix_S16_Mono_Stereo(
  472. void *resampler[2],
  473. const void *lpData,
  474. const WAVESPEC *lpSpec,
  475. void *lpBuffer,
  476. int iBufLen,
  477. const void **llpData
  478. )
  479. /*++
  480. Purpose:
  481. Resample 16-bit signed (little-endian) mono PCM data into 16-bit signed (native-endian) stereo PCM data.
  482. Parameters:
  483. [IN] resampler - array of pointers to the resampler instance.
  484. [IN] lpData - pointer to the buffer of the input PCM data.
  485. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  486. some basic information about the input PCM data.
  487. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  488. [IN] iBufLen - length of the buffer of the output PCM data.
  489. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  490. Return value:
  491. The number of output buffer used, in bytes.
  492. --*/
  493. {
  494. int src_samples = lpSpec->size >> 1;
  495. const short * src = (const short *)lpData;
  496. short *dst = (short *)lpBuffer;
  497. int channel_len = iBufLen >> 1, total_bytes = 0;
  498. while (total_bytes < channel_len && src_samples > 0)
  499. {
  500. int j, to_write = resampler_get_free_count(resampler[0]);
  501. if (to_write > src_samples) to_write = src_samples;
  502. for (j = 0; j < to_write; j++)
  503. resampler_write_sample(resampler[0], SDL_SwapLE16(*src++));
  504. src_samples -= to_write;
  505. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  506. {
  507. int sample = (resampler_get_sample(resampler[0]) >> 8) + *dst;
  508. dst[0] = dst[1] = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  509. total_bytes += sizeof(short); dst += 2;
  510. resampler_remove_sample(resampler[0]);
  511. }
  512. }
  513. if (llpData) *llpData = src;
  514. return total_bytes;
  515. }
  516. static int
  517. SOUND_ResampleMix_S16_Stereo_Mono(
  518. void *resampler[2],
  519. const void *lpData,
  520. const WAVESPEC *lpSpec,
  521. void *lpBuffer,
  522. int iBufLen,
  523. const void **llpData
  524. )
  525. /*++
  526. Purpose:
  527. Resample 16-bit signed (little-endian) stereo PCM data into 16-bit signed (native-endian) mono PCM data.
  528. Parameters:
  529. [IN] resampler - array of pointers to the resampler instance.
  530. [IN] lpData - pointer to the buffer of the input PCM data.
  531. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  532. some basic information about the input PCM data.
  533. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  534. [IN] iBufLen - length of the buffer of the output PCM data.
  535. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  536. Return value:
  537. The number of output buffer used, in bytes.
  538. --*/
  539. {
  540. int src_samples = lpSpec->size >> 2;
  541. const short * src = (const short *)lpData;
  542. short *dst = (short *)lpBuffer;
  543. int channel_len = iBufLen, total_bytes = 0;
  544. while (total_bytes < channel_len && src_samples > 0)
  545. {
  546. int j, to_write = resampler_get_free_count(resampler[0]);
  547. if (to_write > src_samples) to_write = src_samples;
  548. for (j = 0; j < to_write; j++)
  549. {
  550. resampler_write_sample(resampler[0], SDL_SwapLE16(*src++));
  551. resampler_write_sample(resampler[1], SDL_SwapLE16(*src++));
  552. }
  553. src_samples -= to_write;
  554. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  555. {
  556. int sample = (((resampler_get_sample(resampler[0]) >> 8) + (resampler_get_sample(resampler[1]) >> 8)) >> 1) + *dst;
  557. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  558. total_bytes += sizeof(short);
  559. resampler_remove_sample(resampler[0]);
  560. resampler_remove_sample(resampler[1]);
  561. }
  562. }
  563. if (llpData) *llpData = src;
  564. return total_bytes;
  565. }
  566. static int
  567. SOUND_ResampleMix_S16_Stereo_Stereo(
  568. void *resampler[2],
  569. const void *lpData,
  570. const WAVESPEC *lpSpec,
  571. void *lpBuffer,
  572. int iBufLen,
  573. const void **llpData
  574. )
  575. /*++
  576. Purpose:
  577. Resample 16-bit signed (little-endian) stereo PCM data into 16-bit signed (native-endian) stereo PCM data.
  578. Parameters:
  579. [IN] resampler - array of pointers to the resampler instance.
  580. [IN] lpData - pointer to the buffer of the input PCM data.
  581. [IN] lpSpec - pointer to the WAVESPEC structure, which contains
  582. some basic information about the input PCM data.
  583. [IN] lpBuffer - pointer of the buffer of the output PCM data.
  584. [IN] iBufLen - length of the buffer of the output PCM data.
  585. [OUT] llpData - pointer to receive the pointer of remaining input PCM data.
  586. Return value:
  587. The number of output buffer used, in bytes.
  588. --*/
  589. {
  590. int src_samples = lpSpec->size >> 2;
  591. const short * src = (const short *)lpData;
  592. short *dst = (short *)lpBuffer;
  593. int channel_len = iBufLen >> 1, total_bytes = 0;
  594. while (total_bytes < channel_len && src_samples > 0)
  595. {
  596. int j, to_write = resampler_get_free_count(resampler[0]);
  597. if (to_write > src_samples) to_write = src_samples;
  598. for (j = 0; j < to_write; j++)
  599. {
  600. resampler_write_sample(resampler[0], SDL_SwapLE16(*src++));
  601. resampler_write_sample(resampler[1], SDL_SwapLE16(*src++));
  602. }
  603. src_samples -= to_write;
  604. while (total_bytes < channel_len && resampler_get_sample_count(resampler[0]) > 0)
  605. {
  606. int sample;
  607. sample = (resampler_get_sample(resampler[0]) >> 8) + *dst;
  608. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  609. sample = (resampler_get_sample(resampler[1]) >> 8) + *dst;
  610. *dst++ = (sample <= 32767) ? ((sample >= -32768) ? sample : -32768) : 32767;
  611. total_bytes += sizeof(short);
  612. resampler_remove_sample(resampler[0]);
  613. resampler_remove_sample(resampler[1]);
  614. }
  615. }
  616. if (llpData) *llpData = src;
  617. return total_bytes;
  618. }
  619. static BOOL
  620. SOUND_Play(
  621. VOID *object,
  622. INT iSoundNum,
  623. BOOL fLoop,
  624. FLOAT flFadeTime
  625. )
  626. /*++
  627. Purpose:
  628. Play a sound in voc.mkf/sounds.mkf file.
  629. Parameters:
  630. [IN] object - Pointer to the SOUNDPLAYER instance.
  631. [IN] iSoundNum - number of the sound; the absolute value is used.
  632. [IN] fLoop - Not used, should be zero.
  633. [IN] flFadeTime - Not used, should be zero.
  634. Return value:
  635. None.
  636. --*/
  637. {
  638. LPSOUNDPLAYER player = (LPSOUNDPLAYER)object;
  639. const SDL_AudioSpec *devspec = AUDIO_GetDeviceSpec();
  640. WAVESPEC wavespec;
  641. ResampleMixer mixer;
  642. WAVEDATA *cursnd;
  643. void *buf;
  644. const void *snddata;
  645. int len, i;
  646. //
  647. // Check for NULL pointer.
  648. //
  649. if (player == NULL)
  650. {
  651. return FALSE;
  652. }
  653. //
  654. // Get the length of the sound file.
  655. //
  656. len = PAL_MKFGetChunkSize(iSoundNum, player->mkf);
  657. if (len <= 0)
  658. {
  659. return FALSE;
  660. }
  661. buf = malloc(len);
  662. if (buf == NULL)
  663. {
  664. return FALSE;
  665. }
  666. //
  667. // Read the sound file from the MKF archive.
  668. //
  669. PAL_MKFReadChunk(buf, len, iSoundNum, player->mkf);
  670. snddata = player->LoadSound(buf, len, &wavespec);
  671. if (snddata == NULL)
  672. {
  673. free(buf);
  674. return FALSE;
  675. }
  676. if (wavespec.channels == 1 && devspec->channels == 1)
  677. mixer = (wavespec.format == AUDIO_S16) ? SOUND_ResampleMix_S16_Mono_Mono : SOUND_ResampleMix_U8_Mono_Mono;
  678. else if (wavespec.channels == 1 && devspec->channels == 2)
  679. mixer = (wavespec.format == AUDIO_S16) ? SOUND_ResampleMix_S16_Mono_Stereo : SOUND_ResampleMix_U8_Mono_Stereo;
  680. else if (wavespec.channels == 2 && devspec->channels == 1)
  681. mixer = (wavespec.format == AUDIO_S16) ? SOUND_ResampleMix_S16_Stereo_Mono : SOUND_ResampleMix_U8_Stereo_Mono;
  682. else if (wavespec.channels == 2 && devspec->channels == 2)
  683. mixer = (wavespec.format == AUDIO_S16) ? SOUND_ResampleMix_S16_Stereo_Stereo : SOUND_ResampleMix_U8_Stereo_Stereo;
  684. else
  685. {
  686. free(buf);
  687. return FALSE;
  688. }
  689. SDL_mutexP(player->mutex);
  690. cursnd = &player->soundlist;
  691. while (cursnd->next && cursnd->base)
  692. cursnd = cursnd->next;
  693. if (cursnd->base)
  694. {
  695. WAVEDATA *obj = (WAVEDATA *)malloc(sizeof(WAVEDATA));
  696. memset(obj, 0, sizeof(WAVEDATA));
  697. cursnd->next = obj;
  698. cursnd = cursnd->next;
  699. }
  700. for (i = 0; i < wavespec.channels; i++)
  701. {
  702. if (!cursnd->resampler[i])
  703. cursnd->resampler[i] = resampler_create();
  704. else
  705. resampler_clear(cursnd->resampler[i]);
  706. resampler_set_quality(cursnd->resampler[i], AUDIO_IsIntegerConversion(wavespec.freq) ? RESAMPLER_QUALITY_MIN : gConfig.iResampleQuality);
  707. resampler_set_rate(cursnd->resampler[i], (double)wavespec.freq / (double)devspec->freq);
  708. }
  709. cursnd->base = buf;
  710. cursnd->current = snddata;
  711. cursnd->end = (const uint8_t *)snddata + wavespec.size;
  712. cursnd->spec = wavespec;
  713. cursnd->ResampleMix = mixer;
  714. player->cursounds++;
  715. SDL_mutexV(player->mutex);
  716. return TRUE;
  717. }
  718. VOID
  719. SOUND_Shutdown(
  720. VOID *object
  721. )
  722. /*++
  723. Purpose:
  724. Shutdown the sound subsystem.
  725. Parameters:
  726. None.
  727. Return value:
  728. None.
  729. --*/
  730. {
  731. LPSOUNDPLAYER player = (LPSOUNDPLAYER)object;
  732. if (player)
  733. {
  734. WAVEDATA *cursnd = &player->soundlist;
  735. do
  736. {
  737. if (cursnd->resampler[0]) resampler_delete(cursnd->resampler[0]);
  738. if (cursnd->resampler[1]) resampler_delete(cursnd->resampler[1]);
  739. if (cursnd->base) free((void *)cursnd->base);
  740. } while (cursnd = cursnd->next);
  741. cursnd = player->soundlist.next;
  742. while (cursnd)
  743. {
  744. WAVEDATA *old = cursnd;
  745. cursnd = cursnd->next;
  746. free(old);
  747. }
  748. if (player->mkf) fclose(player->mkf);
  749. }
  750. }
  751. static VOID
  752. SOUND_FillBuffer(
  753. VOID *object,
  754. LPBYTE stream,
  755. INT len
  756. )
  757. /*++
  758. Purpose:
  759. Fill the background music into the sound buffer. Called by the SDL sound
  760. callback function only (audio.c: AUDIO_FillBuffer).
  761. Parameters:
  762. [OUT] stream - pointer to the stream buffer.
  763. [IN] len - Length of the buffer.
  764. Return value:
  765. None.
  766. --*/
  767. {
  768. LPSOUNDPLAYER player = (LPSOUNDPLAYER)object;
  769. if (player)
  770. {
  771. WAVEDATA *cursnd = &player->soundlist;
  772. int sounds = 0;
  773. do
  774. {
  775. if (cursnd->base)
  776. {
  777. cursnd->ResampleMix(cursnd->resampler, cursnd->current, &cursnd->spec, stream, len, &cursnd->current);
  778. cursnd->spec.size = (const uint8_t *)cursnd->end - (const uint8_t *)cursnd->current;
  779. if (cursnd->spec.size < cursnd->spec.align)
  780. {
  781. free((void *)cursnd->base);
  782. cursnd->base = cursnd->current = cursnd->end = NULL;
  783. player->cursounds--;
  784. }
  785. else
  786. sounds++;
  787. }
  788. } while ((cursnd = cursnd->next) && sounds < player->cursounds);
  789. }
  790. }
  791. LPAUDIOPLAYER
  792. SOUND_Init(
  793. SDL_mutex *mutex
  794. )
  795. /*++
  796. Purpose:
  797. Initialize the sound subsystem.
  798. Parameters:
  799. None.
  800. Return value:
  801. None.
  802. --*/
  803. {
  804. char *mkfs[2];
  805. SoundLoader func[2];
  806. int i;
  807. if (gConfig.fIsWIN95)
  808. {
  809. mkfs[0] = "sounds.mkf"; func[0] = SOUND_LoadWAVEData;
  810. mkfs[1] = "voc.mkf"; func[1] = SOUND_LoadVOCData;
  811. }
  812. else
  813. {
  814. mkfs[0] = "voc.mkf"; func[0] = SOUND_LoadVOCData;
  815. mkfs[1] = "sounds.mkf"; func[1] = SOUND_LoadWAVEData;
  816. }
  817. for (i = 0; i < 2; i++)
  818. {
  819. FILE *mkf = UTIL_OpenFile(mkfs[i]);
  820. if (mkf)
  821. {
  822. LPSOUNDPLAYER player = (LPSOUNDPLAYER)malloc(sizeof(SOUNDPLAYER));
  823. memset(&player->soundlist, 0, sizeof(WAVEDATA));
  824. player->Play = SOUND_Play;
  825. player->FillBuffer = SOUND_FillBuffer;
  826. player->Shutdown = SOUND_Shutdown;
  827. player->mutex = mutex;
  828. player->LoadSound = func[i];
  829. player->mkf = mkf;
  830. player->soundlist.resampler[0] = resampler_create();
  831. player->soundlist.resampler[1] = resampler_create();
  832. player->cursounds = 0;
  833. return (LPAUDIOPLAYER)player;
  834. }
  835. }
  836. return NULL;
  837. }
  838. #ifdef PSP
  839. void
  840. SOUND_Reload(
  841. void
  842. )
  843. {
  844. fclose(gSndPlayer.mkf);
  845. SOUND_LoadMKF();
  846. }
  847. #endif