Steady and even playback

Aug 13, 2011 at 6:08 PM
Edited Aug 13, 2011 at 6:09 PM
Goal - I'm making a basic mistake no doubt.  In this example, my goal is to play two audio files in time.  "hat" on each beat, "kick" on beat one.
Problem - The rhythm is choppy and uneven.  At first I thought it was the accuracy of system.timer events so I changed it up to a loop dependent on the system.diagnostics.stopwatch.  No dice.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NAudio.Wave;
using NAudio.CoreAudioApi;

namespace Beat
    class Program
        static void Main(string[] args)
            IWavePlayer player = null;
            WaveMixerStream32 mixer = null;
            WaveStream ws = null;
            WaveChannel32 wc1 = null;
            WaveChannel32 wc2 = null;

            ws = new WaveFileReader("kick.wav");
            wc1 = new WaveChannel32(ws);
            ws = new WaveFileReader("hat.wav");
            wc2 = new WaveChannel32(ws);

            mixer = new WaveMixerStream32();
            mixer.AutoStop = false;

            player = new DirectSoundOut();

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            TimeSpan interval = new TimeSpan(0, 0, 0, 0, 180);
            int nCount = 0;
            while (true)

                if (sw.Elapsed > interval)
                    wc2.Position = 0;

                    if (nCount == 4)
                        wc1.Position = 0;
                        nCount = 0;
Aug 25, 2011 at 12:42 PM

This is because of buffer read sizes. The soundcard is requesting (say) 100ms at a time from the input streams, and although you are repositioning the inputs at a specific moment, the reposition doens't take effect until another Read takes place when the soundcard needs another buffer. Have a look at the latest source code for a drum machine that puts the beats in sample accurate positions.