--- xmil/sound/psggeng.c 2004/08/01 05:31:31 1.1 +++ xmil/sound/psggeng.c 2004/08/17 16:52:46 1.3 @@ -9,117 +9,137 @@ extern PSGGENCFG psggencfg; void SOUNDCALL psggen_getpcm(PSGGEN psg, SINT32 *pcm, UINT count) { + UINT r; + SINT32 *p; SINT32 noisevol; UINT8 mixer; UINT noisetbl = 0; PSGTONE *tone; PSGTONE *toneterm; SINT32 samp; -// UINT psgvol; SINT32 vol; UINT i; UINT noise; - if ((psg->mixer & 0x3f) == 0) { - count = min(count, psg->puchicount); - psg->puchicount -= count; - } - if (count == 0) { - return; - } - do { - noisevol = 0; - if (psg->envcnt) { - psg->envcnt--; - if (psg->envcnt == 0) { - psg->envvolcnt--; - if (psg->envvolcnt < 0) { - if (psg->envmode & PSGENV_ONESHOT) { - psg->envvol = (psg->envmode & PSGENV_LASTON)?15:0; + while(count) { + if (psg->envvolcnt >= 0) { + r = min(count, psg->envcnt); + psg->envcnt -= r; + } + else { + r = count; + } + p = pcm; + pcm += r * 2; + count -= r; + + if ((psg->mixer & 0x3f) == 0) { + r = min(r, psg->puchicount); + psg->puchicount -= r; + } + while(r) { + r--; + noisevol = 0; + mixer = psg->mixer; + if (mixer & 0x38) { + for (i=0; i<(1 << PSGADDEDBIT); i++) { + SINT32 countbak; + countbak = psg->noise.count; + psg->noise.count -= psg->noise.freq; + if (psg->noise.count > countbak) { + psg->noise.base = rand_get() & + (1 << (1 << PSGADDEDBIT)); + } + noisetbl += psg->noise.base; + noisetbl >>= 1; + } + } + tone = psg->tone; + toneterm = tone + 3; + do { + vol = *(tone->pvol); + if (vol) { + samp = 0; + switch(mixer & 9) { + case 0: // no mix + if (tone->puchi) { + tone->puchi--; + samp += vol << PSGADDEDBIT; + } + break; + + case 1: // tone only + for (i=0; i<(1 << PSGADDEDBIT); i++) { + tone->count += tone->freq; + samp += vol * ((tone->count>=0)?1:-1); + } + break; + + case 8: // noise only + noise = noisetbl; + for (i=0; i<(1 << PSGADDEDBIT); i++) { + samp += vol * ((noise & 1)?1:-1); + noise >>= 1; + } + break; + + case 9: + noise = noisetbl; + for (i=0; i<(1 << PSGADDEDBIT); i++) { + tone->count += tone->freq; + if ((tone->count >= 0) && (noise & 1)) { + samp += vol; + } + else { + samp -= vol; + } + noise >>= 1; + } + break; + } + if (!(tone->pan & 1)) { + p[0] += samp; } - else { - psg->envvolcnt = 15; - if (!(psg->envmode & PSGENV_ONECYCLE)) { - psg->envmode ^= PSGENV_INC; - } - psg->envcnt = psg->envmax; - psg->envvol = (psg->envvolcnt ^ psg->envmode) & 0x0f; + if (!(tone->pan & 2)) { + p[1] += samp; } } + mixer >>= 1; + } while(++tone < toneterm); + p += 2; + } + + if ((psg->envvolcnt >= 0) && (psg->envcnt == 0)) { + psg->envvolcnt--; + if (psg->envvolcnt < 0) { + if (psg->envmode & PSGENV_ONESHOT) { + psg->envvol = (psg->envmode & PSGENV_LASTON)?15:0; + } else { + psg->envvolcnt = 15; + if (!(psg->envmode & PSGENV_ONECYCLE)) { + psg->envmode ^= PSGENV_INC; + } psg->envcnt = psg->envmax; psg->envvol = (psg->envvolcnt ^ psg->envmode) & 0x0f; } - psg->evol = psggencfg.volume[psg->envvol]; } - } - mixer = psg->mixer; - if (mixer & 0x38) { - for (i=0; i<(1 << PSGADDEDBIT); i++) { - SINT32 countbak; - countbak = psg->noise.count; - psg->noise.count -= psg->noise.freq; - if (psg->noise.count > countbak) { -// psg->noise.base = GETRAND() & (1 << (1 << PSGADDEDBIT)); - psg->noise.base = rand_get() & (1 << (1 << PSGADDEDBIT)); - } - noisetbl += psg->noise.base; - noisetbl >>= 1; + else { + psg->envcnt = psg->envmax; + psg->envvol = (psg->envvolcnt ^ psg->envmode) & 0x0f; } - } - tone = psg->tone; - toneterm = tone + 3; - do { - vol = *(tone->pvol); - if (vol) { - samp = 0; - switch(mixer & 9) { - case 0: // no mix - if (tone->puchi) { - tone->puchi--; - samp += vol << PSGADDEDBIT; - } - break; - - case 1: // tone only - for (i=0; i<(1 << PSGADDEDBIT); i++) { - tone->count += tone->freq; - samp += vol * ((tone->count>=0)?1:-1); - } - break; - - case 8: // noise only - noise = noisetbl; - for (i=0; i<(1 << PSGADDEDBIT); i++) { - samp += vol * ((noise & 1)?1:-1); - noise >>= 1; - } - break; - - case 9: - noise = noisetbl; - for (i=0; i<(1 << PSGADDEDBIT); i++) { - tone->count += tone->freq; - if ((tone->count >= 0) || (noise & 1)) { - samp += vol; - } - else { - samp -= vol; - } - noise >>= 1; - } - break; - } - if (!(tone->pan & 1)) { - pcm[0] += samp; - } - if (!(tone->pan & 2)) { - pcm[1] += samp; - } + psg->puchicount = psggencfg.puchidec; + if (psg->reg.vol[0] & 0x10) { + psg->tone[0].puchi = psggencfg.puchidec; } - mixer >>= 1; - } while(++tone < toneterm); - pcm += 2; - } while(--count); + if (psg->reg.vol[1] & 0x10) { + psg->tone[1].puchi = psggencfg.puchidec; + } + if (psg->reg.vol[2] & 0x10) { + psg->tone[2].puchi = psggencfg.puchidec; + } + psg->evol = psggencfg.volume[psg->envvol]; + } + } }