// for now assume 16-bit LE PCM, reinterleavein towav output public static void InterleaveRiffToWavOutputFiles(string[] inputFiles, string outputFile, InterleaveRiffFilesOptionsStruct interleaveOptions) { // verify that two or more files have been input if (inputFiles.Length < 2) { throw new Exception("More than one file must be input for interleaving."); } // verify features match if (!inputFilesHaveEqualFeatures(inputFiles)) { throw new Exception("Input files must have same channel count and frequency."); } // interleave data interleaveDataChunks(inputFiles, outputFile, interleaveOptions); // update RIFF header }
private static string interleaveDataChunks(string[] inputFiles, string outputFile, InterleaveRiffFilesOptionsStruct interleaveOptions) { Dictionary <int, FileStream> inputFileHash = new Dictionary <int, FileStream>(); FileStream outputStream = null; string interleavedFilePath = String.Format("{0}.interleaved.data{1}", Path.GetFileNameWithoutExtension(outputFile), Path.GetExtension(outputFile)); uint maxDataSize = 0; uint bytesProcessed = 0; byte[] bytes = new byte[2]; int bytesRead; uint[] dataSizes = new uint[inputFiles.Length]; long[] dataStartOffset = new long[inputFiles.Length]; long[] fileSizes = new long[inputFiles.Length]; try { // open file streams and get data location info for (int i = 0; i < inputFiles.Length; i++) { using (FileStream fs = File.OpenRead(inputFiles[i])) { inputFileHash.Add(i, fs); dataSizes[i] = GetDataSizeFromRiffHeader(inputFileHash[i]); dataStartOffset[i] = GetDataStartOffsetFromRiffHeader(inputFileHash[i]); fileSizes[i] = inputFileHash[i].Length; if (dataSizes[i] > maxDataSize) { maxDataSize = dataSizes[i]; } } } // write output file (16-bit LE PCM assumed) using (outputStream = File.OpenWrite(interleavedFilePath)) { // move to data section for (int i = 0; i < inputFiles.Length; i++) { inputFileHash[i].Position = dataStartOffset[i]; } // write to file while (bytesProcessed <= maxDataSize) { for (int i = 0; i < inputFiles.Length; i++) { // read bytes bytesRead = inputFileHash[i].Read(bytes, 0, 2); // insert filler bytes for (int j = bytesRead; j < 2; j++) { bytes[j] = interleaveOptions.FillerByte; } // write bytes to output file outputStream.Write(bytes, 0, 2); } bytesProcessed += 2; } } } finally { // close all streams foreach (int k in inputFileHash.Keys) { if ((inputFileHash[k] != null) && (inputFileHash[k].CanRead)) { inputFileHash[k].Close(); inputFileHash[k].Dispose(); } } if ((outputStream != null) && (outputStream.CanWrite)) { outputStream.Close(); outputStream.Dispose(); } } return(interleavedFilePath); }