copying file using float array - WaveFileWrite.WriteSamples()

Jul 17 at 5:47 PM
Edited Jul 17 at 5:52 PM
I would like to make some basic operations on samples and i've created a simple test code - it should get the samples from AudioFileReader to float array and write it back to different audio file, using WaveFileWriter.WriteSamples(). However the output seems damaged (i can hear clipping/distortion). Moreover, the length of the files are different (as the message box in my code shows), anyone knows what seems to be the case of this behaviour?

Here's fragment of my code:
            /*... load waveReader ... */

            float[] buffer = new float[waveReader.Length];
            
            waveReader.Read(buffer, 0, buffer.Length);

            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.Filter = "Wave File|*.wav;*";
            saveDialog.Title = "Save Audio Output";
            if (saveDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) 
            return;

            NAudio.Wave.WaveFileWriter writer = new 
                      NAudio.Wave.WaveFileWriter(saveDialog.FileName, 
                      watermarkReader.WaveFormat);

            writer.WriteSamples(buffer, 0, buffer.Length);
            
            MessageBox.Show("source: " + waveReader.Length + ", copy: " + writer.Length, "INFO");
&#43 is 'plus' sign
Coordinator
Jul 28 at 5:32 PM
What is the WaveFormat of the watermarkReader?
Jul 31 at 12:04 PM
Edited Jul 31 at 12:07 PM
it's IEEE float (i use AudioFileReader for both waveReader and watermarkReader) - i found out that when i divide 'count' by 4, when writing it:
writer.WriteSamples(buffer, 0, buffer.Length/4); 
i get desired length of the file. The problem is the output is still louder - isn't always clipping, but when the input is loud enough - it clips. I would like to get the same volume as the input file... I also tried to create custom ISampleProvider and write it there but i was getting various exceptions so i gave up with this idea.
Coordinator
Jul 31 at 9:45 PM
when you read into a float array you are specifying the number of samples, not bytes. You should also check the return value of Read and use that instead of buffer.Length/4.
What is the original file format of the file you are reading? Is waveReader an AudioFileReader?
Aug 1 at 9:29 AM
Edited Aug 1 at 9:30 AM
i used both .wav and .mp3 as the original file format, result is the same.
waveReader is an AudioFileReader.
You should also check the return value of Read and use that instead of buffer.Length/4.
could you explain how? because i tried to do something like this:
int count = 4;
while (count!=0{
            count = waveReader.Read(buffer, 0, count);
}
but it creates silence
Coordinator
Aug 1 at 9:39 AM
you'd usually read a second or two at a time. Read out from waveReader, and then write to waveWriter, then repeat until you've reached the end.


some psuedo-code:
float[] buffer = new float[waveReader.WaveFormat.SampleRate * 2];
int read = 0;
do
{
    read = waveReader.Read(buffer, 0, buffer.Length);
    // perform any processing here
    writer.WriteSamples(buffer, 0, read );
} while (read > 0);
Marked as answer by stereoid on 8/1/2014 at 3:44 AM
Aug 1 at 9:53 AM
Edited Aug 1 at 10:09 AM
Thank you, that works but i still have a problem with clipping - output is louder then input - what might be the problem here? And it ocurrs for both mp3 and wav files.

EDIT: ok, i divided the samples in buffer by 2 and it looks like it has the same volume (or at least close to it). Thank you once again :)
Coordinator
Aug 1 at 11:33 PM
OK, that's strange that the samples are doubling in volume. Maybe its some kind of mono/stereo issue?
if you pass an audioFileReader straight into WaveFileWriter.CreateWaveFile16 does that also double the volume?
Aug 4 at 8:23 AM
no, the volume is the same
Coordinator
Aug 4 at 10:20 AM
hmm strange. I don't really use WriteSamples myself. Maybe there is an odd bug in there somewhere.