static void Main(string[] args) { // First round of testing for RIFF streaming. Console.WriteLine("Configuring new Audio format: 16kHz, 16-bit depth, 2 channels"); var wavFormat = new AudioFormat(16000, 16, 2); var wavType = WaveGenerator.WaveType.SQUARE; Console.WriteLine("Creating a triad chord 3.2s long, with one note extended one second longer than the others."); var lowTriad = WaveGenerator.CreateNewWave(wavFormat, wavType, 100.0, 3.2, 220); var medTriad = WaveGenerator.CreateNewWave(wavFormat, wavType, 100.0, 4.2, 261.6256); var highTriad = WaveGenerator.CreateNewWave(wavFormat, wavType, 100.0, 3.2, 329.6276); Console.WriteLine("Mixing the samples for the triad."); var chord = PCMAudioTools.MixSamples(wavFormat, 100.0, (10.0, lowTriad), (30.0, medTriad), (20.0, highTriad)); Console.WriteLine("Changing the audio stream's volume."); PCMAudioTools.ChangeVolume(100.0, ref chord); // testing volume change Console.WriteLine("Creating mock Emergency Alert System tone: 2.2s @1200Hz"); var EAS = WaveGenerator.CreateNewWave(wavFormat, wavType, 100.0, 2.2, 1200); Console.WriteLine("Creating mock sine wave for CW: 1.0s @780Hz."); var CWTone = WaveGenerator.CreateNewWave(wavFormat, wavType, 100.0, 1.0, 680); Console.WriteLine("Stringing it all together into one sequence."); PCMAudioTools.AppendSamples(ref chord, (100.0, EAS), (20.0, CWTone)); Console.WriteLine("PLAYING RIFF STREAM"); PlayRIFFSoundData(ref chord); Console.WriteLine("PLAYING MP3 STREAM"); PlayMP3SoundData(ref chord); // New sequence of tests... // Always hold at the end Console.WriteLine("Press any key to exit."); Console.ReadKey(); }
/// <summary> /// Plays the given sequence of Morse symbols using the internal WaveGenerator module. This "queues" /// audio to play, rather than relying on Thread.Sleep to gap the DITs/DAHs (symbols) from each other. /// </summary> /// <param name="morseStream">The sequence of MorseSymbol items to be played.</param> /// <param name="cancelToken">Tracks whether or not this operation should be cancelled.</param> /// <see cref="MorseSymbol"/> /// <see cref="WaveGenerator"/> public void PlayWaveStream(List <MorseSymbol> morseStream, CancellationToken cancelToken) { // First, get the audio constructed. var wavFormat = new WaveAudioFormat(16000, 16, 1); //doesn't need to be the most high-def sound var wavType = WaveGenerator.WaveType.SINE; //always a SINE wave (for now; configurable later) var streamSequence = new List <WaveSample>(); //container for the resulting stream of samples streamSequence.Add(new WaveSample(wavFormat, 0)); //initialize the stream with at least ONE empty sample ////Loading icon?? foreach (MorseSymbol sym in morseStream) { if (cancelToken != null && cancelToken.IsCancellationRequested) { return; } if (sym.hasSound()) { WaveAudioTools.AppendSamples( ref streamSequence, (100.0, WaveGenerator.CreateNewWave(wavFormat, wavType, this.Gain * 100.0, sym.getDuration() / 1000.0, this.Frequency)) ); } else { WaveAudioTools.AppendSamples( ref streamSequence, (100.0, WaveGenerator.CreateEmptySpace(wavFormat, sym.getDuration() / 1000.0)) ); } } // Construct the output stream in WAV format. using var finalStream = new WaveStream(streamSequence); ////Release loading icon?? // Then, play the stream, while at the same time updating the text stream to sync as // best as possible to the currently-playing audio. // Define a lambda of sorts for updating the live text view for transmissions. Action <MorseSymbol> updateTextStream = s => { Program.mainForm.Invoke((System.Windows.Forms.MethodInvoker) delegate { Program.txLiveView.AppendText(s.getRepresentation()); }); }; // Construct the player. using var queuedStream = new System.IO.MemoryStream(finalStream.GetRawWaveStream()); using var mediaPlayer = new System.Media.SoundPlayer(queuedStream); //...and...... GO! mediaPlayer.Play(); int infiniteLoopPrevention = 0; // Give the player 2s to load the stream. while (!mediaPlayer.IsLoadCompleted && infiniteLoopPrevention < 100) { if (cancelToken != null && cancelToken.IsCancellationRequested) { mediaPlayer.Stop(); mediaPlayer.Dispose(); break; } Thread.Sleep(20); infiniteLoopPrevention++; } // During stream playback, send out the symbols. for (int index = 0; index < morseStream.Count; index++) { var sym = morseStream[index]; if (cancelToken != null && cancelToken.IsCancellationRequested) { mediaPlayer.Stop(); mediaPlayer.Dispose(); break; } //Thread.Sleep((int)sym.getDuration()); Task.Delay((int)sym.getDuration()).Wait(); updateTextStream(sym); // Handle progress bar updates. Program.mainForm.Invoke((System.Windows.Forms.MethodInvoker) delegate { try { Program.pbTXProgress.Value = (((index * 100) / morseStream.Count) + 1); } catch { } }); } }