Note that there are some explanatory texts on larger screens.

plurals
  1. POSound quality issues when using NAudio to play several wav files at once
    text
    copied!<p>My objective is this: to allow users of my .NET program to choose their own .wav files for sound effects. These effects may be played simultaneously. NAudio seemed like my best bet.</p> <p>I decided to use WaveMixerStream32. One early challenge was that my users had .wav files of different formats, so to be able to mix them together with WaveMixerStream32, I needed to "normalize" them to a common format. I wasn't able to find a good example of this to follow so I suspect my problem is a result of my doing this part wrong.</p> <p>My problem is that when some sounds are played, there are very noticeable "clicking" sounds at their end. I can reproduce this myself. </p> <p>Also, my users have complained that sometimes, sounds aren't played at all, or are "scratchy" all the way through. I haven't been able to reproduce this in development but I have heard this for myself in our production environment. </p> <p>I've played the user's wav files myself using Windows Media and VLC, so I know the files aren't corrupt. It must be a problem with how I'm using them with NAudio.</p> <p>My NAudio version is v1.4.0.0. </p> <p>Here's the code I used. To set up the mixer:</p> <pre><code>_mixer = new WaveMixerStream32 { AutoStop = false, }; _waveOutDevice = new WaveOut(WaveCallbackInfo.NewWindow()) { DeviceNumber = -1, DesiredLatency = 300, NumberOfBuffers = 3, }; _waveOutDevice.Init(_mixer); _waveOutDevice.Play(); </code></pre> <p>Surprisingly, if I set "NumberOfBuffers" to 2 here I found that sound quality was awful, with audible "ticks" occurring several times a second.</p> <p>To initialize a sound file, I did this:</p> <pre><code>var sample = new AudioSample(fileName); sample.Position = sample.Length; // To prevent the sample from playing right away _mixer.AddInputStream(sample); </code></pre> <p>AudioSample is my class. Its constructor is responsible for the "normalization" of the wav file format. It looks like this:</p> <pre><code>private class AudioSample : WaveStream { private readonly WaveChannel32 _channelStream; public AudioSample(string fileName) { MemoryStream memStream; using (var fileStream = File.OpenRead(fileName)) { memStream = new MemoryStream(); memStream.SetLength(fileStream.Length); fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length); } WaveStream originalStream = new WaveFileReader(memStream); var pcmStream = WaveFormatConversionStream.CreatePcmStream(originalStream); var blockAlignReductionStream = new BlockAlignReductionStream(pcmStream); var waveFormatConversionStream = new WaveFormatConversionStream( new WaveFormat(44100, blockAlignReductionStream.WaveFormat.BitsPerSample, 2), blockAlignReductionStream); var waveOffsetStream = new WaveOffsetStream(waveFormatConversionStream); _channelStream = new WaveChannel32(waveOffsetStream); } </code></pre> <p>Basically, the AudioSample delegates to its _channelStream object. To play an AudioSample, my code sets its "Position" to 0. This code that does this is marshalled onto the UI thread.</p> <p>This <em>almost</em> works great. I can play multiple sounds simultaneously. Unfortunately the sound quality is bad as described above. Can anyone help me figure out why?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload