DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/snd_pc98/sound/psggeng.c
00001 #include    "np2glue.h"
00002 //#include      "compiler.h"
00003 #include        "parts.h"
00004 #include        "sound.h"
00005 #include        "psggen.h"
00006 
00007 
00008 extern  PSGGENCFG       psggencfg;
00009 
00010 
00011 void SOUNDCALL psggen_getpcm(PSGGEN psg, SINT32 *pcm, UINT count) {
00012 
00013 //      SINT32  noisevol;
00014         UINT8   mixer;
00015         UINT    noisetbl = 0;
00016         PSGTONE *tone;
00017         PSGTONE *toneterm;
00018         SINT32  samp;
00019 //      UINT    psgvol;
00020         SINT32  vol;
00021         UINT    i;
00022         UINT    noise;
00023 
00024         if ((psg->mixer & 0x3f) == 0) {
00025                 count = min(count, psg->puchicount);
00026                 psg->puchicount -= count;
00027         }
00028         if (count == 0) {
00029                 return;
00030         }
00031         do {
00032 //              noisevol = 0;
00033                 if (psg->envcnt) {
00034                         psg->envcnt--;
00035                         if (psg->envcnt == 0) {
00036                                 psg->envvolcnt--;
00037                                 if (psg->envvolcnt < 0) {
00038                                         if (psg->envmode & PSGENV_ONESHOT) {
00039                                                 psg->envvol = (psg->envmode & PSGENV_LASTON)?15:0;
00040                                         }
00041                                         else {
00042                                                 psg->envvolcnt = 15;
00043                                                 if (!(psg->envmode & PSGENV_ONECYCLE)) {
00044                                                         psg->envmode ^= PSGENV_INC;
00045                                                 }
00046                                                 psg->envcnt = psg->envmax;
00047                                                 psg->envvol = (psg->envvolcnt ^ psg->envmode) & 0x0f;
00048                                         }
00049                                 }
00050                                 else {
00051                                         psg->envcnt = psg->envmax;
00052                                         psg->envvol = (psg->envvolcnt ^ psg->envmode) & 0x0f;
00053                                 }
00054                                 psg->evol = psggencfg.volume[psg->envvol];
00055                         }
00056                 }
00057                 mixer = psg->mixer;
00058                 if (mixer & 0x38) {
00059                         for (i=0; i<(1 << PSGADDEDBIT); i++) {
00060                                 SINT32 countbak;
00061                                 countbak = psg->noise.count;
00062                                 psg->noise.count -= psg->noise.freq;
00063                                 if (psg->noise.count > countbak) {
00064 //                                      psg->noise.base = GETRAND() & (1 << (1 << PSGADDEDBIT));
00065                                         psg->noise.base = rand_get() & (1 << (1 << PSGADDEDBIT));
00066                                 }
00067                                 noisetbl += psg->noise.base;
00068                                 noisetbl >>= 1;
00069                         }
00070                 }
00071                 tone = psg->tone;
00072                 toneterm = tone + 3;
00073                 do {
00074                         vol = *(tone->pvol);
00075                         if (vol) {
00076                                 samp = 0;
00077                                 switch(mixer & 9) {
00078                                         case 0:                                                 // no mix
00079                                                 if (tone->puchi) {
00080                                                         tone->puchi--;
00081                                                         samp += vol << PSGADDEDBIT;
00082                                                 }
00083                                                 break;
00084 
00085                                         case 1:                                                 // tone only
00086                                                 for (i=0; i<(1 << PSGADDEDBIT); i++) {
00087                                                         tone->count += tone->freq;
00088                                                         samp += vol * ((tone->count>=0)?1:-1);
00089                                                 }
00090                                                 break;
00091 
00092                                         case 8:                                                 // noise only
00093                                                 noise = noisetbl;
00094                                                 for (i=0; i<(1 << PSGADDEDBIT); i++) {
00095                                                         samp += vol * ((noise & 1)?1:-1);
00096                                                         noise >>= 1;
00097                                                 }
00098                                                 break;
00099 
00100                                         case 9:
00101                                                 noise = noisetbl;
00102                                                 for (i=0; i<(1 << PSGADDEDBIT); i++) {
00103                                                         tone->count += tone->freq;
00104                                                         if ((tone->count >= 0) || (noise & 1)) {
00105                                                                 samp += vol;
00106                                                         }
00107                                                         else {
00108                                                                 samp -= vol;
00109                                                         }
00110                                                         noise >>= 1;
00111                                                 }
00112                                                 break;
00113                                 }
00114                                 if (!(tone->pan & 1)) {
00115                                         pcm[0] += samp;
00116                                 }
00117                                 if (!(tone->pan & 2)) {
00118                                         pcm[1] += samp;
00119                                 }
00120                         }
00121                         mixer >>= 1;
00122                 } while(++tone < toneterm);
00123                 pcm += 2;
00124         } while(--count);
00125 }
00126