sound.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /*
  2. * PicoDrive
  3. * (c) Copyright Dave, 2004
  4. * (C) notaz, 2006-2009
  5. *
  6. * This work is licensed under the terms of MAME license.
  7. * See COPYING file in the top-level directory.
  8. */
  9. #include <string.h>
  10. #include "ym2612.h"
  11. #include "sn76496.h"
  12. #include "../pico_int.h"
  13. #include "../cd/cue.h"
  14. #include "mix.h"
  15. #include "emu2413/emu2413.h"
  16. void (*PsndMix_32_to_16l)(short *dest, int *src, int count) = mix_32_to_16l_stereo;
  17. // master int buffer to mix to
  18. static int PsndBuffer[2*(44100+100)/50];
  19. // cdda output buffer
  20. short cdda_out_buffer[2*1152];
  21. // sn76496
  22. extern int *sn76496_regs;
  23. // Low pass filter 'previous' samples
  24. static int32_t lpf_lp;
  25. static int32_t lpf_rp;
  26. static void low_pass_filter_stereo(int *buf32, int length)
  27. {
  28. int samples = length;
  29. int *out32 = buf32;
  30. // Restore previous samples
  31. int32_t lpf_l = lpf_lp;
  32. int32_t lpf_r = lpf_rp;
  33. // Single-pole low-pass filter (6 dB/octave)
  34. int32_t factor_a = PicoIn.sndFilterRange;
  35. int32_t factor_b = 0x10000 - factor_a;
  36. do
  37. {
  38. // Apply low-pass filter
  39. lpf_l = (lpf_l * factor_a) + (out32[0] * factor_b);
  40. lpf_r = (lpf_r * factor_a) + (out32[1] * factor_b);
  41. // 16.16 fixed point
  42. lpf_l >>= 16;
  43. lpf_r >>= 16;
  44. // Update sound buffer
  45. *out32++ = lpf_l;
  46. *out32++ = lpf_r;
  47. }
  48. while (--samples);
  49. // Save last samples for next frame
  50. lpf_lp = lpf_l;
  51. lpf_rp = lpf_r;
  52. }
  53. static void low_pass_filter_mono(int *buf32, int length)
  54. {
  55. int samples = length;
  56. int *out32 = buf32;
  57. // Restore previous sample
  58. int32_t lpf_l = lpf_lp;
  59. // Single-pole low-pass filter (6 dB/octave)
  60. int32_t factor_a = PicoIn.sndFilterRange;
  61. int32_t factor_b = 0x10000 - factor_a;
  62. do
  63. {
  64. // Apply low-pass filter
  65. lpf_l = (lpf_l * factor_a) + (out32[0] * factor_b);
  66. // 16.16 fixed point
  67. lpf_l >>= 16;
  68. // Update sound buffer
  69. *out32++ = lpf_l;
  70. }
  71. while (--samples);
  72. // Save last sample for next frame
  73. lpf_lp = lpf_l;
  74. }
  75. void (*low_pass_filter)(int *buf32, int length) = low_pass_filter_stereo;
  76. // ym2413
  77. #define YM2413_CLK 3579545
  78. OPLL old_opll;
  79. static OPLL *opll = NULL;
  80. unsigned YM2413_reg;
  81. PICO_INTERNAL void PsndInit(void)
  82. {
  83. opll = OPLL_new(YM2413_CLK, PicoIn.sndRate);
  84. OPLL_setChipType(opll,0);
  85. OPLL_reset(opll);
  86. }
  87. PICO_INTERNAL void PsndExit(void)
  88. {
  89. OPLL_delete(opll);
  90. opll = NULL;
  91. }
  92. PICO_INTERNAL void PsndReset(void)
  93. {
  94. // PsndRerate calls YM2612Init, which also resets
  95. PsndRerate(0);
  96. timers_reset();
  97. // Reset low pass filter
  98. lpf_lp = 0;
  99. lpf_rp = 0;
  100. mix_reset();
  101. }
  102. // to be called after changing sound rate or chips
  103. void PsndRerate(int preserve_state)
  104. {
  105. void *state = NULL;
  106. int target_fps = Pico.m.pal ? 50 : 60;
  107. int target_lines = Pico.m.pal ? 313 : 262;
  108. if (preserve_state) {
  109. state = malloc(0x204);
  110. if (state == NULL) return;
  111. ym2612_pack_state();
  112. memcpy(state, YM2612GetRegs(), 0x204);
  113. }
  114. YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PicoIn.sndRate, !(PicoIn.opt&POPT_DIS_FM_SSGEG));
  115. if (preserve_state) {
  116. // feed it back it's own registers, just like after loading state
  117. memcpy(YM2612GetRegs(), state, 0x204);
  118. ym2612_unpack_state();
  119. }
  120. if (preserve_state) memcpy(state, sn76496_regs, 28*4); // remember old state
  121. SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PicoIn.sndRate);
  122. if (preserve_state) memcpy(sn76496_regs, state, 28*4); // restore old state
  123. if(opll != NULL){
  124. if (preserve_state) memcpy(&old_opll, opll, sizeof(OPLL)); // remember old state
  125. OPLL_setRate(opll, PicoIn.sndRate);
  126. OPLL_reset(opll);
  127. }
  128. if (state)
  129. free(state);
  130. // calculate Pico.snd.len
  131. Pico.snd.len = PicoIn.sndRate / target_fps;
  132. Pico.snd.len_e_add = ((PicoIn.sndRate - Pico.snd.len * target_fps) << 16) / target_fps;
  133. Pico.snd.len_e_cnt = 0; // Q16
  134. // samples per line (Q16)
  135. Pico.snd.smpl_mult = 65536LL * PicoIn.sndRate / (target_fps*target_lines);
  136. // samples per z80 clock (Q20)
  137. Pico.snd.clkl_mult = 16 * Pico.snd.smpl_mult * 15/7 / 488;
  138. // clear all buffers
  139. memset32(PsndBuffer, 0, sizeof(PsndBuffer)/4);
  140. memset(cdda_out_buffer, 0, sizeof(cdda_out_buffer));
  141. if (PicoIn.sndOut)
  142. PsndClear();
  143. // set mixer
  144. PsndMix_32_to_16l = (PicoIn.opt & POPT_EN_STEREO) ? mix_32_to_16l_stereo : mix_32_to_16_mono;
  145. // set low pass filter
  146. low_pass_filter = (PicoIn.opt & POPT_EN_STEREO) ? low_pass_filter_stereo : low_pass_filter_mono;
  147. if (PicoIn.AHW & PAHW_PICO)
  148. PicoReratePico();
  149. }
  150. PICO_INTERNAL void PsndStartFrame(void)
  151. {
  152. // compensate for float part of Pico.snd.len
  153. Pico.snd.len_use = Pico.snd.len;
  154. Pico.snd.len_e_cnt += Pico.snd.len_e_add;
  155. if (Pico.snd.len_e_cnt >= 0x10000) {
  156. Pico.snd.len_e_cnt -= 0x10000;
  157. Pico.snd.len_use++;
  158. }
  159. }
  160. PICO_INTERNAL void PsndDoDAC(int cyc_to)
  161. {
  162. int pos, len;
  163. int dout = ym2612.dacout;
  164. // number of samples to fill in buffer (Q20)
  165. len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.dac_pos;
  166. // update position and calculate buffer offset and length
  167. pos = (Pico.snd.dac_pos+0x80000) >> 20;
  168. Pico.snd.dac_pos += len;
  169. len = ((Pico.snd.dac_pos+0x80000) >> 20) - pos;
  170. // avoid loss of the 1st sample of a new block (Q rounding issues)
  171. if (pos+len == 0)
  172. len = 1, Pico.snd.dac_pos += 0x80000;
  173. if (len <= 0)
  174. return;
  175. if (!PicoIn.sndOut)
  176. return;
  177. // fill buffer, applying a rather weak order 1 bessel IIR on the way
  178. // y[n] = (x[n] + x[n-1])*(1/2) (3dB cutoff at 11025 Hz, no gain)
  179. // 1 sample delay for correct IIR filtering over audio frame boundaries
  180. if (PicoIn.opt & POPT_EN_STEREO) {
  181. short *d = PicoIn.sndOut + pos*2;
  182. // left channel only, mixed ro right channel in mixing phase
  183. *d++ += Pico.snd.dac_val2; d++;
  184. while (--len) *d++ += Pico.snd.dac_val, d++;
  185. } else {
  186. short *d = PicoIn.sndOut + pos;
  187. *d++ += Pico.snd.dac_val2;
  188. while (--len) *d++ += Pico.snd.dac_val;
  189. }
  190. Pico.snd.dac_val2 = (Pico.snd.dac_val + dout) >> 1;
  191. Pico.snd.dac_val = dout;
  192. }
  193. PICO_INTERNAL void PsndDoPSG(int line_to)
  194. {
  195. int pos, len;
  196. int stereo = 0;
  197. // Q16, number of samples since last call
  198. len = ((line_to+1) * Pico.snd.smpl_mult) - Pico.snd.psg_pos;
  199. if (len <= 0)
  200. return;
  201. // update position and calculate buffer offset and length
  202. pos = (Pico.snd.psg_pos+0x8000) >> 16;
  203. Pico.snd.psg_pos += len;
  204. len = ((Pico.snd.psg_pos+0x8000) >> 16) - pos;
  205. if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))
  206. return;
  207. if (PicoIn.opt & POPT_EN_STEREO) {
  208. stereo = 1;
  209. pos <<= 1;
  210. }
  211. SN76496Update(PicoIn.sndOut + pos, len, stereo);
  212. }
  213. #if 0
  214. PICO_INTERNAL void PsndDoYM2413(int line_to)
  215. {
  216. int pos, len;
  217. int stereo = 0;
  218. short *buf;
  219. // Q16, number of samples since last call
  220. len = ((line_to+1) * Pico.snd.smpl_mult) - Pico.snd.ym2413_pos;
  221. if (len <= 0)
  222. return;
  223. // update position and calculate buffer offset and length
  224. pos = (Pico.snd.ym2413_pos+0x8000) >> 16;
  225. Pico.snd.ym2413_pos += len;
  226. len = ((Pico.snd.ym2413_pos+0x8000) >> 16) - pos;
  227. if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_YM2413))
  228. return;
  229. if (PicoIn.opt & POPT_EN_STEREO) {
  230. stereo = 1;
  231. pos <<= 1;
  232. }
  233. buf = PicoIn.sndOut + pos;
  234. while (len-- > 0) {
  235. int16_t getdata = OPLL_calc(opll) * 3;
  236. *buf++ += getdata;
  237. buf += stereo; // only left for stereo, to be mixed to right later
  238. }
  239. }
  240. #endif
  241. void YM2413_regWrite(unsigned data){
  242. OPLL_writeIO(opll,0,data);
  243. }
  244. void YM2413_dataWrite(unsigned data){
  245. OPLL_writeIO(opll,1,data);
  246. }
  247. PICO_INTERNAL void PsndDoFM(int cyc_to)
  248. {
  249. int pos, len;
  250. int stereo = 0;
  251. // Q16, number of samples since last call
  252. len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.fm_pos;
  253. // don't do this too often (about once every canline)
  254. if (len >> 16 <= PicoIn.sndRate >> 10)
  255. return;
  256. // update position and calculate buffer offset and length
  257. pos = (Pico.snd.fm_pos+0x80000) >> 20;
  258. Pico.snd.fm_pos += len;
  259. len = ((Pico.snd.fm_pos+0x80000) >> 20) - pos;
  260. // fill buffer
  261. if (PicoIn.opt & POPT_EN_STEREO) {
  262. stereo = 1;
  263. pos <<= 1;
  264. }
  265. if (PicoIn.opt & POPT_EN_FM)
  266. YM2612UpdateOne(PsndBuffer + pos, len, stereo, 1);
  267. }
  268. // cdda
  269. static void cdda_raw_update(int *buffer, int length)
  270. {
  271. int ret, cdda_bytes, mult = 1;
  272. cdda_bytes = length*4;
  273. if (PicoIn.sndRate <= 22050 + 100) mult = 2;
  274. if (PicoIn.sndRate < 22050 - 100) mult = 4;
  275. cdda_bytes *= mult;
  276. ret = pm_read(cdda_out_buffer, cdda_bytes, Pico_mcd->cdda_stream);
  277. if (ret < cdda_bytes) {
  278. memset((char *)cdda_out_buffer + ret, 0, cdda_bytes - ret);
  279. Pico_mcd->cdda_stream = NULL;
  280. return;
  281. }
  282. // now mix
  283. switch (mult) {
  284. case 1: mix_16h_to_32(buffer, cdda_out_buffer, length*2); break;
  285. case 2: mix_16h_to_32_s1(buffer, cdda_out_buffer, length*2); break;
  286. case 4: mix_16h_to_32_s2(buffer, cdda_out_buffer, length*2); break;
  287. }
  288. }
  289. void cdda_start_play(int lba_base, int lba_offset, int lb_len)
  290. {
  291. if (Pico_mcd->cdda_type == CT_MP3)
  292. {
  293. int pos1024 = 0;
  294. if (lba_offset)
  295. pos1024 = lba_offset * 1024 / lb_len;
  296. mp3_start_play(Pico_mcd->cdda_stream, pos1024);
  297. return;
  298. }
  299. pm_seek(Pico_mcd->cdda_stream, (lba_base + lba_offset) * 2352, SEEK_SET);
  300. if (Pico_mcd->cdda_type == CT_WAV)
  301. {
  302. // skip headers, assume it's 44kHz stereo uncompressed
  303. pm_seek(Pico_mcd->cdda_stream, 44, SEEK_CUR);
  304. }
  305. }
  306. PICO_INTERNAL void PsndClear(void)
  307. {
  308. int len = Pico.snd.len;
  309. if (Pico.snd.len_e_add) len++;
  310. if (PicoIn.opt & POPT_EN_STEREO)
  311. memset32((int *) PicoIn.sndOut, 0, len); // assume PicoIn.sndOut to be aligned
  312. else {
  313. short *out = PicoIn.sndOut;
  314. if ((uintptr_t)out & 2) { *out++ = 0; len--; }
  315. memset32((int *) out, 0, len/2);
  316. if (len & 1) out[len-1] = 0;
  317. }
  318. if (!(PicoIn.opt & POPT_EN_FM))
  319. memset32(PsndBuffer, 0, PicoIn.opt & POPT_EN_STEREO ? len*2 : len);
  320. // drop pos remainder to avoid rounding errors (not entirely correct though)
  321. Pico.snd.dac_pos = Pico.snd.fm_pos = Pico.snd.psg_pos = Pico.snd.ym2413_pos = 0;
  322. }
  323. static int PsndRender(int offset, int length)
  324. {
  325. int *buf32;
  326. int stereo = (PicoIn.opt & 8) >> 3;
  327. int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);
  328. int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);
  329. int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);
  330. buf32 = PsndBuffer+(offset<<stereo);
  331. pprof_start(sound);
  332. if (PicoIn.AHW & PAHW_PICO) {
  333. PicoPicoPCMUpdate(PicoIn.sndOut+(offset<<stereo), length-offset, stereo);
  334. return length;
  335. }
  336. // Fill up DAC output in case of missing samples (Q16 rounding errors)
  337. if (length-daclen > 0) {
  338. short *dacbuf = PicoIn.sndOut + (daclen << stereo);
  339. Pico.snd.dac_pos += (length-daclen) << 20;
  340. *dacbuf++ += Pico.snd.dac_val2;
  341. if (stereo) dacbuf++;
  342. for (daclen++; length-daclen > 0; daclen++) {
  343. *dacbuf++ += Pico.snd.dac_val;
  344. if (stereo) dacbuf++;
  345. }
  346. Pico.snd.dac_val2 = Pico.snd.dac_val;
  347. }
  348. // Add in parts of the PSG output not yet done
  349. if (length-psglen > 0) {
  350. short *psgbuf = PicoIn.sndOut + (psglen << stereo);
  351. Pico.snd.psg_pos += (length-psglen) << 16;
  352. if (PicoIn.opt & POPT_EN_PSG)
  353. SN76496Update(psgbuf, length-psglen, stereo);
  354. }
  355. // Add in parts of the FM buffer not yet done
  356. if (length-fmlen > 0) {
  357. int *fmbuf = buf32 + ((fmlen-offset) << stereo);
  358. Pico.snd.fm_pos += (length-fmlen) << 20;
  359. if (PicoIn.opt & POPT_EN_FM)
  360. YM2612UpdateOne(fmbuf, length-fmlen, stereo, 1);
  361. }
  362. // CD: PCM sound
  363. if (PicoIn.AHW & PAHW_MCD) {
  364. pcd_pcm_update(buf32, length-offset, stereo);
  365. }
  366. // CD: CDDA audio
  367. // CD mode, cdda enabled, not data track, CDC is reading
  368. if ((PicoIn.AHW & PAHW_MCD) && (PicoIn.opt & POPT_EN_MCD_CDDA)
  369. && Pico_mcd->cdda_stream != NULL
  370. && !(Pico_mcd->s68k_regs[0x36] & 1))
  371. {
  372. // note: only 44, 22 and 11 kHz supported, with forced stereo
  373. if (Pico_mcd->cdda_type == CT_MP3)
  374. mp3_update(buf32, length-offset, stereo);
  375. else
  376. cdda_raw_update(buf32, length-offset);
  377. }
  378. if ((PicoIn.AHW & PAHW_32X) && (PicoIn.opt & POPT_EN_PWM))
  379. p32x_pwm_update(buf32, length-offset, stereo);
  380. // Apply low pass filter, if required
  381. if (PicoIn.sndFilter == 1) {
  382. low_pass_filter(buf32, length);
  383. }
  384. // convert + limit to normal 16bit output
  385. PsndMix_32_to_16l(PicoIn.sndOut+(offset<<stereo), buf32, length-offset);
  386. pprof_end(sound);
  387. return length;
  388. }
  389. PICO_INTERNAL void PsndGetSamples(int y)
  390. {
  391. static int curr_pos = 0;
  392. curr_pos = PsndRender(0, Pico.snd.len_use);
  393. if (PicoIn.writeSound)
  394. PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
  395. // clear sound buffer
  396. PsndClear();
  397. }
  398. static int PsndRenderMS(int offset, int length)
  399. {
  400. int stereo = (PicoIn.opt & 8) >> 3;
  401. int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);
  402. int ym2413len = ((Pico.snd.ym2413_pos+0x8000) >> 16);
  403. pprof_start(sound);
  404. // Add in parts of the PSG output not yet done
  405. if (length-psglen > 0) {
  406. short *psgbuf = PicoIn.sndOut + (psglen << stereo);
  407. Pico.snd.psg_pos += (length-psglen) << 16;
  408. if (PicoIn.opt & POPT_EN_PSG)
  409. SN76496Update(psgbuf, length-psglen, stereo);
  410. }
  411. if (length-ym2413len > 0) {
  412. short *ym2413buf = PicoIn.sndOut + (ym2413len << stereo);
  413. Pico.snd.ym2413_pos += (length-ym2413len) << 16;
  414. int len = (length-ym2413len);
  415. if (PicoIn.opt & POPT_EN_YM2413){
  416. while (len-- > 0) {
  417. int16_t getdata = OPLL_calc(opll) * 3;
  418. *ym2413buf += getdata;
  419. ym2413buf += 1<<stereo;
  420. }
  421. }
  422. }
  423. // upmix to "stereo" if needed
  424. if (PicoIn.opt & POPT_EN_STEREO) {
  425. int i;
  426. short *p;
  427. for (i = length, p = (short *)PicoIn.sndOut; i > 0; i--, p+=2)
  428. *(p + 1) = *p;
  429. }
  430. pprof_end(sound);
  431. return length;
  432. }
  433. PICO_INTERNAL void PsndGetSamplesMS(int y)
  434. {
  435. static int curr_pos = 0;
  436. curr_pos = PsndRenderMS(0, Pico.snd.len_use);
  437. if (PicoIn.writeSound != NULL)
  438. PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
  439. PsndClear();
  440. }
  441. // vim:shiftwidth=2:ts=2:expandtab