1

I'm using irrKlang to get audio input from a mic. That part works great, but I'm having problems saving the output to a .wav...

The wave file appears to save ok, but it doesn't seem to play. I'm wondering if my header is some how formatted wrong:

    private void SaveWave(string path, AudioFormat format, byte[] waveData)
    {
        //Play the audio for testing purposes
        ss = engine0.AddSoundSourceFromPCMData(waveData, "sound", format);
        engine0.Play2D(ss, true, false, false);

        // write wave header 
        ushort formatType = 1;
        ushort numChannels = (ushort)format.ChannelCount;
        ulong sampleRate = (ulong)format.SampleRate;
        ushort bitsPerChannel = (ushort)(format.SampleSize * 8);
        ushort bytesPerSample = (ushort)format.FrameSize;
        ulong bytesPerSecond = (ulong)format.BytesPerSecond;
        ulong dataLen = (ulong)format.SampleDataSize;

        const int fmtChunkLen = 16;
        const int waveHeaderLen = 4 + 8 + fmtChunkLen + 8;

        ulong totalLen = waveHeaderLen + dataLen;
        ///
        FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
        BinaryWriter bw = new BinaryWriter(fs);
        byte[] riff = System.Text.Encoding.ASCII.GetBytes("RIFF");
        bw.Write(riff);
        bw.Write(totalLen);
        byte[] fmt = System.Text.Encoding.ASCII.GetBytes("WAVEfmt ");
        bw.Write(fmt);
        bw.Write(fmtChunkLen);
        bw.Write(formatType);
        bw.Write(numChannels);
        bw.Write(sampleRate);
        bw.Write(bytesPerSecond);
        bw.Write(bytesPerSample);
        bw.Write(bitsPerChannel);
        byte[] data = System.Text.Encoding.ASCII.GetBytes("data");
        bw.Write(data);
        bw.Write(waveData.Length);
        bw.Write(waveData);
        bw.Close();
        fs.Close();
    }
Taurian
  • 1,660
  • 7
  • 20
  • 28

1 Answers1

0

You're writing the string headers wrong.

BinaryWriter.Write(string) is not meant for writing like this. According to this msdn article, it prefixes it's length to the string before it writes.

You need to write those headers as bytes.

Do it like these,

byte[] riff= System.Text.Encoding.ASCII.GetBytes("RIFF");
bw.Write(riff);
byte[] fmt = System.Text.Encoding.ASCII.GetBytes("WAVEfmt ");
bw.Write(fmt);
// Remove the space in "data " to "data"
//byte[] data= System.Text.Encoding.ASCII.GetBytes("data ");
byte[] data= System.Text.Encoding.ASCII.GetBytes("data");
bw.Write(data);

Rest of the headers seem fine.

Hope this helps you

Vishnu Prasad V
  • 1,228
  • 1
  • 8
  • 18
  • Hey Vishnu, i've updated per your instructions. Same problem, it does save the .wav but it doesn't actually play. Are the spaces in the WAVEfmt supposed to be there? – Taurian Jun 28 '16 at 05:38
  • Bummer, no luck. Here's the error i get: http://imgur.com/gjJK0lu I'll also update the post with my code. – Taurian Jun 28 '16 at 05:48