/// <snip> public WaveGenerator(Int64 amplitude, double freq) { header = new WaveHeader(); format = new WaveFormatChunk(); data = new WaveDataChunk(); // Fill the data array with sample data if (freq < 262) { freq = 262; } if (freq > 1975) { freq = 1975; } // Number of samples = sample rate * channels * bytes per sample uint numSamples = format.dwSamplesPerSec * format.wChannels; // Initialize the 16-bit array data.shortArray = new short[numSamples]; // The "angle" used in the function, adjusted for the number of channels and sample rate. // This value is like the period of the wave. double t = (Math.PI * 2 * freq) / (format.dwSamplesPerSec * format.wChannels); for (uint i = 0; i < numSamples - 1; i++) { // Fill with a simple sine wave at max amplitude for (int channel = 0; channel < format.wChannels; channel++) { data.shortArray[i + channel] = Convert.ToInt16(amplitude * Math.Sin(t * i) + amplitude * Math.Sin(t * i * 1.05946 * 1.05946)); } } // Calculate data chunk size in bytes data.dwChunkSize = (uint)(data.shortArray.Length * (format.wBitsPerSample / 8)); }
public WaveGenerator(WaveExampleType type) { // Init chunks header = new WaveHeader(); format = type == WaveExampleType.MonoWave ? new WaveFormatChunk(false) : new WaveFormatChunk(); data = new WaveDataChunk(); // Fill the data array with sample data switch (type) { case WaveExampleType.ExampleSineWave: { // Number of samples = sample rate * channels * bytes per sample uint numSamples = format.dwSamplesPerSec * format.wChannels; // Initialize the 16-bit array data.shortArray = new short[numSamples]; int amplitude = 32760; // Max amplitude for 16-bit audio double freq = 440.0f; // Concert A: 440Hz // The "angle" used in the function, adjusted for the number of channels and sample rate. // This value is like the period of the wave. double t = (Math.PI * 2 * freq) / (format.dwSamplesPerSec * format.wChannels); for (uint i = 0; i < numSamples; i+=2) { // Fill in the stereo channels short outp = Convert.ToInt16(amplitude * Math.Sin(t * i)); data.shortArray[i] = outp; data.shortArray[i + 1] = outp; } // Calculate data chunk size in bytes data.dwChunkSize = (uint)(data.shortArray.Length * (format.wBitsPerSample / 8)); break; } case WaveExampleType.TetrisWave: { double[] tetrisNoteSequence = { WaveNoteFreq.E, WaveNoteFreq.B, WaveNoteFreq.C, WaveNoteFreq.D, WaveNoteFreq.C, WaveNoteFreq.B, WaveNoteFreq.A, WaveNoteFreq.A, WaveNoteFreq.C, WaveNoteFreq.E, WaveNoteFreq.D, WaveNoteFreq.C, WaveNoteFreq.B, WaveNoteFreq.C, WaveNoteFreq.D, WaveNoteFreq.E, WaveNoteFreq.C, WaveNoteFreq.A }; double[] tetrisNoteLength = { WaveNoteLength.Quarter, WaveNoteLength.Eighth, WaveNoteLength.Eighth, WaveNoteLength.Quarter, WaveNoteLength.Eighth, WaveNoteLength.Eighth, WaveNoteLength.Quarter, WaveNoteLength.Eighth, WaveNoteLength.Eighth, WaveNoteLength.Quarter, WaveNoteLength.Eighth, WaveNoteLength.Eighth, WaveNoteLength.ThreeQuarters, WaveNoteLength.Eighth, WaveNoteLength.Quarter, WaveNoteLength.Quarter, WaveNoteLength.Quarter, WaveNoteLength.Half }; double secondsLong = 0; foreach (double noteLen in tetrisNoteLength) { secondsLong += noteLen; } // Number of samples = sample rate * channels * bytes per sample uint numSamples = (uint)(format.dwSamplesPerSec * format.wChannels * secondsLong); // Initialize the 16-bit array data.shortArray = new short[numSamples]; // Max amplitude for 16-bit audio int amplitude = 32760; // Keep track of samples recorded uint samplesRecorded = 0; // Loop through each note for (int i = 0; i < tetrisNoteSequence.Length; i++) { // The "angle" used in the function, adjusted for the number of channels and sample rate. // This value is like the period of the wave. double t = (Math.PI * 2 * tetrisNoteSequence[i]) / (format.dwSamplesPerSec * format.wChannels); // The length in samples of the note uint noteLengthSamples = (uint)(format.dwSamplesPerSec * format.wChannels * tetrisNoteLength[i]); uint endTheNoteHere = samplesRecorded + noteLengthSamples; for (uint j = samplesRecorded; j < endTheNoteHere - 1; j++) { // Convert to int16 short conv = Convert.ToInt16(amplitude * Math.Sin(t * j)); // Fill with a simple sine wave at max amplitude for (int channel = 0; channel < format.wChannels; channel++) { data.shortArray[j + channel] = conv; } } samplesRecorded += noteLengthSamples; } // Calculate data chunk size in bytes data.dwChunkSize = (uint)(data.shortArray.Length * (format.wBitsPerSample / 8)); break; } case WaveExampleType.MessingWave: { // Number of samples = sample rate * channels * bytes per sample * seconds uint numSamples = format.dwSamplesPerSec * format.wChannels * 40; // Initialize the 16-bit array data.shortArray = new short[numSamples]; int amplitude = 32760; // Max amplitude for 16-bit audio double freq = 20.0f; // Concert A: 440Hz double hz = 0.0009; // Stereo volume interleave double stereoInterleaveFreq = 0.5f; // Channel amplitudes double c = (Math.PI * 2 * stereoInterleaveFreq) / (format.dwSamplesPerSec * format.wChannels); for (uint i = 0; i < numSamples - 1; i++) { // The "angle" used in the function, adjusted for the number of channels and sample rate. // This value is like the period of the wave. double t = (Math.PI * 2 * freq) / (format.dwSamplesPerSec * format.wChannels); double s = Math.Sin(t * i); double d = Math.Sin(c * i); double channelAmp = amplitude * d; // Fill with a simple sine wave at max amplitude var sound = Convert.ToInt16(channelAmp * s); data.shortArray[i] = sound; // Channel 1 data.shortArray[i + 1] = sound; // Channel 2 freq += hz; } // Calculate data chunk size in bytes data.dwChunkSize = (uint)(data.shortArray.Length * (format.wBitsPerSample / 8)); break; } case WaveExampleType.MonoWave: { // Number of samples = sample rate * channels * bytes per sample uint numSamples = format.dwSamplesPerSec * format.wChannels; // Initialize the 16-bit array data.shortArray = new short[numSamples]; int amplitude = 32760; // Max amplitude for 16-bit audio double freq = 40.0f; // Concert A: 440Hz // The "angle" used in the function, adjusted for the number of channels and sample rate. // This value is like the period of the wave. double t = (Math.PI * 2 * freq) / (format.dwSamplesPerSec * format.wChannels); for (uint i = 0; i < numSamples - 1; i++) { // Fill with a simple sine wave at max amplitude for (int channel = 0; channel < format.wChannels; channel++) { data.shortArray[i + channel] = Convert.ToInt16(amplitude * Math.Sin(t * i)); } } // Calculate data chunk size in bytes data.dwChunkSize = (uint)(data.shortArray.Length * (format.wBitsPerSample / 8)); break; } } }