コード例 #1
0
ファイル: SoundScript.cs プロジェクト: romanchom/Luna
        public SoundScript()
        {
            int count = LunaConnectionBase.ledCount;

            capture     = new AudioCapture(samplingRate, channelCount, 1 << windowSizePot);
            vizualizers = new SpectrumVizualizer[channelCount];
            for (int i = 0; i < channelCount; ++i)
            {
                vizualizers[i] = new SpectrumVizualizer(LunaConnectionBase.ledCount, lowFrequency, highFrequency, samplingRate);
            }


            sfftProcessor  = new FFTProcessor(10);
            sfftAggregator = new MelAggregator(count / 2, lowFrequency, highFrequency, sfftProcessor.WindowSize, samplingRate);
            beatDetector   = new NeuralBeatDetector();
        }
コード例 #2
0
        private static IEnumerable <Complex> ChirpFFT(float[] data, ChirpModel model, LocalRange range)
        {
            if (model == null)
            {
                return(null);
            }

            var fftComplex = new Complex[data.Length]; // the FFT function requires complex format

            for (int i = 0; i < fftComplex.Length; i++)
            {
                fftComplex[i] = new Complex(data[i], 0.0);// make it complex format (imaginary = 0)
            }

            return(FFTProcessor.ChirpTransform(fftComplex, range, model.SampleRate));
        }
コード例 #3
0
        private static Complex[] InternalFFT(float[] data)
        {
            var fftComplex = new Complex[data.Length];

            for (int i = 0; i < data.Length; i++)
            {
                fftComplex[i] = new Complex(data[i], 0.0);
            }
            FFTProcessor.Transform(fftComplex, false);
            //Accord.Math.FourierTransform.FFT(fftComplex, Accord.Math.FourierTransform.Direction.Forward);
            var n = data.Length;

            for (int i = 0; i < n; i++)  // Scaling (because this FFT implementation omits it)
            {
                fftComplex[i] /= n;
            }

            return(fftComplex);
        }
コード例 #4
0
ファイル: MEL.cs プロジェクト: 101010b/AudioProcessor2
            public melfilter(FFTProcessor fft, double f1, double fc, double f2)
            {
                double df = fft.freq[1];

                start  = (int)Math.Floor(f1 / df);
                stop   = (int)Math.Ceiling(f2 / df);
                coeffs = new double[stop - start + 1];
                double sum = 0;

                for (int i = start; i <= stop; i++)
                {
                    double c = 0;
                    double f = fft.freq[i];
                    if (f <= fc)
                    {
                        c = (f - f1) / (fc - f1);
                    }
                    else
                    {
                        c = 1.0 - (f - fc) / (f2 - fc);
                    }
                    if (c < 0)
                    {
                        c = 0;
                    }
                    if (c > 1.0)
                    {
                        c = 1.0;
                    }
                    coeffs[i - start] = c;
                    sum += c;
                }
                // Normalize bin widths
                for (int i = 0; i < coeffs.Length; i++)
                {
                    coeffs[i] /= sum;
                }
            }
コード例 #5
0
        public override void tick()
        {
            if (!_active)
            {
                return;
            }

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

            if (dbin == null)
            {
                return;
            }

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

            if (dbTrig != null)
            { // Triggered mode
                int trigger = -1;
                for (int i = 0; i < owner.blockSize; i++)
                {
                    if ((dbTrig.data[i] > 0) && (lastTrig <= 0))
                    {
                        trigger = i;
                    }
                    lastTrig = dbTrig.data[i];
                }
                if (trigger >= 0)
                {
                    // Triggered somewhere in this block
                    buffInFill = 0;
                }
            }
            if (buffInFill + owner.blockSize <= blockSize)
            {
                Array.Copy(dbin.data, 0, buffIn, buffInFill, owner.blockSize);
                buffInFill += owner.blockSize;
            }
            else
            {
                // Going to fill it
                int rem = blockSize - buffInFill;
                Array.Copy(dbin.data, 0, buffIn, buffInFill, rem);
                buffInFill += rem;
                processBlock(dbout);
                buffInFill = 0;
                Array.Copy(dbin.data, rem, buffIn, 0, owner.blockSize - rem);
                buffInFill += owner.blockSize - rem;
            }
        }
コード例 #6
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);
                }
            }
        }
コード例 #7
0
        public void initSpectrumAnalyzer(SpectrumAnalyzer _spectrumAnalyzer, int _channels, int _FIFOdepth)
        {
            inputs = new FIFO[_channels];
            for (int i = 0; i < _channels; i++)
            {
                inputs[i] = new FIFO(_FIFOdepth);
            }
            lines        = new SpectrumAnalyzerLine[_channels];
            inputsActive = new Boolean[_channels];
            inputData    = new double[_channels][];
            for (int i = 0; i < _channels; i++)
            {
                lines[i] = new SpectrumAnalyzerLine(spectrumAnalyzerScreen);
                switch (i % 4)
                {
                case 0: lines[i].color = Color.Red; break;

                case 1: lines[1].color = Color.Green; break;

                case 2: lines[2].color = Color.Cyan; break;

                case 3: lines[3].color = Color.Magenta; break;
                }
            }
            FIFOdepth        = _FIFOdepth;
            spectrumAnalyzer = _spectrumAnalyzer;
            timer.Interval   = 100; // ms
            timer.Tick      += Timer_Tick;

            _blockSize  = 4096;
            _windowType = FFTProcessor.WindowType.Hann;
            for (int i = 0; i < _channels; i++)
            {
                lines[i].acf = FFTProcessor.windowAmplitudeCorrectionFactorsdB[(int)_windowType];
            }

            fftProcessor = new FFTProcessor(_blockSize, spectrumAnalyzer.owner.sampleRate, _windowType);

            fftBlockSizes = new List <int>();
            for (int i = 64; i <= 8192; i *= 2)
            {
                SpectrumAnalyzerBlockSize.Items.Add(String.Format("{0} --> {1:f1}ms",
                                                                  i, 1000.0 * i / spectrumAnalyzer.owner.sampleRate));
                fftBlockSizes.Add(i);
            }
            SpectrumAnalyzerBlockSize.SelectedIndex         = fftBlockSizes.IndexOf(_blockSize);
            SpectrumAnalyzerBlockSize.SelectedIndexChanged += SpectrumAnalyzerBlockSize_SelectedIndexChanged;

            string[] windows = Enum.GetNames(typeof(FFTProcessor.WindowType));
            fftWindows = new List <FFTProcessor.WindowType>();
            for (int i = 0; i < windows.Length; i++)
            {
                fftWindows.Add((FFTProcessor.WindowType)i);
                SpectrumAnalyzerWindow.Items.Add(windows[i]);
            }
            SpectrumAnalyzerWindow.SelectedIndex         = fftWindows.IndexOf(_windowType);
            SpectrumAnalyzerWindow.SelectedIndexChanged += SpectrumAnalyzerWindow_SelectedIndexChanged;

            spectrumAnalyzerScreen.initSpectrumAnalyzerScreen(this, _channels, lines);

            if (spectrumAnalyzerScreen.gridF.logScale)
            {
                SpectrumAnalyzerFLog.Checked = true;
            }
            SpectrumAnalyzerFLog.Click += SpectrumAnalyzerFLog_Click;

            SpectrumAnalyzerFMin.Value = Convert.ToDecimal(spectrumAnalyzerScreen.gridF.min);
            SpectrumAnalyzerFMax.Value = Convert.ToDecimal(spectrumAnalyzerScreen.gridF.max);
            SpectrumAnalyzerYMin.Value = Convert.ToDecimal(spectrumAnalyzerScreen.gridY.min);
            SpectrumAnalyzerYMax.Value = Convert.ToDecimal(spectrumAnalyzerScreen.gridY.max);

            SpectrumAnalyzerFMin.ValueChanged += SpectrumAnalyzerFMin_ValueChanged;
            SpectrumAnalyzerFMax.ValueChanged += SpectrumAnalyzerFMax_ValueChanged;
            SpectrumAnalyzerYMin.ValueChanged += SpectrumAnalyzerYMin_ValueChanged;
            SpectrumAnalyzerYMax.ValueChanged += SpectrumAnalyzerYMax_ValueChanged;

            SpectrumAnalyzerAutoScale.Click += SpectrumAnalyzerAutoScale_Click;

            SpectrumAnalyzerChannelOnA.Checked = lines[0].show;
            SpectrumAnalyzerChannelOnB.Checked = lines[1].show;
            SpectrumAnalyzerChannelOnC.Checked = lines[2].show;
            SpectrumAnalyzerChannelOnD.Checked = lines[3].show;

            SpectrumAnalyzerChannelOnA.Click += SpectrumAnalyzerChannelOnA_Click;
            SpectrumAnalyzerChannelOnB.Click += SpectrumAnalyzerChannelOnB_Click;
            SpectrumAnalyzerChannelOnC.Click += SpectrumAnalyzerChannelOnC_Click;
            SpectrumAnalyzerChannelOnD.Click += SpectrumAnalyzerChannelOnD_Click;

            SpectrumAnalyzerPkHldA.Checked = lines[0].showMax;
            SpectrumAnalyzerPkHldB.Checked = lines[1].showMax;
            SpectrumAnalyzerPkHldC.Checked = lines[2].showMax;
            SpectrumAnalyzerPkHldD.Checked = lines[3].showMax;

            SpectrumAnalyzerPkHldA.Click += SpectrumAnalyzerPkHldA_Click;
            SpectrumAnalyzerPkHldB.Click += SpectrumAnalyzerPkHldB_Click;
            SpectrumAnalyzerPkHldC.Click += SpectrumAnalyzerPkHldC_Click;
            SpectrumAnalyzerPkHldD.Click += SpectrumAnalyzerPkHldD_Click;

            SpectrumAnalyzerAvgA.Checked = lines[0].showAvg;
            SpectrumAnalyzerAvgB.Checked = lines[1].showAvg;
            SpectrumAnalyzerAvgC.Checked = lines[2].showAvg;
            SpectrumAnalyzerAvgD.Checked = lines[3].showAvg;

            SpectrumAnalyzerAvgA.Click += SpectrumAnalyzerAvgA_Click;
            SpectrumAnalyzerAvgB.Click += SpectrumAnalyzerAvgB_Click;
            SpectrumAnalyzerAvgC.Click += SpectrumAnalyzerAvgC_Click;
            SpectrumAnalyzerAvgD.Click += SpectrumAnalyzerAvgD_Click;

            SpectrumAnalyzerSave.Click += SpectrumAnalyzerSave_Click;

            run = true;
            SpectrumAnalyzerRun.Checked = run;
            SpectrumAnalyzerRun.Click  += SpectrumAnalyzerRun_Click;

            showGrid = true;
            SpectrumAnalyzerGrid.Checked         = showGrid;
            spectrumAnalyzerScreen.drawGrid      = showGrid;
            SpectrumAnalyzerGrid.CheckedChanged += SpectrumAnalyzerGrid_CheckedChanged;

            channels      = _channels; // Triggers start
            timer.Enabled = true;
        }
コード例 #8
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]);
                }
            }
        }
コード例 #9
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);
                }
            }
        }
コード例 #10
0
        //int[] chunk_freq = { 10, 100, 2048};
        //int[] chunk_freq_jump = { 1, 10, 20};


        private double[] FFT(double[] lastData)
        {
            DateTime chkpoint1 = DateTime.Now;

            if (dataList == null)
            {
                return(null);
            }
            int actualN = distance2Node + 1;

            if (actualN < N_FFT)
            {
                return(new double[0]);
            }

            bool transformed = false;

            if (lastData == null || lastData.Length == 0)
            {
                lastData = new double[N_FFT];
            }
            else
            {
                transformed = true;
            }
            ComplexNumber[] data        = new ComplexNumber[N_FFT];
            var             runningNode = endingNode;

            for (int i = 0; i < N_FFT; i++)
            {
                data[i] = runningNode.Value;
                if (runningNode.PrevNode == null)
                {
                }
                runningNode = runningNode.PrevNode;
            }
            var    result = FFTProcessor.FFT(data);
            double N2     = result.Length / 2;

            double[] finalresult = new double[lastData.Length];
            int      k = 1, transformedDataIndex = 0;
            double   value = 0;

            double refFeq = 250;

            int i_ref = (int)(refFeq * N2 / 22050);

            for (int i = 0; i < N2; i += k)
            {
                value = 0;
                //k = i / i_ref;
                //k = k == 0 ? 1 : k;
                var mappedFreq = i * samplingFrequency / 2 / N2;
                for (int l = 0; l < chunk_freq.Length; l++)
                {
                    if (mappedFreq < chunk_freq[l] || l == chunk_freq.Length - 1)
                    {
                        k = chunk_freq_jump[l];//chunk_freq[l] / chunk_freq[0];
                        break;
                    }
                }

                for (int j = i; j < i + k && j < N2; j++)
                {
                    value += result[j].Manigtude;
                }


                value = value * MasterScaleFFT;
                lastData[transformedDataIndex] -= lastDelay * DropOffScale;
                if (Mode == 0)
                {
                    finalresult[transformedDataIndex] = value;
                }
                else
                {
                    finalresult[transformedDataIndex] = value > lastData[transformedDataIndex] ? value : lastData[transformedDataIndex];
                }
                transformedDataIndex++;
            }


            if (!transformed)
            {
                Array.Resize <double>(ref finalresult, transformedDataIndex);
            }


            DateTime chkpoint1_end = DateTime.Now;

            lastDelay = chkpoint1_end.Subtract(chkpoint1).TotalMilliseconds;
            osdPanel.AddSet("FFT delay(ms)", lastDelay.ToString());
            return(finalresult);
        }
コード例 #11
0
        public void initWaterfallSpectrum(WaterfallSpectrum _waterfallSpectrum)
        {
            FIFOdepth = 32768;
            input     = new FIFO(FIFOdepth);

            _blockSize        = 4096;
            _windowType       = FFTProcessor.WindowType.Hann;
            waterfallSpectrum = _waterfallSpectrum;

            timer.Interval = 50; // ms
            timer.Tick    += Timer_Tick;


            fftProcessor  = new FFTProcessor(_blockSize, waterfallSpectrum.owner.sampleRate, _windowType);
            fftBlockSizes = new List <int>();
            for (int i = 2048; i <= 8192; i *= 2)
            {
                waterfallSpectrumBlockSize.Items.Add(String.Format("{0} --> {1:f1}ms",
                                                                   i, 1000.0 * i / waterfallSpectrum.owner.sampleRate));
                fftBlockSizes.Add(i);
            }
            waterfallSpectrumBlockSize.SelectedIndex         = fftBlockSizes.IndexOf(_blockSize);
            waterfallSpectrumBlockSize.SelectedIndexChanged += waterfallSpectrumBlockSize_SelectedIndexChanged;

            string[] windows = Enum.GetNames(typeof(FFTProcessor.WindowType));
            fftWindows = new List <FFTProcessor.WindowType>();
            for (int i = 0; i < windows.Length; i++)
            {
                fftWindows.Add((FFTProcessor.WindowType)i);
                waterfallSpectrumWindow.Items.Add(windows[i]);
            }
            waterfallSpectrumWindow.SelectedIndex         = fftWindows.IndexOf(_windowType);
            waterfallSpectrumWindow.SelectedIndexChanged += waterfallSpectrumWindow_SelectedIndexChanged;

            waterfallSpectrumScreen.initWaterfallSpectrumScreen(this);

            double bst = (double)_blockSize / waterfallSpectrum.owner.sampleRate;

            waterfallSpectrumScreen.gridY.max = (waterfallSpectrumScreen.gridY.low - waterfallSpectrumScreen.gridY.high) * bst;

            if (waterfallSpectrumScreen.gridF.logScale)
            {
                waterfallSpectrumFLog.Checked = true;
            }
            waterfallSpectrumFLog.Click += waterfallSpectrumFLog_Click;

            waterfallSpectrumFMin.Value         = Convert.ToDecimal(waterfallSpectrumScreen.gridF.min);
            waterfallSpectrumFMax.Value         = Convert.ToDecimal(waterfallSpectrumScreen.gridF.max);
            waterfallSpectrumFMin.ValueChanged += WaterfallSpectrumFMin_ValueChanged;
            waterfallSpectrumFMax.ValueChanged += WaterfallSpectrumFMax_ValueChanged;

            waterfallSpectrumAutoScale.Click += WaterfallSpectrumAutoScale_Click;

            waterfallSpectrumShowGrid.Checked = waterfallSpectrumScreen.drawGrid;
            waterfallSpectrumShowGrid.Click  += WaterfallSpectrumShowGrid_Click;

            waterfallSpectrumRun.Click += WaterfallSpectrumRun_Click;

            waterfallSpectrumColorScheme.Items.Add("KrYW");
            waterfallSpectrumColorScheme.Items.Add("KbBW");
            waterfallSpectrumColorScheme.Items.Add("KrgBW");
            waterfallSpectrumColorScheme.Items.Add("KW");
            waterfallSpectrumColorScheme.Items.Add("KmryGCBW");
            waterfallSpectrumColorScheme.Text         = waterfallSpectrumScreen.colorTable.scheme;
            waterfallSpectrumColorScheme.TextChanged += WaterfallSpectrumColorScheme_TextChanged;

            waterfallLines = new WaterfallLineFIFO(waterfallSpectrumScreen, 1024, _blockSize / 2, waterfallSpectrum.owner.sampleRate / 2,
                                                   waterfallSpectrumScreen.Width, waterfallSpectrumScreen.Height);


            ready         = true;
            run           = true;
            timer.Enabled = true;
        }
コード例 #12
0
ファイル: ConnectionPage.xaml.cs プロジェクト: zjmoney/lights
        private async void Callback(Object state)
        {
            double redLowVolume   = 0;
            double greenLowVolume = 0;
            double blueLowVolume  = 0;

            double redHighVolume   = 0;
            double greenHighVolume = 0;
            double blueHighVolume  = 0;
            // Long running operation
            await FFTProcessor.ControlLightStrip((double[])echoProperties["Data"]);

            var data = echoProperties["Data"] as double[];

            double lowRangeVal = 1, highRangeVal = 1;

            for (int i = 2; i < data.Length / 5; i++)
            {
                lowRangeVal += Math.Abs(data[i]);
            }
            for (int j = 0; j < data.Length / 3 / 3 + 15; j++)
            {
                redLowVolume += Math.Abs(data[j]);
            }
            for (int j = data.Length / 3 / 3; j < 2 * (data.Length / 3 / 3) + 15; j++)
            {
                greenLowVolume += Math.Abs(data[j]);
            }
            for (int j = 2 * (data.Length / 3 / 3); j < data.Length / 3 - 10; j++)
            {
                blueLowVolume += Math.Abs(data[j]);
            }



            for (int i = (4 * data.Length) / 5; i < data.Length; i++)
            {
                highRangeVal += Math.Abs(data[i]);
            }

            for (int j = (2 * data.Length) / 3 - 20; j < ((2 * data.Length) / 3) + (3 / 18) * data.Length + 10; j++)
            {
                redHighVolume += Math.Abs(data[j]);
            }
            for (int j = ((2 * data.Length) / 3) + (1 / 9) * data.Length - 20; j < ((2 * data.Length) / 3) + (5 / 18) * data.Length + 10; j++)
            {
                greenHighVolume += Math.Abs(data[j]);
            }
            for (int j = ((2 * data.Length) / 3) + (2 / 9) * data.Length; j < data.Length; j++)
            {
                blueHighVolume += Math.Abs(data[j]);
            }

            maxLowVolume  = Math.Max(maxLowVolume, lowRangeVal);
            maxHighVolume = Math.Max(maxHighVolume, highRangeVal);


            redLowVolume   = 6 * redLowVolume > 255 ? 255 : 6 * redLowVolume;
            greenLowVolume = 6 * greenLowVolume > 255 ? 255 : 6 * greenLowVolume;
            blueLowVolume  = 5 * blueLowVolume > 255 ? 255 : 5 * blueLowVolume;

            redHighVolume   = 9 * redHighVolume > 255 ? 255 : 9 * redHighVolume;
            greenHighVolume = 9 * greenHighVolume > 255 ? 255 : 9 * greenHighVolume;
            blueHighVolume  = 6 * blueHighVolume > 255 ? 255 : 4 * blueHighVolume;

            // Lowers other volumes
            double maxColor = Math.Max(Math.Max(redLowVolume, greenLowVolume), blueLowVolume);

            if (Math.Abs(maxColor - redLowVolume) > 0.0001)
            {
                redLowVolume *= 1.2;

                blueLowVolume  *= 0.3;
                greenLowVolume *= 0.3;
            }
            else if (Math.Abs(maxColor - greenLowVolume) > 0.0001)
            {
                greenLowVolume *= 1.2;
                blueLowVolume  *= 0.3;
                redLowVolume   *= 0.3;
            }
            else if (Math.Abs(maxColor - blueLowVolume) > 0.0001)
            {
                blueLowVolume  *= 1.1;
                redLowVolume   *= 0.3;
                greenLowVolume *= 0.3;
            }

            redHighVolume   = rand.NextDouble() * 255;
            greenHighVolume = 255 - redHighVolume;
            // Lowers other volumes
            double maxColorHigh = Math.Max(Math.Max(redHighVolume, greenHighVolume), blueHighVolume);

            if (Math.Abs(maxColorHigh - redHighVolume) > 0.0001)
            {
                redHighVolume   += 20;
                blueHighVolume  *= 0.3;
                greenHighVolume *= 0.1;
            }
            else if (Math.Abs(maxColorHigh - greenHighVolume) > 0.0001)
            {
                greenHighVolume += 20;
                blueHighVolume  *= 0.5;
                redHighVolume   *= 0.1;
            }
            else if (Math.Abs(maxColorHigh - blueHighVolume) > 0.0001)
            {
                blueHighVolume  *= 5.0;
                redHighVolume   *= 0.2;
                greenHighVolume *= 0.5;
            }

            SetPixelRange(15 - (int)(lowRangeVal / maxLowVolume * 15), 15, redLowVolume, greenLowVolume, blueLowVolume);
            SetPixelRange(0, 15 - (int)(lowRangeVal / maxLowVolume * 15), 0, 0, 0);

            SetPixelRange(15, 15 + (int)(highRangeVal / maxHighVolume * 15), redHighVolume, greenHighVolume, blueHighVolume);
            SetPixelRange(15 + (int)(highRangeVal / maxHighVolume * 15), 30, 0, 0, 0);

            UpdateStrip();
            audioTimer.Change(50, 0);
        }
コード例 #13
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);
                }
            }
        }
コード例 #14
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;
                    }
                }
            }
        }