/// <summary> /// Load the summed signal into a wav file, can be saved or played /// </summary> /// <param name="workbookSourceSignal"></param> private void CreateWavFile(Signal workbookSourceSignal) { int sampleRate = (int)workbookSourceSignal.SamplingHZ; SignalWaveFile = new WaveFile(sampleRate, 16, 1); // Convert amplitudes to 16 bit PCM values // First find max value, set that to be 100% // Scale all other values against that max, convert each value to 16 bit int. Biased to 32767 for Y zero point List <double> signalValues = workbookSourceSignal.Samples; double peakValue = signalValues.Max(); if (Math.Abs(signalValues.Min()) > peakValue) { peakValue = Math.Abs(signalValues.Min()); } foreach (double value in signalValues) { double percentage = value / peakValue; double pcmVal = (percentage * 32767) + 32767; // Bias at midpoint of 16 bit range SignalWaveFile.AddSample(pcmVal); } }
/// <summary> /// Generates the specified dual-tone multi-frequencies <paramref name="repeatCount"/> times storing them in the specified <see cref="WaveFile"/>. /// </summary> /// <param name="destination"><see cref="WaveFile"/> used to store generated dual-tone multi-frequencies.</param> /// <param name="tones">Dual-tone multi-frequencies to generate.</param> /// <param name="volume">Volume of generated dual-tones as a percentage (0 to 1).</param> /// <param name="repeatCount">Number of times to repeat each tone.</param> /// <exception cref="ArgumentOutOfRangeException">Value must be expressed as a fractional percentage between zero and one.</exception> /// <exception cref="InvalidOperationException"><see cref="DTMF"/> only generated for <see cref="WaveFile"/> with a sample rate of 8, 16, 24, 32 or 64 bits per sample.</exception> public static void Generate(WaveFile destination, DTMF[] tones, double volume, int repeatCount) { if (volume < 0.0D || volume > 1.0D) { throw new ArgumentOutOfRangeException(nameof(volume), "Value must be expressed as a fractional percentage between zero and one"); } double amplitude = destination.AmplitudeScalar * volume; // Iterate through each repeat count for (int x = 0; x < repeatCount; x++) { // Interate through each tone foreach (DTMF tone in tones) { // Iterate through each sample for total DTMF duration for (long y = 0; y < tone.Duration * destination.SampleRate; y++) { // Compute frequencies of DTMF at given time and add to wave file destination.AddSample(ComputeFrequencies(tone, y, destination.SampleRate) * amplitude); } } } }
/// <summary> /// Generates the specified dual-tone multi-frequencies <paramref name="repeatCount"/> times storing them in the specified <see cref="WaveFile"/>. /// </summary> /// <param name="destination"><see cref="WaveFile"/> used to store generated dual-tone multi-frequencies.</param> /// <param name="tones">Dual-tone multi-frequencies to generate.</param> /// <param name="volume">Volume of generated dual-tones as a percentage (0 to 1).</param> /// <param name="repeatCount">Number of times to repeat each tone.</param> /// <exception cref="ArgumentOutOfRangeException">Value must be expressed as a fractional percentage between zero and one.</exception> /// <exception cref="InvalidOperationException"><see cref="DTMF"/> only generated for <see cref="WaveFile"/> with a sample rate of 8, 16, 24, 32 or 64 bits per sample.</exception> public static void Generate(WaveFile destination, DTMF[] tones, double volume, int repeatCount) { if (volume < 0.0D || volume > 1.0D) throw new ArgumentOutOfRangeException("volume", "Value must be expressed as a fractional percentage between zero and one"); double amplitude = destination.AmplitudeScalar * volume; // Iterate through each repeat count for (int x = 0; x < repeatCount; x++) { // Interate through each tone foreach (DTMF tone in tones) { // Iterate through each sample for total DTMF duration for (long y = 0; y < tone.Duration * destination.SampleRate; y++) { // Compute frequencies of DTMF at given time and add to wave file destination.AddSample(DTMF.ComputeFrequencies(tone, y, destination.SampleRate) * amplitude); } } } }