Ejemplo n.º 1
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                if (this.batch.Length == 0)
                {
                    return;
                }

                float inv = 1.0f / this.batch.Length;

                FPCM fpcm = null;

                foreach (GenBase gb in this.batch)
                {
                    if (fpcm == null)
                    {
                        fpcm = pcmFactory.GetZeroedFPCM(start, size);
                    }
                    else
                    {
                        fpcm.Zero(start, size);
                    }

                    float [] rf = fpcm.buffer;

                    fixed(float *prf = rf)
                    {
                        gb.Accumulate(prf, start, size, prefBuffSz, pcmFactory);

                        for (int i = start; i < start + size; ++i)
                        {
                            data[i] += prf[i] * inv;
                        }
                    }
                }
            }
Ejemplo n.º 2
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                if (this.passed == true)
                {
                    this.gen.Accumulate(data, start, size, prefBuffSz, pcmFactory);
                    return;
                }

                if (this.offset > 0)
                {
                    int burn = Min(size, this.offset);
                    start       += burn;
                    size        -= burn;
                    this.offset -= burn;

                    if (size <= 0)
                    {
                        return;
                    }
                }

                FPCM fa = pcmFactory.GetZeroedFPCM(start, size);

                float [] a = fa.buffer;

                fixed(float *pa = a)
                {
                    this.gen.Accumulate(pa, start, size, prefBuffSz, pcmFactory);

                    float at     = this.itAttack;
                    float tot    = (float)this.totalAttackSamples;
                    int   sampCt = Min(size, totalAttackSamples - itAttack);

                    for (int i = start; i < start + sampCt; ++i)
                    {
                        float v = at / tot;
                        at += 1.0f;

                        data[i] = pa[i] * v;
                    }

                    start         += sampCt;
                    size          -= sampCt;
                    this.itAttack += sampCt;

                    if (this.itAttack >= this.totalAttackSamples)
                    {
                        this.passed = true;
                    }

                    for (int i = start; i < start + size; ++i)
                    {
                        data[i] = pa[i];
                    }
                }
            }
Ejemplo n.º 3
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                FPCM fa = pcmFactory.GetZeroedFPCM(start, size);
                FPCM fb = pcmFactory.GetZeroedFPCM(start, size);

                float [] a = fa.buffer;
                float [] b = fb.buffer;

                fixed(float *pa = a, pb = b)
                {
                    this.gma.Accumulate(pa, start, size, prefBuffSz, pcmFactory);
                    this.gmb.Accumulate(pb, start, size, prefBuffSz, pcmFactory);

                    for (int i = start; i < start + size; ++i)
                    {
                        data[i] = pa[i] + pb[i];
                    }
                }
            }
Ejemplo n.º 4
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                FPCM fa = pcmFactory.GetZeroedFPCM(start, size);

                float [] a = fa.buffer;

                fixed(float *pa = a)
                {
                    this.input.Accumulate(pa, start, size, prefBuffSz, pcmFactory);

                    for (int i = start; i < start + size; ++i)
                    {
                        data[i] = ((float)(int)(pa[i] * factor)) * invFactor;
                    }
                }
            }
Ejemplo n.º 5
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                while (size > 0)
                {
                    if (this.playing == true)
                    {
                        int burn = Min(size, this.samplesLeft);

                        this.input.Accumulate(data, start, size, prefBuffSz, pcmFactory);

                        this.samplesLeft -= burn;
                        size             -= burn;
                        start            += burn;

                        if (this.samplesLeft == 0)
                        {
                            this.playing     = false;
                            this.samplesLeft = this.holdSamples;
                        }
                    }
                    else
                    {
                        int burn = Min(size, this.samplesLeft);

                        // A true burn, pulling the samples just to do absolutely nothing
                        // with them, but we need to get time to pass for the rest of the hierarchy.
                        FPCM    fa = pcmFactory.GetZeroedFPCM(start, size);
                        float[] a  = fa.buffer;

                        fixed(float *pa = a)
                        {
                            this.input.Accumulate(pa, start, size, prefBuffSz, pcmFactory);
                        }

                        this.samplesLeft -= burn;
                        size             -= burn;
                        start            += burn;

                        if (this.samplesLeft == 0)
                        {
                            this.playing     = true;
                            this.samplesLeft = this.playSamples;
                        }
                    }
                }
            }
Ejemplo n.º 6
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBufSz, FPCMFactoryGenLimit pcmFactory)
            {
                // Early release
                if (this.released == true)
                {
                    if (this.releaseLeft > 0)
                    {
                        FPCM    fpcmRl = pcmFactory.GetZeroedFPCM(start, size);
                        float[] fprl   = fpcmRl.buffer;

                        int sampsCt = Mathf.Min(this.releaseLeft, size);

                        // We could probably optimize this by only calling AccumulateImpl_NonReleasePart()
                        // when we're not in sustain yet.
                        fixed(float *pfprl = fprl)
                        {
                            this.AccumulateImpl_NonReleasePart(pfprl, start, size, prefBufSz, pcmFactory);

                            float total = this.releaseTotal;
                            float left  = this.releaseLeft;

                            for (int ei = start; ei < start + sampsCt; ++ei)
                            {
                                data[ei] = pfprl[ei] * (left / total);
                                left    -= 1.0f;
                            }
                        }

                        this.releaseLeft -= sampsCt;
                        return;
                    }
                    else if (this.saftey > 0)
                    {
                        this.saftey -= size;
                    }
                }
                else
                {
                    this.AccumulateImpl_NonReleasePart(data, start, size, prefBufSz, pcmFactory);
                }
            }
Ejemplo n.º 7
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                FPCM fa = pcmFactory.GetZeroedFPCM(start, size);

                float[] a = fa.buffer;

                fixed(float *pa = a)
                {
                    this.input.Accumulate(pa, start, size, prefBuffSz, pcmFactory);

                    for (int i = start; i < start + size; ++i)
                    {
                        this.valAccum += this.integrateFactor * pa[i];
                        this.wtAccum  += this.integrateFactor;

                        data[i] += this.valAccum / this.wtAccum;

                        this.wtAccum  *= this.decayFactor;
                        this.valAccum *= this.decayFactor;
                    }
                }
            }
Ejemplo n.º 8
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                if (this.durationSamples <= 0)
                {
                    if (this.sustain == 0.0f)
                    {
                        // If duration is over and we don't have sustain, early exit. We account
                        // for what we would have written as a timer for Finished() do it doesn't
                        // exit too early.
                        this.durationSamples -= size;
                    }
                    else
                    {
                        // If duration is over, we're in sustain
                        FPCM    fsus = pcmFactory.GetZeroedFPCM(start, size);
                        float[] sus  = fsus.buffer;

                        fixed(float *psus = sus)
                        {
                            this.gen.Accumulate(psus, start, size, prefBuffSz, pcmFactory);
                            for (int i = start; i < start + size; ++i)
                            {
                                data[i] = psus[i] * this.sustain;
                            }
                        }
                    }
                    return;
                }

                // Are we at a time before the decay is activated?
                // If it's going to be that way for the entire decay, just
                // relay it.
                if (this.offsetSamples > size)
                {
                    this.offsetSamples -= size;
                    this.gen.Accumulate(data, start, size, prefBuffSz, pcmFactory);
                    return;
                }

                FPCM fa = pcmFactory.GetZeroedFPCM(start, size);

                float[] a = fa.buffer;

                fixed(float *pa = a)
                {
                    this.gen.Accumulate(pa, start, size, prefBuffSz, pcmFactory);

                    // Are we at a time before the decay is activated, but
                    // will need to start the decay before we exit?
                    if (this.offsetSamples > 0)
                    {
                        int endOS = start + this.offsetSamples;
                        for (int i = start; i < start + endOS; ++i)
                        {
                            data[i] = pa[i];
                        }

                        size  -= this.offsetSamples;
                        start += this.offsetSamples;
                        this.offsetSamples = 0;
                    }

                    // The decay. We have two versions, because if the sustain ramps to zero, we can
                    // avoid some lerp math.
                    float total    = totalDurationSamples;
                    int   decSamps = Mathf.Min(size, this.durationSamples);
                    int   end      = start + decSamps;

                    if (this.sustain == 0.0f)
                    {
                        float durs = (float)this.durationSamples;
                        for (int i = start; i < end; ++i)
                        {
                            float lam = durs / total;
                            data[i] = pa[i] * lam;
                            durs   -= 1.0f;
                        }
                        durationSamples -= decSamps;
                    }
                    else
                    {
                        float durs = (float)this.durationSamples;
                        for (int i = start; i < end; ++i)
                        {
                            float lam = sustain + durs / total * this.invSustain;
                            data[i] += pa[i] * lam;
                            durs    -= 1.0f;
                        }
                        start += decSamps;
                        size  -= decSamps;
                        this.durationSamples -= decSamps;

                        // If we finish the ramp in the middle, we need to fill the rest with sustain
                        for (int i = start; i < start + size; ++i)
                        {
                            data[i] = pa[i] * this.sustain;
                        }
                    }
                }
            }
Ejemplo n.º 9
0
            unsafe public override void AccumulateImpl(float *data, int start, int size, int prefBuffSz, FPCMFactoryGenLimit pcmFactory)
            {
                if (this.offset > 0)
                {
                    int of = Min(this.offset, size);
                    if (this.passOffset == OffsetPass.Silent)
                    {
                        // If silent, we still need to let time pass for it, so
                        // we need to burn it.
                        FPCM     fpcm = pcmFactory.GetZeroedFPCM(start, size);
                        float [] a    = fpcm.buffer;

                        fixed(float *pa = a)
                        {
                            this.input.Accumulate(pa, start, of, prefBuffSz, pcmFactory);
                        }
                    }
                    else if (this.passOffset == OffsetPass.Pass)
                    {
                        this.input.Accumulate(data, start, of, prefBuffSz, pcmFactory);
                    }
                    else if (this.passOffset == OffsetPass.Hold)
                    {
                    }   // Do nothing

                    this.offset -= of;
                    start       += of;
                    size        -= of;

                    if (size == 0)
                    {
                        return;
                    }
                }

                if (this.recordingIt < this.rfs.Length)
                {
                    int recAmt = Min(size, this.rfs.Length - this.recordingIt);

                    FPCM     fpcm = pcmFactory.GetZeroedFPCM(0, size);
                    float [] lbuf = fpcm.buffer;

                    fixed(float *plbuf = lbuf)
                    {
                        this.input.Accumulate(plbuf, 0, recAmt, prefBuffSz, pcmFactory);

                        for (int i = 0; i < recAmt; ++i)
                        {
                            data[start + i]      = plbuf[i];
                            rfs[recordingIt + i] = plbuf[i];
                        }
                    }

                    this.recordingIt += recAmt;
                    start            += recAmt;
                    size             -= recAmt;

                    if (this.recordingIt == this.rfs.Length)
                    {
                        // If the buffer size is tiny, we're going to duplicate it to a sane amount
                        // so we don't have many tiny cycles when it comes to replaying it.
                        if (this.rfs.Length < prefBuffSz)
                        {
                            int repCt = this.rfs.Length / prefBuffSz;
                            if (repCt > 1)
                            {
                                float [] rfOld = this.rfs;
                                int      oldSz = this.rfs.Length;

                                // Repeat the buffer
                                this.rfs = new float[oldSz * repCt];
                                for (int i = 1; i < repCt; ++i)
                                {
                                    int baseIdx = i * oldSz;
                                    for (int j = 0; j < oldSz; ++j)
                                    {
                                        this.rfs[baseIdx + j] = rfOld[j];
                                    }
                                }
                            }
                        }
                    }
                }

                while (size > 0)
                {
                    this.playbackIt %= this.rfs.Length;

                    int sameCt = Min(this.rfs.Length - this.playbackIt, size);

                    for (int i = 0; i < sameCt; ++i)
                    {
                        data[start + i] = rfs[this.playbackIt + i];
                    }

                    this.playbackIt += sameCt;
                    start           += sameCt;
                    size            -= sameCt;
                }
            }
Ejemplo n.º 10
0
            unsafe public void AccumulateImpl_NonReleasePart(float *data, int start, int size, int prefBufSz, FPCMFactoryGenLimit pcmFactory)
            {
                FPCM fpcm = pcmFactory.GetZeroedFPCM(start, size);

                float[] fp = fpcm.buffer;

                fixed(float *pfp = fp)
                {
                    this.input.Accumulate(pfp, start, size, prefBufSz, pcmFactory);


                    if (this.offset > 0)
                    {
                        int ofrm = Mathf.Min(this.offset, size);
                        this.offset -= ofrm;
                        start       += ofrm;
                        size        -= ofrm;

                        if (size <= 0)
                        {
                            return;
                        }
                    }

                    // ATTACK
                    if (this.attackIt < this.attackTotal)
                    {
                        int   atrm    = Mathf.Min(this.attackTotal - this.attackIt, size);
                        int   end     = start + atrm;
                        float totalAt = this.attackTotal;
                        float at      = this.attackIt;
                        for (int i = start; i < end; ++i)
                        {
                            data[i] = pfp[i] * (at / totalAt);
                            at     += 1.0f;
                        }

                        this.attackIt += atrm;

                        size  -= atrm;
                        start += atrm;
                        if (size <= 0)
                        {
                            return;
                        }
                    }

                    // DECAY
                    if (this.decayLeft > 0)
                    {
                        int   dcrm    = Mathf.Min(this.decayLeft, size);
                        int   dcend   = start + dcrm;
                        float totalDc = this.decayTotal;
                        float cd      = this.decayLeft;
                        float susDiff = 1.0f - this.sustain;
                        for (int i = start; i < dcend; ++i)
                        {
                            data[i] = pfp[i] * (this.sustain + (cd / totalDc) * susDiff);
                            cd     -= 1.0f;
                        }

                        this.decayLeft -= dcrm;

                        size  -= dcrm;
                        start += dcrm;
                        if (size <= 0)
                        {
                            return;
                        }
                    }

                    // If we're still here, all that's left is sustain
                    for (int i = start; i < start + size; ++i)
                    {
                        data[i] = pfp[i] * this.sustain;
                    }
                }
            }