This project has moved and is read-only. For the latest updates, please go here.

Crossfading, how?

Jul 18, 2013 at 1:48 PM
I'm using WaveOutEvent to play music files. But how do i use this to implement simple crossfading, so a new song starts like 5 sec before that current is done.

Thanks in advance!
Jul 19, 2013 at 3:05 PM
To play two things at once, use the MixingSampleProvider. And to fade in and out, use the FadeInOutSampleProvider. So begin a fade-out on the original file, and then add a new input to the mixer that is at the beginning of a fade-in.
Jul 20, 2013 at 9:25 PM
Thanks for your help.


I'm not sure how to do this.. this is my code for playing a file. I clean up and dispose everything before this between every play.
            WaveStream readerStream = null;
            WaveFormat format;

            readerStream = new Mp3FileReader(mediaPath);

            format = WaveFormat.CreateIeeeFloatWaveFormat(readerStream.WaveFormat.SampleRate, readerStream.WaveFormat.Channels);

            // Provide PCM conversion if needed
            if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm)
            {
                readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
                readerStream = new BlockAlignReductionStream(readerStream);
            }

            // Provide conversion to 16 bits if needed
            if (readerStream.WaveFormat.BitsPerSample != 16)
            {
                readerStream = new WaveFormatConversionStream(format, readerStream);
            }

            mixingSampleProvider = new MixingSampleProvider(format);
            waveChannel = new WaveChannel32(readerStream);

            // Chain the DSP Equalizer Effect - DSP Equalizer must come AFTER WaveChannel32 because it
            //  was coded to expect Ieee Float samples, NOT PCM samples
            mixerEffect = new EqualizerEffect();
            mixerEffect.OnFactorChanges();

            readerStream = new DSPEffectStream(waveChannel, mixerEffect);

            //Convert wave to samples
            waveToSample = new WaveToSampleProvider(waveChannel);

            //Provide metering support
            meterSampleProvider = new MeteringSampleProvider(waveToSample);

            //Provide volume support
            volumeSampleProvider = new VolumeSampleProvider(meterSampleProvider);

            //Add the samples to the mixed stream used to enable crossfading
            mixingSampleProvider.AddMixerInput(volumeSampleProvider);

            //Convert samples back to wave
            sampleToWave = new SampleToWaveProvider(mixingSampleProvider);

            waveOutDevice = new WaveOutEvent();
            waveOutDevice.DeviceNumber = playbackAudioDevice.Id;
            waveOutDevice.Init(sampleToWave);
I obviously can't repeat that to enable crossfade. How should i implement this? and is this the correct way of initializing the different providers?

I hope you can push me in the right direction :)
Jul 22, 2013 at 3:40 PM
And how is i supposed to clean up correcly?

I sometimes get a "dispose not called"
if (waveOutDevice != null)
            {
                waveOutDevice.Stop();
                waveOutDevice.Dispose();
                waveOutDevice = null;
            }

            if (waveChannel != null)
            {
                waveChannel.Close();
                waveChannel.Dispose();
                waveChannel = null;
            }
Jul 22, 2013 at 4:27 PM
did you Dispose your mp3filereader?
Also, what version of NAudio are you using? Only the debug build reports dispose not called issues
And Mp3FileReader already returns 16 bit PCM, so no need for the extra conversion steps.
Your audio pipeline is OK, just include the FadeInOutSampleProvider in the chain as well
Jul 23, 2013 at 10:58 AM
I tested it ealier today, at the dispose not called error occoures because of an exception for at specific file. So not a general problem i think.

I'm using 1.6 and yes, i'm currently only running it in debug mode :)

Okay cool, thanks.


I'm not sure how to do this. Can you answer these questions:

The code i posted is from a method that i call every time i play a new file. So it disposes it all and reinitialize all of it. Is that wrong when i want to crossfade? i mean, should i reuse some of it?
The reason that i get confused is that if i want to crossfade, i would have to add a stream into the mixingSampleProvider correct? but what about all the other code that touches the stream, like volume, mixereffect etc.

I hope it makes sense ;)
Jul 24, 2013 at 9:34 AM
the fade step is the last step in the audio pipeline. You just put it after volume, mixereffect etc.
Jul 24, 2013 at 1:29 PM
Okay thanks, but what about the closing/disposing of it all between the song change? :)
Jul 26, 2013 at 1:25 PM
when the fadeout has ended, you'd need to dispose the file that had just finished playing and remove it from the mixer inputs. This will require you to make your own ISampleProvider for crossfading. NAudio does not include a ready made part for this, but I will consider it perhaps for a future demo