Skip to content

Commit

Permalink
docs for playback stopped
Browse files Browse the repository at this point in the history
  • Loading branch information
markheath committed Nov 20, 2017
1 parent 46053ed commit af5c437
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 7 deletions.
23 changes: 23 additions & 0 deletions Docs/PlaybackStopped.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Handling Playback Stopped

In NAudio, you use an implementation of the `IWavePlayer` class to play audio. Examples include `WaveOut`, `WaveOutEvent`, `WasapiOut`, `AsioOut` etc. To specify the audio to be played, you call the `Init` method passing in an `IWaveProvider`. And to start playing you call `Play`.

## Manually Stopping Playback

You can stop audio playback any time by simply calling `Stop`. Depending on the implementation of `IWavePlayer`, playback may not stop instantaneously, but finish playing the currently queued buffer (usually no more than 100ms). So even when you call `Stop`, you should wait for the `PlaybackStopped` event to be sure that playback has actually stopped.

## Reaching the end of the input audio

In NAudio, the `Read` method on `IWaveProvider` is called every time the output device needs more audio to play. The `Read` method should normally return the requested number of bytes of audio (the `count` parameter). If `Read` returns less than `count` this means this is the last piece of audio in the input stream. If `Read` returns 0, the end has been reached.

NAudio playback devices will stop playing when the `IWaveProvider`'s `Read` method returns 0. This will cause the `PlaybackStopped` event to get raised.

## Output device error

If there is any kind of audio error during playback, the `PlaybackStopped` event will be fired, and the `Exception` property set to whatever exception caused playback to stop. A very common cause of this would be playing to a USB device that has been removed during playback.

## Disposing resources

Often when playback ends, you want to clean up some resources, such as disposing the output device, and closing any input files such as `AudioFileReader`. It is strongly recommended that you do this when you receive the `PlaybackStopped` event and not immediately after calling `Stop`. This is because in many `IWavePlayer` implementations, the audio playback code is on another thread, and you may be disposing resources that will still be used.

Note that NAudio attempts to fire the `PlaybackStopped` event on the `SynchronizationContext` the device was created on. This means in a WinForms or WPF application it is safe to access the GUI in the handler.
1 change: 1 addition & 0 deletions NAudio.sln
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{BA7F6DBB-9
Docs\PlayAudioFileConsoleApp.md = Docs\PlayAudioFileConsoleApp.md
Docs\PlayAudioFileWinForms.md = Docs\PlayAudioFileWinForms.md
Docs\PlayAudioFromUrl.md = Docs\PlayAudioFromUrl.md
Docs\PlaybackStopped.md = Docs\PlaybackStopped.md
Docs\PlaySineWave.md = Docs\PlaySineWave.md
Docs\RawSourceWaveStream.md = Docs\RawSourceWaveStream.md
Docs\RecordWavFileWinFormsWaveIn.md = Docs\RecordWavFileWinFormsWaveIn.md
Expand Down
8 changes: 5 additions & 3 deletions NAudio/Wave/WaveOutputs/IWavePlayer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;

// ReSharper disable once CheckNamespace
namespace NAudio.Wave
{
/// <summary>
Expand Down Expand Up @@ -34,9 +35,10 @@ public interface IWavePlayer : IDisposable
PlaybackState PlaybackState { get; }

/// <summary>
/// The volume 1.0 is full scale
/// The volume
/// 1.0f is full scale
/// Note that not all implementations necessarily support volume changes
/// </summary>
[Obsolete("Not intending to keep supporting this going forward: set the volume on your input WaveProvider instead")]
float Volume { get; set; }

/// <summary>
Expand All @@ -52,7 +54,7 @@ public interface IWavePlayer : IDisposable
public interface IWavePosition
{
/// <summary>
/// Position (in terms of bytes played - does not necessarily)
/// Position (in terms of bytes played - does not necessarily translate directly to the position within the source audio file)
/// </summary>
/// <returns>Position in bytes</returns>
long GetPosition();
Expand Down
8 changes: 4 additions & 4 deletions NAudio/Wave/WaveOutputs/StoppedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;

// ReSharper disable once CheckNamespace
namespace NAudio.Wave
{
/// <summary>
Expand All @@ -21,8 +20,9 @@ public StoppedEventArgs(Exception exception = null)
}

/// <summary>
/// An exception. Will be null if the playback or record operation stopped
/// An exception. Will be null if the playback or record operation stopped due to
/// the user requesting stop or reached the end of the input audio
/// </summary>
public Exception Exception { get { return exception; } }
public Exception Exception => exception;
}
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ NAudio comes with several demo applications which are the quickest way to see ho
- [Creating and configuring a WasapiOut device](Docs/WasapiOut.md)
- [Implement "Fire and Forget" Playback (e.g. game sound effects)](http://markheath.net/post/fire-and-forget-audio-playback-with)
- [Play streaming MP3](http://markheath.net/post/how-to-play-back-streaming-mp3-using)
- [Handling playback stopped](Docs/PlaybackStopped.md)

### Working with Codecs

Expand Down

0 comments on commit af5c437

Please sign in to comment.