/// <summary>Single thread DFT function.</summary> /// <param name="start">The start index in the samples array.</param> /// <param name="end">The end index in the samples array.</param> private void dftSingle(long start, long end) { long N = end - start; fourierSamples = new ComplexNum[N]; applyWindowing(start, N); for (long f = 0; f < N; f++) { fourierSamples[f] = new ComplexNum(); for (int t = 0; t < N; t++) { fourierSamples[f].Re += windowingSamples[t] * Math.Cos((2 * Math.PI * t * f) / N); fourierSamples[f].Im -= windowingSamples[t] * Math.Sin((2 * Math.PI * t * f) / N); } if (Math.Abs(fourierSamples[f].Re) < zeroThreshold) { fourierSamples[f].Re = 0.0; } if (Math.Abs(fourierSamples[f].Im) < zeroThreshold) { fourierSamples[f].Im = 0.0; } } }
/// <summary>Generates a filter to filter out aliases for upsampling/downsampling.</summary> /// <param name="newSampleRate">The new sample rate to determine the nyquist limit.</param> /// <param name="csData">The sample data.</param> /// <returns>ComplexNum array representing the filter.</returns> private ComplexNum[] genSampleFilter(int newSampleRate, ClipboardData csData) { ComplexNum[] filter = new ComplexNum[csData.Cs.Length / 10]; int freq = newSampleRate / 2; int bin = (freq * filter.Length) / newSampleRate; for (int i = 0; i < filter.Length; ++i) { filter[i] = new ComplexNum(); if (i <= bin) { filter[i].Re = 1.0; filter[i].Im = 1.0; } else { filter[i].Re = 0.0; filter[i].Im = 0.0; } } return(filter); }
/// <summary>Thread proc for multithread DFT</summary> /// <param name="threadIndex">Index of the thread.</param> /// <param name="startRawSamples">The start index in the raw samples array.</param> /// <param name="N">The total number of samples with which DFT is being applied to.</param> /// <param name="chunkSize">Size of this threads chunk.</param> private void dftThreadProc(int threadIndex, long startRawSamples, long N, long chunkSize) { ComplexNum[] dftSamples = new ComplexNum[chunkSize]; for (long f = 0; f < chunkSize; f++) { dftSamples[f] = new ComplexNum(); for (int t = 0; t < N; t++) { dftSamples[f].Re += windowingSamples[t] * Math.Cos((2 * Math.PI * t * (f + (threadIndex * chunkSize))) / N); dftSamples[f].Im -= windowingSamples[t] * Math.Sin((2 * Math.PI * t * (f + (threadIndex * chunkSize))) / N); } if (Math.Abs(dftSamples[f].Re) < zeroThreshold) { dftSamples[f].Re = 0.0; } if (Math.Abs(dftSamples[f].Im) < zeroThreshold) { dftSamples[f].Im = 0.0; } } dftThreadSamples[threadIndex] = dftSamples; }