sound.c 26 KB

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