/// <summary> /// Get WAV file header. /// </summary> /// <param name="fileNames">The file names.</param> /// <param name="setOutput">Set output string action.</param> public void GetWavHeader(string[] fileNames, Action <string> setOutput) { var sb = new StringBuilder(); int totalFiles = 0; foreach (string fileName in fileNames) { try { using (var fs = File.OpenRead(fileName)) { var h = WavFileInfo.ReadFileHeader(fs); if (totalFiles > 0) { sb.Append("\n\n"); } sb.Append( string.Format( "FileName:\t\t{0}\nFileSize:\t\t{1}\n{2}", Path.GetFileName(fileName), fs.Length.ToString(), h.ToString())); totalFiles++; } } catch (Exception ex) { string text = string.Format("Error: {0}\n", ex.Message); sb.Append(text); setOutput(sb.ToString()); } } setOutput(sb.ToString()); }
/// <summary> /// Split multi-channel WAV file into single channel WAV files. /// </summary> /// <param name="fileName">Input WAV file name.</param> /// <param name="outputPath">Output WAV files path.</param> /// <param name="ct">Cancellation token.</param> /// <returns>The total processed bytes.</returns> public long SplitWavFile(string fileName, string outputPath, CancellationToken ct) { long countBytesTotal = 0; long countBytes = 0; var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); var header = WavFileInfo.ReadFileHeader(fs); Progress(0.0); countBytes += header.HeaderSize; countBytesTotal += header.HeaderSize; string fileNameOnly = Path.GetFileNameWithoutExtension(fileName); string[] outputFileNames = new string[header.NumChannels]; WavChannel[] channels = new WavChannel[header.NumChannels]; int countChannels = 0; if (header.IsExtensible == false) { for (int c = 0; c < header.NumChannels; c++) { string numnber = (c + 1).ToString("D2"); var ch = new WavChannel("Channel" + numnber, "CH" + numnber, 0); channels[c] = ch; } } else { foreach (WavChannel ch in WavFileHeader.WavMultiChannelTypes) { if (((uint)ch.Mask & header.ChannelMask) != 0) { channels[countChannels++] = ch; } } } for (int p = 0; p < channels.Count(); p++) { outputFileNames[p] = outputPath + fileNameOnly + "." + channels[p].ShortName + ".wav"; } long dataSize = header.Subchunk2Size; int bufferSize = (int)header.ByteRate; int channelBufferSize = (int)(header.ByteRate / header.NumChannels); byte[] buffer = new byte[bufferSize]; byte[][] channelBuffer = new byte[header.NumChannels][]; int copySize = header.BlockAlign / header.NumChannels; var outputFiles = new FileStream[header.NumChannels]; var mh = WavFileInfo.GetMonoWavFileHeader(header); for (int c = 0; c < header.NumChannels; c++) { channelBuffer[c] = new byte[channelBufferSize]; outputFiles[c] = new FileStream(outputFileNames[c], FileMode.Create, FileAccess.ReadWrite); WavFileInfo.WriteFileHeader(outputFiles[c], mh); } var cleanUp = new Action(() => { fs.Dispose(); for (int c = 0; c < header.NumChannels; c++) { outputFiles[c].Dispose(); } }); for (long i = 0; i < dataSize; i += bufferSize) { int n = fs.Read(buffer, 0, bufferSize); if (n > 0) { int[] count = new int[header.NumChannels]; for (int j = 0; j < n; j += header.BlockAlign) { for (int c = 0; c < header.NumChannels; c++) { for (int k = 0; k < copySize; k++) { channelBuffer[c][count[c]++] = buffer[j + (c * copySize) + k]; } } } for (int c = 0; c < header.NumChannels; c++) { outputFiles[c].Write(channelBuffer[c], 0, count[c]); } if (ct.IsCancellationRequested) { cleanUp(); ct.ThrowIfCancellationRequested(); } countBytes += n; countBytesTotal += n; Progress((countBytes / fs.Length) * 100.0); } } cleanUp(); return(countBytesTotal); }