Search code examples
c#audionaudio

How to Mix 2 wav files together?


I'm trying to record an input and merge it together with a song (not concatenate). I have a guitar that i recorded while listening to a song and I want to put the guitar on the song (like audcaity). Is there any way for doing it? If its not possible on real time mixing - is it possible to merge them after i recorded? Like after I recorded the guitar and now its a wav file and i want to mix 2 wav files together. Thats the input device:

 private void Capture()
    {
        input = new WasapiCapture((MMDevice)inputCombo.SelectedItem);
        bufferedWaveProvider = new BufferedWaveProvider(input.WaveFormat);
        input.DataAvailable += WaveInOnDataAvailable;
        input.StartRecording();
        write = new WaveFileWriter(System.IO.Path.GetTempFileName(), input.WaveFormat);
    }

 private void WaveInOnDataAvailable(object sender, WaveInEventArgs e)
    {
        bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
        write.Write(e.Buffer, 0, e.BytesRecorded);
        write.Flush();
    }

Instead of writing it into a blank file i want to write it into a wav file thats already exists and not override it. Is it maybe possible with the MixingSampleProvider?


Solution

  • To mix multiple ISampleProvider sources using a MixingSampleProvider, you can do the following:

    Here SignalGenerator has a Gain property which allows to specify how loud it should be in the mix.

    using System;
    using NAudio.Wave;
    using NAudio.Wave.SampleProviders;
    
    namespace ConsoleApplication1
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                ISampleProvider provider1 = new SignalGenerator
                {
                    Frequency = 1000.0f,
                    Gain = 0.5f
                };
    
                ISampleProvider provider2 = new SignalGenerator
                {
                    Frequency = 1250.0f,
                    Gain = 0.5f
                };
    
                var takeDuration1 = TimeSpan.FromSeconds(5); // otherwise it would emit indefinitely
                var takeDuration2 = TimeSpan.FromSeconds(10);
    
                var sources = new[]
                {
                    provider1.Take(takeDuration1),
                    provider2.Take(takeDuration2)
                };
    
                var mixingSampleProvider = new MixingSampleProvider(sources);
    
                var waveProvider = mixingSampleProvider.ToWaveProvider();
    
                WaveFileWriter.CreateWaveFile("test.wav", waveProvider);
            }
        }
    }