コード例 #1
0
        // halt_osc: handle halting an oscillator
        // chip = chip ptr
        // onum = oscillator #
        // type = 1 for 0 found in sample data, 0 for hit end of table size
        private void es5503_halt_osc(ES5503Chip chip, int onum, int type, ref UInt32 accumulator, int resshift)
        {
            ES5503Osc pOsc        = chip.oscillators[onum];
            ES5503Osc pPartner    = chip.oscillators[onum ^ 1];
            int       mode        = (pOsc.control >> 1) & 3;
            int       partnerMode = (pPartner.control >> 1) & 3;

            // if 0 found in sample data or mode is not free-run, halt this oscillator
            if ((mode != (int)MODE.FREE) || (type != 0))
            {
                pOsc.control |= 1;
            }
            else                // preserve the relative phase of the oscillator when looping
            {
                UInt16 wtsize = (UInt16)(pOsc.wtsize - 1);
                UInt32 altram = accumulator >> resshift;

                if (altram > wtsize)
                {
                    altram -= wtsize;
                }
                else
                {
                    altram = 0;
                }

                accumulator = altram << resshift;
            }

            // if we're in swap mode or we're the even oscillator and the partner is in swap mode,
            // start the partner.
            if ((mode == (int)MODE.SWAP) || ((partnerMode == (int)MODE.SWAP) && ((onum & 1) == 0)))
            {
                pPartner.control    &= 0xff;             // ~1;    // clear the halt bit
                pPartner.accumulator = 0;                // and make sure it starts from the top (does this also need phase preservation?)
            }

            // IRQ enabled for this voice?
            if ((pOsc.control & 0x08) != 0)
            {
                pOsc.irqpend = 1;

                if (chip.irq_func != null)
                {
                    chip.irq_func(chip.irq_param, 1);
                }
            }
        }
コード例 #2
0
        private void es5503_pcm_update(ES5503Chip param, UInt32 samples, int[][] outputs)
        {
            byte       osc;
            UInt32     snum;
            UInt32     ramptr;
            ES5503Chip chip = param;
            byte       chnsStereo, chan;

            for (int i = 0; i < samples; i++)
            {
                outputs[0][i] = 0;
                outputs[1][i] = 0;
            }
            if (chip.docram == null)
            {
                return;
            }

            chnsStereo = (byte)(chip.output_channels & 0xff);            // ~1;
            for (osc = 0; osc < chip.oscsenabled; osc++)
            {
                ES5503Osc pOsc = chip.oscillators[osc];

                if ((pOsc.control & 1) == 0 && pOsc.Muted == 0)
                {
                    UInt32 wtptr = pOsc.wavetblpointer & wavemasks[pOsc.wavetblsize];
                    UInt32 altram;
                    UInt32 acc      = pOsc.accumulator;
                    UInt16 wtsize   = (UInt16)(pOsc.wtsize - 1);
                    UInt16 freq     = pOsc.freq;
                    Int16  vol      = pOsc.vol;
                    byte   chnMask  = (byte)((pOsc.control >> 4) & 0x0F);
                    int    resshift = resshifts[pOsc.resolution] - pOsc.wavetblsize;
                    UInt32 sizemask = accmasks[pOsc.wavetblsize];
                    Int32  outData;

                    chnMask &= chip.outchn_mask;
                    for (snum = 0; snum < samples; snum++)
                    {
                        altram = acc >> resshift;
                        ramptr = altram & sizemask;

                        acc += freq;

                        // channel strobe is always valid when reading; this allows potentially banking per voice
                        chip.channel_strobe = (byte)((pOsc.control >> 4) & 0xf);
                        pOsc.data           = chip.docram[ramptr + wtptr];

                        if (pOsc.data == 0x00)
                        {
                            es5503_halt_osc(chip, osc, 1, ref acc, resshift);
                        }
                        else
                        {
                            outData = (pOsc.data - 0x80) * vol;

                            // send groups of 2 channels to L or R
                            for (chan = 0; chan < chnsStereo; chan++)
                            {
                                if (chan == chnMask)
                                {
                                    outputs[chan & 1][snum] += outData;
                                }
                            }
                            outData = (outData * 181) >> 8;                             // outData *= sqrt(2)
                            // send remaining channels to L+R
                            for (; chan < chip.output_channels; chan++)
                            {
                                if (chan == chnMask)
                                {
                                    outputs[0][snum] += outData;
                                    outputs[1][snum] += outData;
                                }
                            }

                            if (altram >= wtsize)
                            {
                                es5503_halt_osc(chip, osc, 0, ref acc, resshift);
                            }
                        }

                        // if oscillator halted, we've got no more samples to generate
                        if ((pOsc.control & 1) != 0)
                        {
                            pOsc.control |= 1;
                            break;
                        }
                    }

                    pOsc.accumulator = acc;
                }
            }
        }