// master int buffer to mix to\r
static int PsndBuffer[2*(44100+100)/50];\r
\r
-// dac, psg\r
-static unsigned short dac_info[312+4]; // pos in sample buffer\r
-\r
// cdda output buffer\r
short cdda_out_buffer[2*1152];\r
\r
extern int *sn76496_regs;\r
\r
\r
-static void dac_recalculate(void)\r
-{\r
- int lines = Pico.m.pal ? 313 : 262;\r
- int i, pos;\r
-\r
- pos = 0; // Q16\r
-\r
- for(i = 0; i <= lines; i++)\r
- {\r
- dac_info[i] = ((pos+0x8000) >> 16); // round to nearest\r
- pos += Pico.snd.fm_mult;\r
- }\r
- for (i = lines+1; i < sizeof(dac_info) / sizeof(dac_info[0]); i++)\r
- dac_info[i] = dac_info[i-1];\r
-}\r
-\r
-\r
PICO_INTERNAL void PsndReset(void)\r
{\r
// PsndRerate calls YM2612Init, which also resets\r
Pico.snd.len_e_cnt = 0; // Q16\r
\r
// samples per line (Q16)\r
- Pico.snd.fm_mult = 65536LL * PicoIn.sndRate / (target_fps*target_lines);\r
+ Pico.snd.smpl_mult = 65536LL * PicoIn.sndRate / (target_fps*target_lines);\r
// samples per z80 clock (Q20)\r
- Pico.snd.dac_mult = 16 * Pico.snd.fm_mult * 15/7 / 488;\r
-\r
- // recalculate dac info\r
- dac_recalculate();\r
+ Pico.snd.clkl_mult = 16 * Pico.snd.smpl_mult * 15/7 / 488;\r
\r
// clear all buffers\r
memset32(PsndBuffer, 0, sizeof(PsndBuffer)/4);\r
Pico.snd.len_e_cnt -= 0x10000;\r
Pico.snd.len_use++;\r
}\r
-\r
- Pico.snd.psg_line = 0;\r
}\r
\r
PICO_INTERNAL void PsndDoDAC(int cyc_to)\r
int dout = ym2612.dacout;\r
\r
// number of samples to fill in buffer (Q20)\r
- len = (cyc_to * Pico.snd.dac_mult) - Pico.snd.dac_pos;\r
+ len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.dac_pos;\r
\r
// update position and calculate buffer offset and length\r
pos = (Pico.snd.dac_pos+0x80000) >> 20;\r
\r
PICO_INTERNAL void PsndDoPSG(int line_to)\r
{\r
- int line_from = Pico.snd.psg_line;\r
- int pos, pos1, len;\r
+ int pos, len;\r
int stereo = 0;\r
\r
- pos = dac_info[line_from];\r
- pos1 = dac_info[line_to + 1];\r
- len = pos1 - pos;\r
+ // Q16, number of samples since last call\r
+ len = ((line_to+1) * Pico.snd.smpl_mult) - Pico.snd.psg_pos;\r
if (len <= 0)\r
return;\r
\r
- Pico.snd.psg_line = line_to + 1;\r
+ // update position and calculate buffer offset and length\r
+ pos = (Pico.snd.psg_pos+0x8000) >> 16;\r
+ Pico.snd.psg_pos += len;\r
+ len = ((Pico.snd.psg_pos+0x8000) >> 16) - pos;\r
\r
if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))\r
return;\r
SN76496Update(PicoIn.sndOut + pos, len, stereo);\r
}\r
\r
-PICO_INTERNAL void PsndDoFM(int line_to)\r
+PICO_INTERNAL void PsndDoFM(int cyc_to)\r
{\r
int pos, len;\r
int stereo = 0;\r
\r
// Q16, number of samples since last call\r
- len = ((line_to-1) * Pico.snd.fm_mult) - Pico.snd.fm_pos;\r
+ len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.fm_pos;\r
\r
// don't do this too often (about every 4th scanline)\r
- if (len >> 16 <= PicoIn.sndRate >> 12)\r
+ if (len >> 20 <= PicoIn.sndRate >> 12)\r
return;\r
\r
// update position and calculate buffer offset and length\r
- pos = (Pico.snd.fm_pos+0x8000) >> 16;\r
+ pos = (Pico.snd.fm_pos+0x80000) >> 20;\r
Pico.snd.fm_pos += len;\r
- len = ((Pico.snd.fm_pos+0x8000) >> 16) - pos;\r
+ len = ((Pico.snd.fm_pos+0x80000) >> 20) - pos;\r
\r
// fill buffer\r
if (PicoIn.opt & POPT_EN_STEREO) {\r
if (!(PicoIn.opt & POPT_EN_FM))\r
memset32(PsndBuffer, 0, PicoIn.opt & POPT_EN_STEREO ? len*2 : len);\r
// drop pos remainder to avoid rounding errors (not entirely correct though)\r
- Pico.snd.dac_pos = Pico.snd.fm_pos = 0;\r
+ Pico.snd.dac_pos = Pico.snd.fm_pos = Pico.snd.psg_pos = 0;\r
}\r
\r
\r
{\r
int *buf32;\r
int stereo = (PicoIn.opt & 8) >> 3;\r
- int fmlen = ((Pico.snd.fm_pos+0x8000) >> 16);\r
+ int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);\r
int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);\r
\r
buf32 = PsndBuffer+(offset<<stereo);\r
if (length-daclen > 0) {\r
short *dacbuf = PicoIn.sndOut + (daclen << stereo);\r
Pico.snd.dac_pos += (length-daclen) << 20;\r
- for (; length-daclen > 0; daclen++) {\r
+ *dacbuf++ += Pico.snd.dac_val2;\r
+ if (stereo) dacbuf++;\r
+ for (daclen++; length-daclen > 0; daclen++) {\r
*dacbuf++ += Pico.snd.dac_val;\r
if (stereo) dacbuf++;\r
}\r
+ Pico.snd.dac_val2 = Pico.snd.dac_val;\r
}\r
\r
// Add in parts of the FM buffer not yet done\r
if (length-fmlen > 0) {\r
int *fmbuf = buf32 + ((fmlen-offset) << stereo);\r
- Pico.snd.fm_pos += (length-fmlen) << 16;\r
+ Pico.snd.fm_pos += (length-fmlen) << 20;\r
if (PicoIn.opt & POPT_EN_FM)\r
YM2612UpdateOne(fmbuf, length-fmlen, stereo, 1);\r
}\r
{\r
static int curr_pos = 0;\r
\r
- if (ym2612.dacen)\r
- PsndDoDAC(cycles_68k_to_z80(Pico.t.m68c_aim - Pico.t.m68c_frame_start));\r
PsndDoPSG(y - 1);\r
\r
curr_pos = PsndRender(0, Pico.snd.len_use);\r