Individual Samples Access & Modification

Mar 13, 2012 at 5:13 PM

Hi there, In next few months I will try to do some declicking algorithms for coruppted wave files and I would like to use NAudio for reading and writing waves. So I would like to ask users of NAudio, whether there is any direct access for getting and setting individual samples of wave files in NAudio library. For example, I would like to open some wav file, then I would like to look on value of for example fifth sample on all channels as a float for instane. I would also like to know weather there is a way how to change these 5th samples and after that how can I save this modified outcome. Can you please help me and show me, how this can be performed. I hadn't find any documentation so far, is there any? Thank you.

Coordinator
Mar 14, 2012 at 7:51 AM

Yes, NAudio is designed to give you access to the individual audio samples. However, there are lots of different audio formats (bit depths, compression types etc), so there is no one simple way that works for everything. The WaveFileReader class will give you access to the raw byte data. You can then convert each pair of bytes into 16 bit samples yourself, or take advantage of some of the NAudio helper classes to allow you to more easily work directly with 16 bit audio (assuming your audio is 16 bit). Then you use the WaveFileWriter class to write your modified audio back out to disk.

If you want to deal with audio as floats, as you say, use the new AudioFileReader class which will return a ISampleProvider, which makes it very easy to examine the value of each sample as a float as it comes through the Read method. You would create your own ISampleProvider whose Read method reads from the source AudioFileReader and examines and modifies the audio:

   var reader = new AudioFileReader();

   var mySampleProvider = new MySampleProvider(reader);

   WaveFileWriter.CreateWaveFile(myWaveProvider, "example.wav");

 

class MySampleProvider: ISampleProvider

   private int Read(float[] buffer, int offset, int count)

{

   int samplesRead = source.Read(buffer, offset, count);

  // TODO: examine and optionally change the contents of buffer

   return samplesRead;

}