sound.c 12 KB

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