I'm looking for a way to mix thousands of WAV files into a single file using NAudio's MixingSampleProvider
. I'm building a drum sampler and I'd like to be able to create a whole song (based on MIDI information) that could then be exported into a single WAV file.
The issue I'm running into is that the MixingSampleProvider
has a limit of 1024 sources and throws and exception saying Too many mixer inputs
if that limit is reached. I'm sure this limit is there for a reason, I'd like to know how to achieve my goal despite it.
I've searched through the NAudio demos and Mark Heath's blog, but I haven't found exactly what I need there.
I was thinking I could split the song into smaller segments (under 1024 sampler inputs) and merge the separate parts afterwards. Is that the way to go, or is there a better one? Thanks for any advice.
Here's a part of my code:
public class DrumSampler
{
private readonly MixingSampleProvider _mixer;
private readonly Dictionary<string, SampleSource> _cachedSamples = new();
public DrumSampler()
{
var waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 2);
_mixer = new MixingSampleProvider(waveFormat);
LoadSamples();
}
private void LoadSamples()
{
LoadSample("kick", @"C:\Samples\kick.wav");
LoadSample("snare", @"C:\Samples\snare.wav");
LoadSample("crash", @"C:\Samples\crash.wav");
}
private void LoadSample(string key, string filePath)
{
_cachedSamples.Add(key, SampleSource.CreateFromWaveFile(filePath, _mixer.WaveFormat));
}
public void ExportSong()
{
AddDrums();
WaveFileWriter.CreateWaveFile16("song.wav", _mixer);
}
private void AddDrums()
{
//simulate adding drum samples based on MIDI information
for (int i = 0; i < 1000; i++)
{
var sample = _cachedSamples["kick"];
var delayed = new DelayedSampleProvider(sample, TimeSpan.FromSeconds(123));
_mixer.AddMixerInput(delayed);
}
}
}
The SampleSource
implementation is taken from NAudio's DrumMachineDemo.
The DelayedSampleProvider
implementation is inspired by NAudio's OffsetSampleProvider.