/// <summary> /// Frequency domain convolution. /// </summary> /// <param name="SignalBuffer">the dry signal.</param> /// <param name="Filter">the pressure domain impulse response.</param> /// <returns>the convolved signal.</returns> public static float[] FFT_Convolution(double[] SignalBuffer, double[] Filter, int threadid) { if (SignalBuffer == null) { return(null); } int minlength = SignalBuffer.Length > Filter.Length ? SignalBuffer.Length : Filter.Length; int W = (int)Math.Pow(2, Math.Ceiling(Math.Log(minlength, 2))); if (SignalBuffer.Length < W) { Array.Resize(ref SignalBuffer, W); } if (Filter.Length < W) { Array.Resize(ref Filter, W); } MathNet.Numerics.Complex[] freq1 = FFT_General(SignalBuffer, threadid); MathNet.Numerics.Complex[] freq2 = FFT_General(Filter, threadid); MathNet.Numerics.Complex[] freq3 = new MathNet.Numerics.Complex[W]; for (int i = 0; i < freq1.Length; i++) { freq3[i] = freq1[i] * freq2[i]; } double[] conv = IFFT_Real_General(freq3, threadid); float[] output = new float[conv.Length]; double mod = 1d / Math.Sqrt(conv.Length); for (int i = 0; i < conv.Length; i++) { output[i] = (float)(conv[i] * mod); // * mod); } double maxfilt = Filter[0]; double maxsig = SignalBuffer[0]; double max = conv[0]; for (int i = 1; i < Filter.Length; i++) { Math.Max(maxfilt, Filter[i]); } for (int i = 1; i < SignalBuffer.Length; i++) { Math.Max(maxsig, SignalBuffer[i]); } for (int i = 1; i < conv.Length; i++) { Math.Max(max, conv[i]); } max++; maxsig++; maxfilt++; return(output); }
public static MathNet.Numerics.Complex[] Minimum_Phase_TF_Octaves(double[] Octave_filter, int sample_frequency, int length_starttofinish, int threadid) { double[] M_spec = Magnitude_Filter(Octave_filter, sample_frequency, length_starttofinish, threadid); MathNet.Numerics.Complex[] logspec = new MathNet.Numerics.Complex[M_spec.Length]; for (int i = 0; i < M_spec.Length; i++) { logspec[i] = Math.Log(M_spec[i]); } double[] real_cepstrum = IFFT_Real_General(Mirror_Spectrum(logspec), threadid); Scale(ref real_cepstrum); double[] ym = new double[length_starttofinish]; ym[0] = real_cepstrum[0]; for (int i = 1; i < length_starttofinish / 2; i++) { ym[i] = 2 * real_cepstrum[i]; } ym[length_starttofinish / 2] = real_cepstrum[length_starttofinish / 2]; MathNet.Numerics.Complex[] ymspec = FFT_General(ym, threadid); for (int i = 0; i < ymspec.Length; i++) { ymspec[i] = (ymspec[i]).Exponential(); } return(ymspec); }
public static MathNet.Numerics.Complex[] Minimum_Phase_TF(double[] M_spec, int sample_frequency, int threadid) { MathNet.Numerics.Complex[] logspec = new MathNet.Numerics.Complex[M_spec.Length]; for (int i = 0; i < M_spec.Length; i++) { logspec[i] = Math.Log(M_spec[i]); } double[] real_cepstrum = IFFT_Real_General(Mirror_Spectrum(logspec), threadid); Scale(ref real_cepstrum); double[] ym = new double[real_cepstrum.Length]; ym[0] = real_cepstrum[0]; for (int i = 1; i < M_spec.Length; i++) { ym[i] = 2 * real_cepstrum[i]; } ym[M_spec.Length] = real_cepstrum[M_spec.Length]; MathNet.Numerics.Complex[] ymspec = FFT_General(ym, threadid); for (int i = 0; i < ymspec.Length; i++) { ymspec[i] = (ymspec[i]).Exponential(); } return(ymspec); }
public override MathNet.Numerics.Complex Reflection_Narrow(double frequency) { MathNet.Numerics.Complex alpha = 0; for (int a = 0; a < Transfer_FunctionR.Length; a++) { alpha += new MathNet.Numerics.Complex(Transfer_FunctionR[a].Interpolate(frequency), Transfer_FunctionI[a].Interpolate(frequency)); } alpha /= Transfer_FunctionR.Length; return(alpha); }
public override MathNet.Numerics.Complex[] Reflection_Spectrum(int sample_frequency, int length, Hare.Geometry.Vector Normal, Hare.Geometry.Vector Dir, int threadid) { MathNet.Numerics.Complex[] Ref_trns = new MathNet.Numerics.Complex[length]; for (int j = 0; j < length; j++) { Ref_trns[j] = new MathNet.Numerics.Complex(Transfer_Function.Interpolate(j * (sample_frequency / 2) / length), 0); } return(Ref_trns); }
public static double[] Minimum_Phase_Signal(double[] Octave_pressure, int sample_frequency, int length_starttofinish, int threadid) { double[] M_spec = Magnitude_Spectrum(Octave_pressure, sample_frequency, length_starttofinish, threadid); double sum_start = 0; for (int i = 0; i < M_spec.Length; i++) { sum_start += M_spec[i] * M_spec[i]; } MathNet.Numerics.Complex[] logspec = new MathNet.Numerics.Complex[M_spec.Length]; for (int i = 0; i < M_spec.Length; i++) { logspec[i] = Math.Log(M_spec[i]); } double[] real_cepstrum = IFFT_Real_General(Mirror_Spectrum(logspec), threadid); Scale(ref real_cepstrum); double[] ym = new double[length_starttofinish]; ym[0] = real_cepstrum[0]; for (int i = 1; i < length_starttofinish / 2; i++) { ym[i] = 2 * real_cepstrum[i]; } ym[length_starttofinish / 2] = real_cepstrum[length_starttofinish / 2]; MathNet.Numerics.Complex[] ymspec = FFT_General(ym, threadid); for (int i = 0; i < ymspec.Length; i++) { ymspec[i] = (ymspec[i]).Exponential(); } double[] Signal = IFFT_Real_General(ymspec, threadid); //This is real valued hopefully... (if not there is a problem...) for (int i = 0; i < Signal.Length; i++) { Signal[i] /= Math.Sqrt(Signal.Length); } double sum_end1 = 0; for (int i = 0; i < ymspec.Length; i++) { sum_end1 += Signal[i] * Signal[i]; } return(Signal); }
public override MathNet.Numerics.Complex[] Reflection_Spectrum(int sample_frequency, int length, Hare.Geometry.Vector Normal, Hare.Geometry.Vector Dir, int threadid) { int a = (int)(Math.Abs(Hare.Geometry.Hare_math.Dot(Dir, Normal)) * 180 / Math.PI / 18); MathNet.Numerics.Complex[] Ref_trns = new MathNet.Numerics.Complex[length]; for (int j = 0; j < length; j++) { double freq = j * (sample_frequency / 2) / length; Ref_trns[j] = new MathNet.Numerics.Complex(Transfer_FunctionR[a].Interpolate(freq), Transfer_FunctionI[a].Interpolate(freq)); } return(Ref_trns); }
public MathNet.Numerics.Complex[][] Interpolate(double[] freq) { MathNet.Numerics.Complex[][] Zr = new MathNet.Numerics.Complex[freq.Length][]; for (int f = 0; f < freq.Length; f++) { Zr[f] = new MathNet.Numerics.Complex[Zr_Curves_R.Length]; for (int a = 0; a < Zr_Curves_R.Length; a++) { Zr[f][a] = new MathNet.Numerics.Complex(Zr_Curves_R[a].Interpolate(freq[f]), Zr_Curves_I[a].Interpolate(freq[f])); } } return(Zr); }
public static void IFFT(Complex[] xdata, int m) { var temp = new MathNet.Numerics.Complex[(int)Math.Pow(2, m)]; for (int i = 0; i < temp.Length; i++) { temp[i].Real = xdata[i].Real; temp[i].Imag = xdata[i].Imag; } cft.TransformBackward(temp); for (int i = 0; i < temp.Length; i++) { xdata[i].Real = temp[i].Real; xdata[i].Imag = temp[i].Imag; } }