0

I need to join 2 WAV files which are in a byte array by C#. I'm getting this exception:

Not a WAVE file - no RIFF header

As I got from the net when I was searching about it, the issue is about the header of the byte array that is not in WAV format. But I couldn't find any help about adding header. This is my code:

public static void Concatenate(string outputFile, IEnumerable<byte[]> sourceFiles)
{
    byte[] buffer = new byte[1024];
    WaveFileWriter waveFileWriter = null;

    try
    {
        foreach (byte[] sourceFile in sourceFiles)
        {
            Stream streamReader = new MemoryStream(sourceFile);
            using (WaveFileReader reader = new WaveFileReader(streamReader))
            {
                if (waveFileWriter == null)
                {
                    // first time in create new Writer
                    waveFileWriter = new WaveFileWriter(outputFile, reader.WaveFormat);
                }
                else
                {
                    if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat))
                    {
                        throw new InvalidOperationException("Can't concatenate WAV Files that don't share the same format");
                    }
                }

                int read;
                while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
                {
                    waveFileWriter.WriteData(buffer, 0, read);
                }
            }
        }
    }
    finally
    {
        if (waveFileWriter != null)
        {
            waveFileWriter.Dispose();
        }
    }
}

How can I add a WAV file header to byte array? And other question: I have to add the header to the byte arrays one by one or first concat two byte arrays and then add header?

  • I don't know NAudio, but if both files are in exactly the same audio format (codec, bits, stereo, data rate) then you can likely just concatenate the data chunks. (Assuming PCM, or a packet-based codec that just accepts concatenation, but AFAIK they all do: most will encode a 'reset encoding state' into the first packet.) Otherwise you'll have to convert one to match the other first, then you can append. I'd assume WavFileReader and Writer will manage the headers for you? – Rup Sep 24 '18 at 09:43
  • 1
    You are using a library to read the wave file. The library is throwing an error that the bytes you are giving it **is not compatible with that library**. . Just because it has an extension of .wav does not mean it is encoded in a standard way. They could be 8bit.16bit,32bit, 48khz? proprietory compression? – Piotr Kula Sep 24 '18 at 09:43
  • 2
    @ppumkin OK, but anything with a .wav extension ought to start with a RIFF header even if it's using a non-standard codec. The non-standard bit will be in the fmt chunk. – Rup Sep 24 '18 at 09:45
  • 1
    But does it...? Open it in a hex viewer and check the header is there. Also, there seems to be a bug related to this? https://stackoverflow.com/questions/24824027/not-a-wave-file-no-riff-header-locks-file – Piotr Kula Sep 24 '18 at 09:46
  • @Rup: from what I saw from a quick google riff headers have a file size field so you'll need to adjust that as well as concatenating (unless modern stuff just ignores that value in favour of the actual file size). – Chris Sep 24 '18 at 09:46
  • 2
    Are you sure the files are both OK (in correct format)? I saw many times WAVE files renamed to MP3, but also MP3 renamed to WAV.. – Julo Sep 24 '18 at 09:47
  • @Chris Yes, true. I'd assume that a class called WavFileWriter will take care of the chunk lengths etc. – Rup Sep 24 '18 at 09:48
  • @ppumkin I'm saving wav file byte array in my db by ReadToEnd() function in HttpPostedFileBase – Hossein Gholizadeh Sep 24 '18 at 09:49
  • @Rup: Oh, I see. For some reason I thought you were suggesting just working directly on the byte arrays. Sorry! – Chris Sep 24 '18 at 09:50
  • 1
    Are you saving just the audio data in the byte array? If so, do you know the audio format? That is, encoding type, sample rate, bits per sample, etc.? – Ian Sep 24 '18 at 10:09
  • @lan I'm saving just byte array from HttpPostedFileBase.with no other properties about it's type. – Hossein Gholizadeh Sep 24 '18 at 10:21
  • 1
    But what is in the byte array? – Ian Sep 24 '18 at 10:24
  • that's recorded wav file byte array – Hossein Gholizadeh Sep 24 '18 at 10:32
  • So it's read in from a physical file? Can a standard media player like VLC or WMP play the WAV file? – Ian Sep 24 '18 at 10:36
  • No i'm recording it.that's not a physical file – Hossein Gholizadeh Sep 24 '18 at 10:37
  • 1
    Oh I see. So you're recording a byte stream, which will be just the audio data. In this case you will be able to determine the audio format as you'll need to specify it before starting recording, or some default parameters will be used. Either way, the method you've posted assumes each byte array has a header, and you'll need to add it. – Ian Sep 24 '18 at 10:41
  • Possible duplicate of [Create valid wav file header for streams in memory](https://stackoverflow.com/questions/22695723/create-valid-wav-file-header-for-streams-in-memory) – Ian Sep 24 '18 at 10:42
  • Or of you do think that there's a header on this file, please can you try saving it to disk as a .wav file then testing with with e.g. ffprobe from ffmpeg to see what type of file it thinks it is? – Rup Sep 24 '18 at 10:42
  • yeah the issue is from my recorder.beacuse when i save wav file by upload it's correct but when i record it,it's wrong.OK,I'm going to save recorder file and test it – Hossein Gholizadeh Sep 24 '18 at 10:47

0 Answers0