/// <summary> /// Recursively merge all files in a directory with a WAV header /// </summary> /// <param name="dir">Merging directory</param> /// <returns></returns> private IEnumerable <FileInfo> CollapseWaves(DirectoryInfo dir) { const short CHANNELS = 1; const int SAMPLE_RATE = 16000; const short BITS_PER_SAMPLE = 16; const int HEADER_SIZE = 44; //size of a wav header //these are all case-sensitive / length-sensitive const string RIFF = "RIFF"; const string WAVEfmt = "WAVEfmt "; const string DATA = "data"; var files = dir.GetFiles().Where(f => f.Extension.ToLower() == ".wav" || f.Extension.ToLower() == ".efd"); if (files.Count() <= 1) { return(files); } else { //get first file in the directory var first = new FileStream(files.ElementAt(0).FullName, FileMode.Open, FileAccess.Read); //get second file var second = new FileStream(files.ElementAt(1).FullName, FileMode.Open, FileAccess.Read); //each file has a header, so add the total bytes and then subtract the header size for each int length = (int)(first.Length + second.Length - (2 * HEADER_SIZE)); var merged = new FileStream(Path.Combine(dir.FullName, Path.GetRandomFileName()) + ".wav", FileMode.Create, FileAccess.Write); var bw = new BinaryWriter(merged); bw.Write(RIFF.ToCharArray()); bw.Write(length + HEADER_SIZE); bw.Write(WAVEfmt.ToCharArray()); //chunk information and audio format info bw.Write((int)16); bw.Write((short)1); bw.Write(CHANNELS); bw.Write(SAMPLE_RATE); bw.Write((int)(SAMPLE_RATE * ((BITS_PER_SAMPLE * CHANNELS) / 8))); bw.Write((short)((BITS_PER_SAMPLE * CHANNELS) / 8)); bw.Write(BITS_PER_SAMPLE); bw.Write(DATA.ToCharArray()); bw.Write(length); //read the files with an offset of the headersize byte[] arrFirst = new byte[first.Length]; first.Read(arrFirst, HEADER_SIZE, arrFirst.Length - HEADER_SIZE); byte[] arrSecond = new byte[second.Length]; second.Read(arrSecond, HEADER_SIZE, arrSecond.Length - HEADER_SIZE); first.Close(); second.Close(); bw.Write(arrFirst); bw.Write(arrSecond); bw.Close(); merged.Close(); //delete merged files File.Delete(files.ElementAt(0).FullName); File.Delete(files.ElementAt(1).FullName); return(CollapseWaves(dir)); } }