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