public static Wave operator +(Wave wave1, Wave wave2) { if (wave1.frequency != wave2.frequency) { throw new ArgumentException("The frequencies of 'wave1' and 'wave2' don't match."); } double basePhase = wave1.phase; double phaseDifference = wave2.phase - wave1.phase; double frequency = Items.Equal(wave1.frequency, wave2.frequency); double amplitude = Scalars.SquareRoot ( wave1.amplitude.Square() + 2 * wave1.amplitude * wave2.amplitude * Scalars.PSine(phaseDifference + 0.25) + wave2.amplitude.Square() ); double phase = basePhase + Scalars.ArcTangent ( wave2.amplitude * Scalars.PSine(phaseDifference), wave1.amplitude + wave2.amplitude * Scalars.PSine(phaseDifference + 0.25) ) / (2 * Math.PI); return(new Wave(frequency, amplitude, phase)); }
public static IEnumerable <Wave> SignalToSpectrum(IEnumerable <double> signal, double length) { if (signal == null) { throw new ArgumentNullException("signal"); } if (length <= 0) { throw new ArgumentOutOfRangeException("length"); } Complex[] spectrum = DiscreteFourierTransform.TransformForward(signal.Select(sample => (Complex)sample)).ToArray(); for (int spectrumIndex = 0; spectrumIndex < spectrum.Length; spectrumIndex++) { double frequencyIndex = spectrumIndex > spectrum.Length / 2 ? spectrumIndex - spectrum.Length : spectrumIndex; double frequency = frequencyIndex / length; double cosineAmplitude = spectrum[spectrumIndex].Real; double sineAmplitude = spectrum[spectrumIndex].Imaginary; double mixedAmplitude = Scalars.SquareRoot(cosineAmplitude.Square() + sineAmplitude.Square()); double amplitude = mixedAmplitude / Scalars.SquareRoot(spectrum.Length); double phase = Scalars.ArcTangent(sineAmplitude, cosineAmplitude); yield return(new Wave(frequency, amplitude, -phase / (2 * Math.PI) + 0.25)); } }
// Intended for synthesis // Input \ Output | Real | Imaginary // ---------------|------|---------- // Real | + | - // Imaginary | + | + static MatrixComplex GetReverseTransformation(int size) { MatrixComplex transformation = new MatrixComplex(size, size); Complex factor = (2 * Math.PI / size) * Complex.ImaginaryOne; for (int row = 0; row < transformation.RowCount; row++) { for (int column = 0; column < transformation.ColumnCount; column++) { transformation[row, column] = Scalars.Exponentiate(-factor * row * column); } } return((1 / Scalars.SquareRoot(size)) * transformation); }