chisel
chisel

Reputation: 21

NAudio asynchronous audio

I want to be able to dump sound files to the audio output asynchronously throughout the life of the application. I need to be able to request a file to be played and have it mixed in with any files already playing. The same file may be called multiple times. Is WaveMixerStream the way to go? Is it safe/recommended to keep a player and mixer stream open for the life of the application or will that cause performance problems?

//globals
IWavePlayer _Context;
WaveMixerStream32 _Mixer;

//constructor
_Context = new DirectSoundOut();
_Mixer = new WaveMixerStream32();
_Context.Init( Instance._Mixer );
_Context.Play();

//asynchronous sound output, on demand from user interface
_Mixer.AddInputStream( sound.FileWaveStream );

Upvotes: 2

Views: 1762

Answers (1)

Mark Heath
Mark Heath

Reputation: 49492

There are several ways you could do this, but here's one option. Create a player and mixer open all the time. I would use the MixingSampleProvider as the mixer, passing it through a SampleToWaveProvider or SampleToWaveProvider16 as the input to the player.

To ensure that playback never stops you would either need to customise MixingSampleProvider so that Read always returns the number of samples asked for even if there are no active inputs, or add a dummy input which is a never-ending stream of silence.

Now to play a sound, just pass an ISampleProvider (e.g. AudioFileReader) into your mixer's AddMixerInput and it will play it. It auto-removes inputs when they reach the end.

An alternative is to create a new player object for each sound to play. The disadvantage is working out a way to keep the player object alive until playback stops (probably by storing in a dictionary and then Disposing and taking it out when the PlaybackStopped event fires). The advantage is that you aren't keeping the sound device open when you don't need to, and you can easily play sounds at different sample rates / number of channels.

Upvotes: 1

Related Questions