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(); }
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)); }
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); }
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; } }
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; } }
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); } } }
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; }
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]); } } }
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); } } }
//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); }
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; }
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); }
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); } } }
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; } } } }