コード例 #1
0
        private void processBlock(DataBuffer dbout)
        {
            if (buffInFill == blockSize)
            {
                if (fft == null)
                {
                    fft = new FFTProcessor(FFTProcessor.ProcessorMode.Bidirectional, blockSize, owner.sampleRate, fftWindow);
                }

                if (fftWindow != fft.windowType)
                {
                    fft.windowType = fftWindow;
                }

                fft.runFFT(ref buffIn, true, ref re, ref im);
                Array.Copy(buffIn, blockSize / 2, buffIn, 0, buffInFill - blockSize / 2);
                buffInFill -= blockSize / 2;

                // Process FFT Data
                if (normalize || (mode == FFTOutMode.Phase) || (mode == FFTOutMode.Sig) || (mode == FFTOutMode.SigPhase))
                {
                    // Must calculate Energy
                    if ((energy == null) || (energy.Length != re.Length))
                    {
                        energy = new double[re.Length];
                    }
                    for (int i = 0; i < re.Length; i++)
                    {
                        energy[i] = re[i] * re[i] + im[i] * im[i];
                    }
                    emax = energy[0];
                    rmax = re[0];
                    imax = im[0];
                    for (int i = 1; i < re.Length; i++)
                    {
                        if (energy[i] > emax)
                        {
                            emax = energy[i];
                        }
                        if (re[i] > rmax)
                        {
                            rmax = re[i];
                        }
                        if (im[i] > imax)
                        {
                            imax = im[i];
                        }
                        if (re[i] < -rmax)
                        {
                            rmax = -re[i];
                        }
                        if (im[i] < -imax)
                        {
                            imax = -im[i];
                        }
                    }
                }
                switch (mode)
                {
                case FFTOutMode.ReIm:
                    if ((outArray == null) || (outArray.Length != 2 * re.Length))
                    {
                        outArray = new double[2 * re.Length];
                    }
                    if (normalize)
                    {
                        double sf = 1;
                        if (emax > 0)
                        {
                            sf = 1.0 / Math.Sqrt(emax);
                        }
                        for (int i = 0; i < re.Length; i++)
                        {
                            outArray[2 * i]     = re[i] * sf;
                            outArray[2 * i + 1] = im[i] * sf;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < re.Length; i++)
                        {
                            outArray[2 * i]     = re[i];
                            outArray[2 * i + 1] = im[i];
                        }
                    }
                    break;

                case FFTOutMode.Re:
                case FFTOutMode.Im:
                    if ((outArray == null) || (outArray.Length != re.Length))
                    {
                        outArray = new double[re.Length];
                    }
                    if (normalize)
                    {
                        double sf = 1;
                        if (mode == FFTOutMode.Re)
                        {
                            if (rmax > 0)
                            {
                                sf = 1 / rmax;
                            }
                            for (int i = 0; i < re.Length; i++)
                            {
                                outArray[i] = re[i] * sf;
                            }
                        }
                        else
                        {
                            if (imax > 0)
                            {
                                sf = 1 / imax;
                            }
                            for (int i = 0; i < re.Length; i++)
                            {
                                outArray[i] = im[i] * sf;
                            }
                        }
                    }
                    else
                    {
                        if (mode == FFTOutMode.Re)
                        {
                            Array.Copy(re, outArray, re.Length);
                        }
                        else
                        {
                            Array.Copy(im, outArray, re.Length);
                        }
                    }
                    break;

                case FFTOutMode.Phase:
                    if ((outArray == null) || (outArray.Length != re.Length))
                    {
                        outArray = new double[re.Length];
                    }
                    for (int i = 0; i < re.Length; i++)
                    {
                        outArray[i] = Math.Atan2(im[i], re[i]);
                    }
                    break;

                case FFTOutMode.Sig:
                    if ((outArray == null) || (outArray.Length != re.Length))
                    {
                        outArray = new double[re.Length];
                    }
                    if (normalize)
                    {
                        double sf = 1;
                        if (emax > 0)
                        {
                            sf = 1.0 / Math.Sqrt(emax);
                        }
                        for (int i = 0; i < re.Length; i++)
                        {
                            outArray[i] = Math.Sqrt(energy[i]) * sf;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < re.Length; i++)
                        {
                            outArray[i] = Math.Sqrt(energy[i]);
                        }
                    }
                    break;

                case FFTOutMode.SigPhase:
                    if ((outArray == null) || (outArray.Length != 2 * re.Length))
                    {
                        outArray = new double[2 * re.Length];
                    }
                    if (normalize)
                    {
                        double sf = 1;
                        if (emax > 0)
                        {
                            sf = 1.0 / Math.Sqrt(emax);
                        }
                        for (int i = 0; i < re.Length; i++)
                        {
                            outArray[2 * i]     = Math.Sqrt(energy[i]) * sf;
                            outArray[2 * i + 1] = Math.Atan2(im[i], re[i]);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < re.Length; i++)
                        {
                            outArray[2 * i]     = Math.Sqrt(energy[i]);
                            outArray[2 * i + 1] = Math.Atan2(im[i], re[i]);
                        }
                    }
                    break;
                }
                if (dbout != null)
                {
                    dbout.initialize(outArray.Length);
                    dbout.set(outArray);
                }
            }
        }
コード例 #2
0
        public override void tick()
        {
            if (!_active)
            {
                return;
            }

            SignalBuffer dbin = getSignalInputBuffer(ioI);

            SignalBuffer[] dbout = new SignalBuffer[7];
            dbout[0] = getSignalOutputBuffer(ioM3);
            dbout[1] = getSignalOutputBuffer(ioM2);
            dbout[2] = getSignalOutputBuffer(ioM1);
            dbout[3] = getSignalOutputBuffer(io0);
            dbout[4] = getSignalOutputBuffer(ioP1);
            dbout[5] = getSignalOutputBuffer(ioP2);
            dbout[6] = getSignalOutputBuffer(ioP3);

            if (dbin == null)
            {
                return;
            }

            if (oval == null)
            {
                oval = new double[7];
            }

            if (buffIn == null)
            {
                buffIn     = new double[blockSize];
                re         = new double[blockSize / 2];
                im         = new double[blockSize / 2];
                buffInFill = 0;
            }

            Array.Copy(dbin.data, 0, buffIn, buffInFill, owner.blockSize);
            buffInFill += owner.blockSize;

            if (buffInFill == blockSize)
            {
                if (fft == null)
                {
                    fft = new FFTProcessor(FFTProcessor.ProcessorMode.Bidirectional, blockSize, owner.sampleRate, fftWindow);
                }
                n = (int)Math.Floor((double)blockSize * f / (owner.sampleRate));
                fft.windowType = fftWindow;

                fft.runFFT(ref buffIn, true, ref re, ref im);
                Array.Copy(buffIn, blockSize / 2, buffIn, 0, buffInFill - blockSize / 2);
                buffInFill -= blockSize / 2;

                // Process FFT
                for (int i = -3; i <= 3; i++)
                {
                    int m = n + i;
                    oval[i + 3] = 0;
                    if ((m >= 0) && (m < blockSize / 2))
                    {
                        oval[i + 3] = Math.Sqrt(re[m] * re[m] + im[m] * im[m]);
                    }
                }
            }

            for (int i = -3; i <= 3; i++)
            {
                if (dbout[i + 3] != null)
                {
                    dbout[i + 3].SetTo(oval[i + 3]);
                }
            }
        }
コード例 #3
0
ファイル: MEL.cs プロジェクト: 101010b/AudioProcessor2
        public override void tick()
        {
            if (!_active)
            {
                return;
            }

            SignalBuffer dbin  = getSignalInputBuffer(ioI);
            DataBuffer   dbout = getDataOutputBuffer(ioData);

            if (dbin == null)
            {
                return;
            }

            if (oval == null)
            {
                oval = new double[7];
            }

            if ((buffIn == null) || (buffIn.Length != blockSize))
            {
                buffIn     = new double[blockSize];
                re         = new double[blockSize / 2];
                im         = new double[blockSize / 2];
                energy     = new double[blockSize / 2];
                buffInFill = 0;
                fft        = null;
                addto      = null;
            }
            if ((fft != null) && (fft.windowType != fftWindow))
            {
                fft = new FFTProcessor(FFTProcessor.ProcessorMode.Bidirectional, blockSize, owner.sampleRate, fftWindow);
            }


            Array.Copy(dbin.data, 0, buffIn, buffInFill, owner.blockSize);
            buffInFill += owner.blockSize;

            if (buffInFill == blockSize)
            {
                if (fft == null)
                {
                    fft = new FFTProcessor(FFTProcessor.ProcessorMode.Bidirectional, blockSize, owner.sampleRate, fftWindow);
                }
                if ((addto == null) || (fA != fA0) || (fMax != fMax0) || (coeffs != coeffs0))
                {
                    fA0     = fA;
                    fMax0   = fMax;
                    coeffs0 = coeffs;
                    double   melA       = 1125.0 * Math.Log(1 + fA / 700.0);
                    double   melMax     = 1125.0 * Math.Log(1 + fMax / 700.0);
                    double[] centermels = new double[coeffs + 2];

                    for (int i = 0; i < coeffs + 2; i++)
                    {
                        double melf = melA + (i - 1) * (melMax - melA) / (coeffs - 1);
                        centermels[i] = 700.0 * (Math.Exp(melf / 1125.0) - 1);
                    }
                    melfilterbank = new melfilter[coeffs];
                    for (int i = 0; i < coeffs; i++)
                    {
                        melfilterbank[i] = new melfilter(fft, centermels[i], centermels[i + 1], centermels[i + 2]);
                    }

                    mels = new double[coeffs];
                }

                // n = (int)Math.Floor((double)blockSize * fA / (owner.sampleRate));
                fft.windowType = fftWindow;

                fft.runFFT(ref buffIn, true, ref re, ref im);
                Array.Copy(buffIn, blockSize / 2, buffIn, 0, buffInFill - blockSize / 2);
                buffInFill -= blockSize / 2;

                // Process FFT Data
                for (int i = 0; i < re.Length; i++)
                {
                    energy[i] = re[i] * re[i] + im[i] * im[i];
                }

                for (int i = 0; i < coeffs; i++)
                {
                    mels[i] = melfilterbank[i].calc(ref energy);
                }


                if (normalize)
                {
                    double max = Math.Abs(mels[0]);
                    for (int i = 1; i < coeffs; i++)
                    {
                        double ax = Math.Abs(mels[i]);
                        if (ax > max)
                        {
                            max = ax;
                        }
                    }
                    if (max == 0)
                    {
                        max = 1;
                    }
                    for (int i = 0; i < coeffs; i++)
                    {
                        mels[i] = mels[i] / max;
                    }
                }

                if (dbout != null)
                {
                    dbout.initialize(coeffs);
                    dbout.set(mels);
                }
            }
        }
コード例 #4
0
        public override void tick()
        {
            if (!_active)
            {
                return;
            }

            SignalBuffer dbin  = getSignalInputBuffer(ioI);
            DataBuffer   dbout = getDataOutputBuffer(ioData);

            if (dbin == null)
            {
                return;
            }

            if (oval == null)
            {
                oval = new double[7];
            }

            if ((buffIn == null) || (buffIn.Length != blockSize))
            {
                buffIn     = new double[blockSize];
                re         = new double[blockSize / 2];
                im         = new double[blockSize / 2];
                buffInFill = 0;
                fft        = null;
                addto      = null;
            }
            if ((fft != null) && (fft.windowType != fftWindow))
            {
                fft = new FFTProcessor(FFTProcessor.ProcessorMode.Bidirectional, blockSize, owner.sampleRate, fftWindow);
            }


            Array.Copy(dbin.data, 0, buffIn, buffInFill, owner.blockSize);
            buffInFill += owner.blockSize;

            if (buffInFill == blockSize)
            {
                if (fft == null)
                {
                    fft = new FFTProcessor(FFTProcessor.ProcessorMode.Bidirectional, blockSize, owner.sampleRate, fftWindow);
                }
                if ((addto == null) || (fA != fA0) || (fMax != fMax0))
                {
                    fA0   = fA;
                    fMax0 = fMax;
                    double fC = fA * Math.Pow(2, -9.0 / 12.0);
                    addto      = new int[blockSize / 2];
                    addtoCoeff = new double[blockSize / 2];
                    for (int i = 0; i < blockSize / 2; i++)
                    {
                        double f      = fft.freq[i];
                        double weight = bandPass(f, fC, fMax);
                        if (weight < 0.1)
                        {
                            addto[i] = -1;
                        }
                        else
                        {
                            int fn = (int)Math.Floor(Math.Log(f / fC, 2.0) * 12 + 0.5);
                            addto[i]      = fn % 12;
                            addtoCoeff[i] = weight;
                        }
                    }
                }

                // n = (int)Math.Floor((double)blockSize * fA / (owner.sampleRate));
                fft.windowType = fftWindow;

                fft.runFFT(ref buffIn, true, ref re, ref im);
                Array.Copy(buffIn, blockSize / 2, buffIn, 0, buffInFill - blockSize / 2);
                buffInFill -= blockSize / 2;

                // Process FFT Data
                //double[] on = new double[12];
                for (int i = 0; i < 12; i++)
                {
                    on[i] = 0;
                }
                double[] n = new double[12];
                for (int i = 0; i < addto.Length; i++)
                {
                    if (addto[i] >= 0)
                    {
                        on[addto[i]] += addtoCoeff[i] * (re[i] * re[i] + im[i] * im[i]);
                        n[addto[i]]  += addtoCoeff[i];
                    }
                }
                double emax = 0;
                double emin = 0;
                for (int i = 0; i < 12; i++)
                {
                    on[i] = Math.Sqrt(on[i] / n[i]);
                    if (i == 0)
                    {
                        emin = emax = on[i];
                    }
                    else
                    {
                        if (on[i] < emin)
                        {
                            emin = on[i];
                        }
                        if (on[i] > emax)
                        {
                            emax = on[i];
                        }
                    }
                }
                if (normalize)
                {
                    if (emax == emin)
                    {
                        emax = emin + 1;
                    }
                    for (int i = 0; i < 12; i++)
                    {
                        on[i] = (on[i] - emin) / (emax - emin);
                    }
                }
                else
                {
                    double[] onLog = new double[12];
                    for (int i = 0; i < 12; i++)
                    {
                        if (on[i] < 1e-5)
                        {
                            onLog[i] = -100;
                        }
                        else if (on[i] > 1e1)
                        {
                            onLog[i] = 20;
                        }
                        else
                        {
                            onLog[i] = 20 * Math.Log10(on[i]);
                        }
                        onLog[i] = (onLog[i] - (-100)) / (20 - (-100));
                    }
                }
                if (dbout != null)
                {
                    dbout.initialize(12);
                    dbout.set(on);
                }
            }
        }
コード例 #5
0
        public override void tick()
        {
            if (fft == null)
            {
                fft = new FFTProcessor(FFTProcessor.ProcessorMode.Bidirectional, blockSize, owner.sampleRate, FFTProcessor.WindowType.Hann);
            }

            SignalBuffer dbout = getSignalOutputBuffer(ioO);
            SignalBuffer dbin  = getSignalInputBuffer(ioI);

            if (!_active)
            {
                return;
            }

            if ((dbout == null) && (dbin == null))
            {
                return;
            }

            if (buffIn == null)
            {
                buffIn  = new double[blockSize];
                buffOut = new double[blockSize];
                fftOut  = new double[blockSize];
                re      = new double[blockSize / 2];
                im      = new double[blockSize / 2];

                buffInFill  = 0;
                buffOutFill = 0;
                buffOutRead = 0;
            }

            if (dbin != null)
            {
                Array.Copy(dbin.data, 0, buffIn, buffInFill, owner.blockSize);
                buffInFill += owner.blockSize;

                if (buffInFill == blockSize)
                {
                    fft.runFFT(ref buffIn, true, ref re, ref im);
                    Array.Copy(buffIn, blockSize / 2, buffIn, 0, buffInFill - blockSize / 2);
                    buffInFill -= blockSize / 2;
                    // Process FFT
                    int    n1, n2;
                    double s, c;
                    switch (filterMode)
                    {
                    case FFTFilterMode.LowPass:
                        n1 = (int)Math.Floor(f1 / (double)owner.sampleRate * blockSize);
                        if (n1 < 0)
                        {
                            n1 = 0;
                        }
                        for (int i = n1; i < blockSize / 2; i++)
                        {
                            re[i] = im[i] = 0;
                        }
                        break;

                    case FFTFilterMode.HighPass:
                        n1 = (int)Math.Ceiling(f1 / (double)owner.sampleRate * blockSize);
                        if (n1 >= blockSize / 2)
                        {
                            n1 = blockSize / 2 - 1;
                        }
                        for (int i = 0; i < n1; i++)
                        {
                            re[i] = im[i] = 0;
                        }
                        break;

                    case FFTFilterMode.BandPass:
                        n1 = (int)Math.Floor(f1 / (double)owner.sampleRate * blockSize);
                        n2 = (int)Math.Ceiling(f2 / (double)owner.sampleRate * blockSize);
                        if (n1 < 0)
                        {
                            n1 = 0;
                        }
                        if (n2 >= blockSize / 2)
                        {
                            n2 = blockSize / 2 - 1;
                        }
                        for (int i = 0; i < n1; i++)
                        {
                            re[i] = im[i] = 0;
                        }
                        for (int i = n2 + 1; i < blockSize / 2; i++)
                        {
                            re[i] = im[i] = 0;
                        }
                        break;

                    case FFTFilterMode.BandStop:
                        n1 = (int)Math.Floor(f1 / (double)owner.sampleRate * blockSize);
                        n2 = (int)Math.Ceiling(f2 / (double)owner.sampleRate * blockSize);
                        if (n1 < 0)
                        {
                            n1 = 0;
                        }
                        if (n2 >= blockSize / 2)
                        {
                            n2 = blockSize / 2 - 1;
                        }
                        for (int i = n1 + 1; i < n2; i++)
                        {
                            re[i] = im[i] = 0;
                        }
                        break;

                    case FFTFilterMode.AllPass:
                        s = Math.Sin(phi);
                        c = Math.Cos(phi);
                        for (int i = 1; i < blockSize / 2; i++)
                        {
                            double _re = re[i] * c - im[i] * s;
                            double _im = re[i] * s + im[i] * c;
                            re[i] = _re;
                            im[i] = _im;
                        }
                        break;

                    case FFTFilterMode.FrequencyShifter:
                        n1 = (int)Math.Floor(f1 / (double)owner.sampleRate * blockSize + 0.5);
                        if (n1 > 0)
                        {                                                             // positive shift
                            double df = (double)owner.sampleRate / (double)blockSize; // Bin Spacing
                            Array.Copy(re, 1, re, 1 + n1, blockSize / 2 - 1 - n1);
                            Array.Copy(im, 1, im, 1 + n1, blockSize / 2 - 1 - n1);
                            Array.Clear(re, 1, n1);
                            Array.Clear(im, 1, n1);
                            for (int i = 1 + n1; i < blockSize / 2; i++)
                            {
                                double T    = 1.0 / i / df;
                                double T2   = 1.0 / (i + n1) / df;
                                double dphi = -2.0 * Math.PI * (T - T2) * (i + n1) * df;
                                s = Math.Sin(dphi);
                                c = Math.Cos(dphi);
                                double _re = re[i] * c - im[i] * s;
                                double _im = re[i] * s + im[i] * c;
                                re[i] = _re;
                                im[i] = _im;
                            }
                        }
                        if (n1 < 0)
                        {
                            n1 = -n1;
                            Array.Copy(re, n1 + 1, re, 1, blockSize / 2 - n1 - 1);
                            Array.Copy(im, n1 + 1, im, 1, blockSize / 2 - n1 - 1);
                            Array.Clear(re, blockSize / 2 - 1 - n1, n1);
                            Array.Clear(im, blockSize / 2 - 1 - n1, n1);
                        }
                        break;
                    }

                    // Transfer Back
                    fft.runIFFT(ref re, ref im, ref fftOut);
                    Array.Copy(buffOut, blockSize / 2, buffOut, 0, blockSize / 2);
                    Array.Clear(buffOut, blockSize / 2, blockSize / 2);
                    for (int i = 0; i < blockSize; i++)
                    {
                        buffOut[i] += fftOut[i];
                    }
                    buffOutFill = blockSize / 2;
                    buffOutRead = 0;
                }
                if (buffOutFill > 0)
                {
                    if (dbout != null)
                    {
                        Array.Copy(buffOut, buffOutRead, dbout.data, 0, owner.blockSize);
                        buffOutRead += owner.blockSize;
                    }
                }
            }
        }