sound.c 27 KB

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