sound.c 27 KB

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