Beispiel #1
0
 // ---------------------------------------------------------------------------
 //	合成
 //	in:		buffer		合成先
 //			nsamples	合成サンプル数
 //
 public void Mix(int[] buffer, int nsamples)
 {
     fm6[0].Mix(buffer, nsamples, regtc);
     fm6[1].Mix(buffer, nsamples, regtc);
     psg2[0].Mix(buffer, nsamples);
     psg2[1].Mix(buffer, nsamples);
     psg2[2].Mix(buffer, nsamples);
     psg2[3].Mix(buffer, nsamples);
     adpcmb[0].Mix(buffer, nsamples);
     adpcmb[1].Mix(buffer, nsamples);
     adpcmb[2].Mix(buffer, nsamples);
     RhythmMix(buffer, nsamples);
     adpcma.Mix(buffer, (uint)nsamples);
     ep3band.Mix(buffer, nsamples);
     compressor.Mix(buffer, nsamples);
 }
Beispiel #2
0
        protected void MixSubS(int activech, int[] dest, int[] buf)
        {
            int v;
            int L, R;

            if ((activech & 0x001) != 0)
            {
                v = ch[0].Calc();
                L = v;
                R = v;
                distortion.Mix(efcStartCh + 0, ref L, ref R);
                chorus.Mix(efcStartCh + 0, ref L, ref R);
                hpflpf.Mix(efcStartCh + 0, ref L, ref R);
                compressor.Mix(efcStartCh + 0, ref L, ref R);
                buf[0] = (int)((dest[0] >> 1) * L * panL[0]) * reversePhase.FM[num][0][0];
                buf[1] = (int)((dest[0] & 0x1) * R * panR[0]) * reversePhase.FM[num][0][1];
                buf[2] = (int)(buf[0] * reverb.SendLevel[efcStartCh + 0]);
                buf[3] = (int)(buf[1] * reverb.SendLevel[efcStartCh + 0]);
            }

            if ((activech & 0x004) != 0)
            {
                v = ch[1].Calc();
                L = v;
                R = v;
                distortion.Mix(efcStartCh + 1, ref L, ref R);
                chorus.Mix(efcStartCh + 1, ref L, ref R);
                hpflpf.Mix(efcStartCh + 1, ref L, ref R);
                compressor.Mix(efcStartCh + 1, ref L, ref R);
                L       = (int)((dest[1] >> 1) * L * panL[1]) * reversePhase.FM[num][1][0];
                R       = (int)((dest[1] & 0x1) * R * panR[1]) * reversePhase.FM[num][1][1];
                buf[0] += L;
                buf[1] += R;
                buf[2] += (int)(L * reverb.SendLevel[efcStartCh + 1]);
                buf[3] += (int)(R * reverb.SendLevel[efcStartCh + 1]);
            }

            if ((activech & 0x010) != 0)
            {
                v = ch[2].Calc();
                L = v;
                R = v;
                distortion.Mix(efcStartCh + 2, ref L, ref R);
                chorus.Mix(efcStartCh + 2, ref L, ref R);
                hpflpf.Mix(efcStartCh + 2, ref L, ref R);
                compressor.Mix(efcStartCh + 2, ref L, ref R);
                L       = (int)((dest[2] >> 1) * L * panL[2]) * reversePhase.FM[num][2][0];
                R       = (int)((dest[2] & 0x1) * R * panR[2]) * reversePhase.FM[num][2][1];
                buf[0] += L;
                buf[1] += R;
                buf[2] += (int)(L * reverb.SendLevel[efcStartCh + 2]);
                buf[3] += (int)(R * reverb.SendLevel[efcStartCh + 2]);
            }

            if ((activech & 0x040) != 0)
            {
                v = ch[3].Calc();
                L = v;
                R = v;
                distortion.Mix(efcStartCh + 3, ref L, ref R);
                chorus.Mix(efcStartCh + 3, ref L, ref R);
                hpflpf.Mix(efcStartCh + 3, ref L, ref R);
                compressor.Mix(efcStartCh + 3, ref L, ref R);
                L       = (int)((dest[3] >> 1) * L * panL[3]) * reversePhase.FM[num][3][0];
                R       = (int)((dest[3] & 0x1) * R * panR[3]) * reversePhase.FM[num][3][1];
                buf[0] += L;
                buf[1] += R;
                buf[2] += (int)(L * reverb.SendLevel[efcStartCh + 3]);
                buf[3] += (int)(R * reverb.SendLevel[efcStartCh + 3]);
            }

            if ((activech & 0x100) != 0)
            {
                v = ch[4].Calc();
                L = v;
                R = v;
                distortion.Mix(efcStartCh + 4, ref L, ref R);
                chorus.Mix(efcStartCh + 4, ref L, ref R);
                hpflpf.Mix(efcStartCh + 4, ref L, ref R);
                compressor.Mix(efcStartCh + 4, ref L, ref R);
                L       = (int)((dest[4] >> 1) * L * panL[4]) * reversePhase.FM[num][4][0];
                R       = (int)((dest[4] & 0x1) * R * panR[4]) * reversePhase.FM[num][4][1];
                buf[0] += L;
                buf[1] += R;
                buf[2] += (int)(L * reverb.SendLevel[efcStartCh + 4]);
                buf[3] += (int)(R * reverb.SendLevel[efcStartCh + 4]);
            }

            if ((activech & 0x400) != 0)
            {
                v = ch[5].Calc();
                L = v;
                R = v;
                distortion.Mix(efcStartCh + 5, ref L, ref R);
                chorus.Mix(efcStartCh + 5, ref L, ref R);
                hpflpf.Mix(efcStartCh + 5, ref L, ref R);
                compressor.Mix(efcStartCh + 5, ref L, ref R);
                L       = (int)((dest[5] >> 1) * L * panL[5]) * reversePhase.FM[num][5][0];
                R       = (int)((dest[5] & 0x1) * R * panR[5]) * reversePhase.FM[num][5][1];
                buf[0] += L;
                buf[1] += R;
                buf[2] += (int)(L * reverb.SendLevel[efcStartCh + 5]);
                buf[3] += (int)(R * reverb.SendLevel[efcStartCh + 5]);
            }
        }
Beispiel #3
0
        // ---------------------------------------------------------------------------
        //	ADPCMA 合成
        //
        public void Mix(int[] buffer, uint count)
        {
            if (tvol < 128 && (key & 0x3f) != 0)
            {
                //Sample* limit = buffer + count * 2;
                uint limit      = count * 2;
                int  revSampleL = 0;
                int  revSampleR = 0;
                for (int i = 0; i < 6; i++)
                {
                    Channel r = channel[i];
                    if ((key & (1 << i)) != 0 && (byte)r.level < 128)
                    {
                        //uint maskl = (uint)(r.panL == 0f ? -1 : 0);
                        //uint maskr = (uint)(r.panR == 0f ? -1 : 0);

                        int db  = fmvgen.Limit(tl + tvol + r.level + r.volume, 127, -31);
                        int vol = fmgen.OPNABase.tltable[fmvgen.FM_TLPOS + (db << (fmvgen.FM_TLBITS - 7))] >> 4;

                        //Sample* dest = buffer;
                        uint dest = 0;
                        for (; dest < limit; dest += 2)
                        {
                            r.step += (uint)step;
                            if (r.pos >= r.stop)
                            {
                                //SetStatus((uint)(0x100 << i));
                                key &= (byte)~(1 << i);
                                break;
                            }

                            for (; r.step > 0x10000; r.step -= 0x10000)
                            {
                                int data;
                                if ((r.pos & 1) == 0)
                                {
                                    r.nibble = buf[r.pos >> 1];
                                    data     = (int)(r.nibble >> 4);
                                }
                                else
                                {
                                    data = (int)(r.nibble & 0x0f);
                                }
                                r.pos++;

                                r.adpcmx += jedi_table[r.adpcmd + data];
                                r.adpcmx  = (short)fmvgen.Limit(r.adpcmx, 2048 * 3 - 1, -2048 * 3);
                                r.adpcmd += (short)decode_tableA1[data];
                                r.adpcmd  = (short)fmvgen.Limit(r.adpcmd, 48 * 16, 0);
                            }

                            int sampleL = (int)((r.adpcmx * vol) >> 10);
                            int sampleR = (int)((r.adpcmx * vol) >> 10);
                            distortion.Mix(revStartCh + i, ref sampleL, ref sampleR);
                            chorus.Mix(revStartCh + i, ref sampleL, ref sampleR);
                            hpflpf.Mix(revStartCh + i, ref sampleL, ref sampleR);
                            compressor.Mix(revStartCh + i, ref sampleL, ref sampleR);

                            sampleL = (int)(sampleL * r.panL) * reversePhase.AdpcmA[i][0];
                            sampleR = (int)(sampleR * r.panR) * reversePhase.AdpcmA[i][1];
                            fmvgen.StoreSample(ref buffer[dest + 0], sampleL);
                            fmvgen.StoreSample(ref buffer[dest + 1], sampleR);
                            revSampleL += (int)(sampleL * reverb.SendLevel[revStartCh + i] * 0.6);
                            revSampleR += (int)(sampleR * reverb.SendLevel[revStartCh + i] * 0.6);
                            //visRtmVolume[0] = (int)(sample & maskl);
                            //visRtmVolume[1] = (int)(sample & maskr);
                        }
                    }
                }
                reverb.StoreDataC(revSampleL, revSampleR);
            }
        }
Beispiel #4
0
        public void Mix(int[] dest, int count)
        {
            uint maskl = (uint)((control2 & 0x80) != 0 ? -1 : 0);
            uint maskr = (uint)((control2 & 0x40) != 0 ? -1 : 0);

            if (adpcmmask_)
            {
                maskl = maskr = 0;
            }

            if (adpcmplay)
            {
                int ptrDest = 0;
                //		LOG2("ADPCM Play: %d   DeltaN: %d\n", adpld, deltan);
                if (adpld <= 8192)      // fplay < fsamp
                {
                    for (; count > 0; count--)
                    {
                        if (adplc < 0)
                        {
                            adplc += 8192;
                            DecodeADPCMB();
                            if (!adpcmplay)
                            {
                                break;
                            }
                        }

                        int s  = (adplc * apout0 + (8192 - adplc) * apout1) >> 13;
                        int sL = (int)(s & maskl);
                        int sR = (int)(s & maskr);
                        distortion.Mix(efcCh, ref sL, ref sR);
                        chorus.Mix(efcCh, ref sL, ref sR);
                        hpflpf.Mix(efcCh, ref sL, ref sR);
                        compressor.Mix(efcCh, ref sL, ref sR);

                        sL = (int)(sL * panL) * reversePhase.Adpcm[num][0];
                        sR = (int)(sR * panR) * reversePhase.Adpcm[num][1];
                        int revSampleL = (int)(sL * reverb.SendLevel[efcCh]);
                        int revSampleR = (int)(sR * reverb.SendLevel[efcCh]);
                        fmvgen.StoreSample(ref dest[ptrDest + 0], sL);
                        fmvgen.StoreSample(ref dest[ptrDest + 1], sR);
                        reverb.StoreDataC(revSampleL, revSampleR);
                        //visAPCMVolume[0] = (int)(s & maskl);
                        //visAPCMVolume[1] = (int)(s & maskr);
                        ptrDest += 2;
                        adplc   -= adpld;
                    }
                    for (; count > 0 && apout0 != 0; count--)
                    {
                        if (adplc < 0)
                        {
                            apout0 = apout1;
                            apout1 = 0;
                            adplc += 8192;
                        }
                        int s  = (adplc * apout1) >> 13;
                        int sL = (int)(s & maskl);
                        int sR = (int)(s & maskr);
                        distortion.Mix(efcCh, ref sL, ref sR);
                        chorus.Mix(efcCh, ref sL, ref sR);
                        hpflpf.Mix(efcCh, ref sL, ref sR);
                        compressor.Mix(efcCh, ref sL, ref sR);

                        sL = (int)(sL * panL) * reversePhase.Adpcm[num][0];
                        sR = (int)(sR * panR) * reversePhase.Adpcm[num][1];
                        int revSampleL = (int)(sL * reverb.SendLevel[efcCh]);
                        int revSampleR = (int)(sR * reverb.SendLevel[efcCh]);
                        fmvgen.StoreSample(ref dest[ptrDest + 0], sL);
                        fmvgen.StoreSample(ref dest[ptrDest + 1], sR);
                        reverb.StoreDataC(revSampleL, revSampleR);
                        //visAPCMVolume[0] = (int)(s & maskl);
                        //visAPCMVolume[1] = (int)(s & maskr);
                        ptrDest += 2;
                        adplc   -= adpld;
                    }
                }
                else    // fplay > fsamp	(adpld = fplay/famp*8192)
                {
                    int t = (-8192 * 8192) / adpld;
                    for (; count > 0; count--)
                    {
                        int s = apout0 * (8192 + adplc);
                        while (adplc < 0)
                        {
                            DecodeADPCMB();
                            if (!adpcmplay)
                            {
                                goto stop;
                            }
                            s     -= apout0 * Math.Max(adplc, t);
                            adplc -= t;
                        }
                        adplc -= 8192;
                        s    >>= 13;
                        int sL = (int)(s & maskl);
                        int sR = (int)(s & maskr);
                        distortion.Mix(efcCh, ref sL, ref sR);
                        chorus.Mix(efcCh, ref sL, ref sR);
                        hpflpf.Mix(efcCh, ref sL, ref sR);
                        compressor.Mix(efcCh, ref sL, ref sR);

                        sL = (int)(sL * panL) * reversePhase.Adpcm[num][0];
                        sR = (int)(sR * panR) * reversePhase.Adpcm[num][1];
                        int revSampleL = (int)(sL * reverb.SendLevel[efcCh]);
                        int revSampleR = (int)(sR * reverb.SendLevel[efcCh]);
                        fmvgen.StoreSample(ref dest[ptrDest + 0], sL);
                        fmvgen.StoreSample(ref dest[ptrDest + 1], sR);
                        reverb.StoreDataC(revSampleL, revSampleR);
                        //visAPCMVolume[0] = (int)(s & maskl);
                        //visAPCMVolume[1] = (int)(s & maskr);
                        ptrDest += 2;
                    }
stop:
                    ;
                }
            }
            if (!adpcmplay)
            {
                apout0 = apout1 = adpcmout = 0;
                adplc  = 0;
            }
        }
Beispiel #5
0
        public override void Mix(int[] dest, int nsamples)
        {
            byte r7 = (byte)~reg[7];

            if (((r7 & 0x3f) | ((reg[8] | reg[9] | reg[10]) & 0x1f)) != 0)
            {
                chenable[0] = (byte)((((r7 & 0x01) != 0) && (speriod[0] <= (uint)(1 << toneshift))) ? 15 : 0);
                chenable[1] = (byte)((((r7 & 0x02) != 0) && (speriod[1] <= (uint)(1 << toneshift))) ? 15 : 0);
                chenable[2] = (byte)((((r7 & 0x04) != 0) && (speriod[2] <= (uint)(1 << toneshift))) ? 15 : 0);
                nenable[0]  = (byte)((r7 & 0x08) != 0 ? 1 : 0);
                nenable[1]  = (byte)((r7 & 0x10) != 0 ? 1 : 0);
                nenable[2]  = (byte)((r7 & 0x20) != 0 ? 1 : 0);
                p[0]        = ((mask & 1) != 0 && (reg[8] & 0x10) != 0) ? (uint?)null : 0;
                p[1]        = ((mask & 2) != 0 && (reg[9] & 0x10) != 0) ? (uint?)null : 1;
                p[2]        = ((mask & 4) != 0 && (reg[10] & 0x10) != 0) ? (uint?)null : 2;
                if (!phaseResetBefore[0] && phaseReset[0] != 0 && (r7 & 0x09) != 0)
                {
                    scount[0] = 0; phaseResetBefore[0] = true;
                }
                if (!phaseResetBefore[1] && phaseReset[1] != 0 && (r7 & 0x12) != 0)
                {
                    scount[1] = 0; phaseResetBefore[1] = true;
                }
                if (!phaseResetBefore[2] && phaseReset[2] != 0 && (r7 & 0x24) != 0)
                {
                    scount[2] = 0; phaseResetBefore[2] = true;
                }

                int  noise, sample, sampleL, sampleR, revSampleL, revSampleR;
                uint env;
                int  nv = 0;

                if (p[0] != null && p[1] != null && p[2] != null)
                {
                    // エンベロープ無し
                    if ((r7 & 0x38) == 0)
                    {
                        int ptrDest = 0;
                        // ノイズ無し
                        for (int i = 0; i < nsamples; i++)
                        {
                            sampleL    = 0;
                            sampleR    = 0;
                            revSampleL = 0;
                            revSampleR = 0;

                            for (int j = 0; j < (1 << oversampling); j++)
                            {
                                for (int k = 0; k < 3; k++)
                                {
                                    sample = tblGetSample[duty[k]](k, olevel[k]);
                                    int L = sample;
                                    int R = sample;
                                    distortion.Mix(efcStartCh + k, ref L, ref R);
                                    chorus.Mix(efcStartCh + k, ref L, ref R);
                                    hpflpf.Mix(efcStartCh + k, ref L, ref R);
                                    compressor.Mix(efcStartCh + k, ref L, ref R);
                                    L           = (panpot[k] & 2) != 0 ? L : 0;
                                    R           = (panpot[k] & 1) != 0 ? R : 0;
                                    L          *= reversePhase.SSG[num][k][0];
                                    R          *= reversePhase.SSG[num][k][1];
                                    revSampleL += (int)(L * reverb.SendLevel[efcStartCh + k] * 0.6);
                                    revSampleR += (int)(R * reverb.SendLevel[efcStartCh + k] * 0.6);
                                    sampleL    += L;
                                    sampleR    += R;
                                    scount[k]  += speriod[k];
                                }
                            }
                            sampleL    /= (1 << oversampling);
                            sampleR    /= (1 << oversampling);
                            revSampleL /= (1 << oversampling);
                            revSampleR /= (1 << oversampling);

                            StoreSample(ref dest[ptrDest + 0], sampleL);
                            StoreSample(ref dest[ptrDest + 1], sampleR);
                            reverb.StoreDataC(revSampleL, revSampleR);
                            ptrDest += 2;

                            visVolume = sampleL;
                        }
                    }
                    else
                    {
                        int ptrDest = 0;
                        // ノイズ有り
                        for (int i = 0; i < nsamples; i++)
                        {
                            sampleL    = 0;
                            sampleR    = 0;
                            revSampleL = 0;
                            revSampleR = 0;
                            sample     = 0;
                            for (int j = 0; j < (1 << oversampling); j++)
                            {
                                noise = (int)(noisetable[((uint)ncountDbl >> (int)((noiseshift + oversampling + 6)) & (noisetablesize - 1))]
                                              >> (int)((uint)ncountDbl >> (noiseshift + oversampling + 1)));

                                ncountDbl += ((double)nperiod / ((reg[6] & 0x20) != 0 ? ncountDiv : 1.0));

                                for (int k = 0; k < 3; k++)
                                {
                                    sample = tblGetSample[duty[k]](k, olevel[k]);
                                    int L = sample;
                                    int R = sample;

                                    //ノイズ
                                    nv     = ((int)(scount[k] >> (toneshift + oversampling)) & 0 | (nenable[k] & noise)) - 1;
                                    sample = (int)((olevel[k] + nv) ^ nv);
                                    L     += sample;
                                    R     += sample;

                                    distortion.Mix(efcStartCh + k, ref L, ref R);
                                    chorus.Mix(efcStartCh + k, ref L, ref R);
                                    hpflpf.Mix(efcStartCh + k, ref L, ref R);
                                    compressor.Mix(efcStartCh + k, ref L, ref R);
                                    L           = (panpot[k] & 2) != 0 ? L : 0;
                                    R           = (panpot[k] & 1) != 0 ? R : 0;
                                    L          *= reversePhase.SSG[num][k][0];
                                    R          *= reversePhase.SSG[num][k][1];
                                    revSampleL += (int)(L * reverb.SendLevel[efcStartCh + k] * 0.6);
                                    revSampleR += (int)(R * reverb.SendLevel[efcStartCh + k] * 0.6);
                                    sampleL    += L;
                                    sampleR    += R;
                                    scount[k]  += speriod[k];
                                }
                            }

                            sampleL /= (1 << oversampling);
                            sampleR /= (1 << oversampling);
                            StoreSample(ref dest[ptrDest + 0], sampleL);
                            StoreSample(ref dest[ptrDest + 1], sampleR);
                            reverb.StoreDataC(revSampleL, revSampleR);
                            ptrDest += 2;

                            visVolume = sampleL;
                        }
                    }

                    // エンベロープの計算をさぼった帳尻あわせ
                    ecount = (uint)((ecount >> 8) + (eperiod >> (8 - oversampling)) * nsamples);
                    if (ecount >= (1 << (envshift + 6 + oversampling - 8)))
                    {
                        if ((reg[0x0d] & 0x0b) != 0x0a)
                        {
                            ecount |= (1 << (envshift + 5 + oversampling - 8));
                        }
                        ecount &= (1 << (envshift + 6 + oversampling - 8)) - 1;
                    }
                    ecount <<= 8;
                }
                else
                {
                    int ptrDest = 0;
                    // エンベロープあり
                    for (int i = 0; i < nsamples; i++)
                    {
                        sampleL    = 0;
                        sampleR    = 0;
                        revSampleL = 0;
                        revSampleR = 0;

                        for (int j = 0; j < (1 << oversampling); j++)
                        {
                            env     = envelop[ecount >> (envshift + oversampling)];
                            ecount += eperiod;
                            if (ecount >= (1 << (envshift + 6 + oversampling)))
                            {
                                if ((reg[0x0d] & 0x0b) != 0x0a)
                                {
                                    ecount |= (1 << (envshift + 5 + oversampling));
                                }
                                ecount &= (1 << (envshift + 6 + oversampling)) - 1;
                            }
                            noise = (int)(noisetable[((uint)ncountDbl >> (int)((noiseshift + oversampling + 6)) & (noisetablesize - 1))]
                                          >> (int)((uint)ncountDbl >> (noiseshift + oversampling + 1)));
                            ncountDbl += (nperiod / ((reg[6] & 0x20) != 0 ? ncountDiv : 1.0));

                            for (int k = 0; k < 3; k++)
                            {
                                uint lv = (p[k] == null ? env : olevel[k]);
                                sample = tblGetSample[duty[k]](k, lv);
                                int L = sample;
                                int R = sample;

                                //ノイズ
                                nv     = ((int)(scount[k] >> (toneshift + oversampling)) & 0 | (nenable[k] & noise)) - 1;
                                sample = (int)((lv + nv) ^ nv);
                                L     += sample;
                                R     += sample;

                                distortion.Mix(efcStartCh + k, ref L, ref R);
                                chorus.Mix(efcStartCh + k, ref L, ref R);
                                hpflpf.Mix(efcStartCh + k, ref L, ref R);
                                compressor.Mix(efcStartCh + k, ref L, ref R);
                                L           = (panpot[k] & 2) != 0 ? L : 0;
                                R           = (panpot[k] & 1) != 0 ? R : 0;
                                L          *= reversePhase.SSG[num][k][0];
                                R          *= reversePhase.SSG[num][k][1];
                                revSampleL += (int)(L * reverb.SendLevel[efcStartCh + k] * 0.6);
                                revSampleR += (int)(R * reverb.SendLevel[efcStartCh + k] * 0.6);
                                sampleL    += L;
                                sampleR    += R;
                                scount[k]  += speriod[k];
                            }
                        }
                        sampleL    /= (1 << oversampling);
                        sampleR    /= (1 << oversampling);
                        revSampleL /= (1 << oversampling);
                        revSampleR /= (1 << oversampling);

                        StoreSample(ref dest[ptrDest + 0], sampleL);
                        StoreSample(ref dest[ptrDest + 1], sampleR);
                        reverb.StoreDataC(revSampleL, revSampleR);
                        ptrDest += 2;

                        visVolume = sampleL;
                    }
                }
            }
        }