sound.c 26 KB

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