/// <summary> /// Method to handle user's selection in frequency domain /// passes selected samples to concolution filter. /// </summary> /// <param name="method"></param> public void filterSelectedFrequencies(FILTERING method = FILTERING.convolution) { if (freqSelStart == freqSelEnd) { return; } double[] filter = new double[fourierN]; for (int fbin = 0; fbin < filter.Length; fbin++) { if ((fbin >= freqSelStart && fbin <= freqSelEnd) || (fbin >= fourierN - freqSelEnd && fbin <= fourierN - freqSelStart)) { filter[fbin] = 0; } else { filter[fbin] = 1; } } double criticalPoint = 0; if (method == FILTERING.IIRLowpass) { criticalPoint = freqSelStart * SampleRate / fourierN; } else { criticalPoint = freqSelEnd * SampleRate / fourierN; } for (int channel = 0; channel < wave.channels; channel++) { switch (method) { case FILTERING.convolution: wave.samples[channel] = Formulas.convolveFilter(ref wave.samples[channel], filter); break; case FILTERING.DFT: wave.samples[channel] = Formulas.dftFilter(wave.samples[channel], filter); break; case FILTERING.IIRLowpass: //low pass wave.samples[channel] = Formulas.IIRFilter(wave.samples[channel], Math.Min(criticalPoint + 5000, SampleRate / 2), Math.Max(0, criticalPoint - 5000), 0, SampleRate); break; case FILTERING.IIRHighpass: //high pass wave.samples[channel] = Formulas.IIRFilter(wave.samples[channel], Math.Max(0, criticalPoint - 7000), Math.Min(criticalPoint + 3000, SampleRate / 2), 1, SampleRate); break; default: MessageBox.Show("Error occured"); break; } } timeDomain.setSamples(wave.samples); timeDomain.Invalidate(); calculateDFT(); invalidPlayer = true; }
/// <summary> /// Method to resample the sample set. /// Then goes through a lowpass filter /// </summary> /// <param name="samples">sample to be changed</param> /// <param name="originalRate">original samplerate</param> /// <param name="targetRate">target samplerate</param> /// <returns></returns> public static double[] resample(ref double[] samples, int originalRate, int targetRate) { double[] extendedSamples, result; int L, M; if (targetRate == originalRate) { return(samples); } else if (targetRate == 2 * originalRate) { L = 2; M = 1; } else if (targetRate == 4 * originalRate) { L = 4; M = 1; } else if (targetRate == 8 * originalRate) { L = 8; M = 1; } else if (targetRate * 2 == originalRate) { L = 1; M = 2; } else if (targetRate * 4 == originalRate) { L = 1; M = 4; } else if (targetRate * 8 == originalRate) { L = 1; M = 8; } else { return(null); } //used to pad 0's between samples extendedSamples = new double[samples.Length * L]; int i = 0; for (int s = 0; s < samples.Length; s++) { extendedSamples[i] = samples[s]; i++; for (int extra = 0; extra < L - 1; extra++) { extendedSamples[i] = 0; i++; } } //lowpass filter int S = Math.Min(originalRate, targetRate); extendedSamples = Formulas.IIRFilter(extendedSamples, S / 2 + 5000, S / 2 - 5000, 0, S * 2); //skips and select every Mth sample. result = new double[extendedSamples.Length / M]; i = 0; for (int s = 0; s < extendedSamples.Length; s += M) { try { result[i++] = extendedSamples[s]; } catch { } } return(result); }