public void FadeDurationCanBeLongerThanOneRead()
        {
            var source = new TestSampleProvider(10, 1); // 10 samples per second
            source.UseConstValue = true;
            source.ConstValue = 100;
            var fade = new FadeInOutSampleProvider(source);
            fade.BeginFadeIn(1000);
            float[] buffer = new float[4];
            int read = fade.Read(buffer, 0, 4);
            Assert.AreEqual(4, read);
            Assert.AreEqual(0, buffer[0]); // start of fade-in
            Assert.AreEqual(10, buffer[1]);
            Assert.AreEqual(20, buffer[2], 0.0001);
            Assert.AreEqual(30, buffer[3], 0.0001);

            read = fade.Read(buffer, 0, 4);
            Assert.AreEqual(4, read);
            Assert.AreEqual(40, buffer[0], 0.0001);
            Assert.AreEqual(50, buffer[1], 0.0001);
            Assert.AreEqual(60, buffer[2], 0.0001);
            Assert.AreEqual(70, buffer[3], 0.0001);

            read = fade.Read(buffer, 0, 4);
            Assert.AreEqual(4, read);
            Assert.AreEqual(80, buffer[0], 0.0001);
            Assert.AreEqual(90, buffer[1], 0.0001);
            Assert.AreEqual(100, buffer[2], 0.0001);
            Assert.AreEqual(100, buffer[3]);
        }
 public void CanFadeIn()
 {
     var source = new TestSampleProvider(10, 1); // 10 samples per second
     source.UseConstValue = true;
     source.ConstValue = 100;
     var fade = new FadeInOutSampleProvider(source);
     fade.BeginFadeIn(1000);
     float[] buffer = new float[20];
     int read = fade.Read(buffer, 0, 20);
     Assert.AreEqual(20, read);
     Assert.AreEqual(0, buffer[0]); // start of fade-in
     Assert.AreEqual(50, buffer[5]); // half-way
     Assert.AreEqual(100, buffer[10]); // fully fade in
     Assert.AreEqual(100, buffer[15]); // fully fade in
 }
        private void _play()
        {
            /* Audio chain */

            // Sampling
            _wavesampler = new WaveToSampleProvider(new Wave16ToFloatProvider(_wavebuffer));

            // Fading component
            _fade = new FadeInOutSampleProvider(_wavesampler);
            _fade.BeginFadeIn(1500);

            // Notifying component
            var _notify = new NotifyingSampleProvider(_fade);
            _notify.Sample += new EventHandler<SampleEventArgs>(_notify_Sample);

            // Gain adjustment component
            _volume = new VolumeSampleProvider(_notify);
            _volume.Volume = this.Volume;

            // Output
            Output.Init(new SampleToWaveProvider16(_volume));

            /* Playback loop */
            do
            {
                if (_cancel_play.IsCancellationRequested)
                {
                    Console.WriteLine("[Playback thread] Cancellation requested.");

                    // Fade out and stop
                    Console.WriteLine("[Playback thread] Fading out and stopping...");
                    _fade.BeginFadeOut(500);
                    Thread.Sleep(500);
                    Output.Stop();
                    Console.WriteLine("[Playback thread] Output stopped.");
                    this.Status = StreamStatus.Stopped;
                    Console.WriteLine("[Playback thread] Acknowledged as status.");

                    //_cancel_play_token.ThrowIfCancellationRequested();
                    //Console.WriteLine("[Playback thread] WARNING: Cancellation token is not cleanly set!");
                    return;
                }

                if (Output.PlaybackState != PlaybackState.Playing && _wavebuffer.BufferedDuration.TotalMilliseconds > 2750)
                {
                    // Buffer is filled enough
                    Console.WriteLine("[Playback thread] Buffer is okay now, start playback!");
                    this.Status = StreamStatus.Playing;
                    Output.Play();
                }
                else if (Output.PlaybackState == PlaybackState.Playing && _wavebuffer.BufferedDuration.TotalMilliseconds < 2250)
                {
                    // Buffer is underrunning
                    Console.WriteLine("[Playback thread] Buffer is underrunning, pausing playback...");
                    this.Status = StreamStatus.Buffering;
                    Output.Pause();
                }

                if (_bufferThread.Exception != null)
                {
                    Console.WriteLine("[Playback thread] Buffering thread is faulted, aborting playback");
                    throw new Exception("Buffering thread faulted, aborting playback");
                }

                Thread.Sleep(100);
            }
            while (true);
        }