sound.c 26 KB

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