From 53a5ac346e82dabcfc96a88ea9cc35e1dec9e0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Tue, 20 Nov 2012 20:43:43 +0100 Subject: [PATCH] Code cleanup --- .../SimpleWavSplitterWindow.xaml.cs | 350 +++++++++--------- WavFile/WavFileInfo.cs | 53 ++- 2 files changed, 204 insertions(+), 199 deletions(-) diff --git a/SimpleWavSplitter/SimpleWavSplitterWindow.xaml.cs b/SimpleWavSplitter/SimpleWavSplitterWindow.xaml.cs index bdefaba..5b8f055 100644 --- a/SimpleWavSplitter/SimpleWavSplitterWindow.xaml.cs +++ b/SimpleWavSplitter/SimpleWavSplitterWindow.xaml.cs @@ -79,13 +79,15 @@ namespace SimpleWavSplitter private static void GetWavHeader() { - Microsoft.Win32.OpenFileDialog d = new Microsoft.Win32.OpenFileDialog(); - d.Filter = "WAV Files (*.wav)|*.wav|All Files (*.*)|*.*"; - d.FilterIndex = 0; - d.Multiselect = true; - if (d.ShowDialog() == true) + var dlg = new Microsoft.Win32.OpenFileDialog(); + dlg.Filter = "WAV Files (*.wav)|*.wav|All Files (*.*)|*.*"; + dlg.FilterIndex = 0; + dlg.Multiselect = true; + + if (dlg.ShowDialog() == true) { - string[] fileNames = d.FileNames; + string[] fileNames = dlg.FileNames; + foreach (string fileName in fileNames) { // parse WAV file header @@ -95,7 +97,7 @@ namespace SimpleWavSplitter using (System.IO.FileStream f = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { // read WAV file header - WavFileHeader h = WavFileInfo.ReadFileHeader(f); + var h = WavFileInfo.ReadFileHeader(f); // show WAV header MessageBox.Show( @@ -117,211 +119,215 @@ namespace SimpleWavSplitter private void SplitWavFiles() { - Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); + var dlg = new Microsoft.Win32.OpenFileDialog(); dlg.Filter = "WAV Files (*.wav)|*.wav|All Files (*.*)|*.*"; dlg.FilterIndex = 0; dlg.Multiselect = true; + if (dlg.ShowDialog() == true) { - // reset window controls to defaults - progress.Value = 0; + SplitWavFiles(dlg.FileNames); + } + } - // create background worker - worker = new BackgroundWorker(); - worker.WorkerSupportsCancellation = true; + private void SplitWavFiles(string[] dlgFileNames) + { + // reset window controls to defaults + progress.Value = 0; - string dlgFileName = string.Copy(dlg.FileName); + // create background worker + worker = new BackgroundWorker(); + worker.WorkerSupportsCancellation = true; - worker.DoWork += (s, args) => + worker.DoWork += (s, args) => + { + string[] fileNames = (string[])args.Argument; + long countBytesTotal = 0; + var sw = new System.Diagnostics.Stopwatch(); + + sw.Start(); + + foreach (string fileName in fileNames) { - string[] fileNames = (string[])args.Argument; - long countBytesTotal = 0; - var sw = new System.Diagnostics.Stopwatch(); - - sw.Start(); - - foreach (string fileName in fileNames) + // parse WAV file header + try { - // parse WAV file header - try + // update progress + Dispatcher.Invoke((Action)delegate() { - // update progress - Dispatcher.Invoke((Action)delegate() - { - progress.Value = 0.0; - }); + progress.Value = 0.0; + }); - // bytes counter - long countBytes = 0; + // bytes counter + long countBytes = 0; - // create WAV file stream - var f = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); + // create WAV file stream + var f = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); - // read WAV file header - WavFileHeader h = WavFileInfo.ReadFileHeader(f); + // read WAV file header + WavFileHeader h = WavFileInfo.ReadFileHeader(f); - countBytes += h.HeaderSize; - countBytesTotal += h.HeaderSize; + countBytes += h.HeaderSize; + countBytesTotal += h.HeaderSize; - // print debug - System.Diagnostics.Debug.Print(string.Format("FileName: {0}, Header:\n{1}", - fileName, - h.ToString())); + // print debug + System.Diagnostics.Debug.Print(string.Format("FileName: {0}, Header:\n{1}", + fileName, + h.ToString())); - // create output filenames - string filePath = dlgFileName.Remove(fileName.Length - System.IO.Path.GetFileName(fileName).Length); - string fileNameOnly = System.IO.Path.GetFileNameWithoutExtension(fileName); - string[] outputFileNames = new string[h.NumChannels]; - WavChannel[] channels = new WavChannel[h.NumChannels]; - int countChannels = 0; + // create output filenames + string filePath = fileName.Remove(fileName.Length - System.IO.Path.GetFileName(fileName).Length); + string fileNameOnly = System.IO.Path.GetFileNameWithoutExtension(fileName); + string[] outputFileNames = new string[h.NumChannels]; + WavChannel[] channels = new WavChannel[h.NumChannels]; + int countChannels = 0; - // set channel names - if (h.IsExtensible == false) - { - for (int c = 0; c < h.NumChannels; c++) - { - string chNum = (c + 1).ToString("D2"); - WavChannel ch = new WavChannel("Channel" + chNum, "CH" + chNum, 0); - channels[c] = ch; - } - } - else - { - foreach (WavChannel ch in WavFileHeader.WavMultiChannelTypes) - { - if (((uint)ch.Mask & h.ChannelMask) != 0) - channels[countChannels++] = ch; - } - } - - // join: input path + input file name without extension + ''. + short channel name + '.wav' extension - for (int p = 0; p < channels.Count(); p++) - { - outputFileNames[p] = filePath + fileNameOnly + "." + channels[p].ShortName + ".wav"; - } - - // create data buffers - long dataSize = h.Subchunk2Size; - int bufferSize = (int)h.ByteRate; - int channelBufferSize = (int)(h.ByteRate / h.NumChannels); - byte[] buffer = new byte[bufferSize]; - byte[][] channelBuffer = new byte[h.NumChannels][]; - int copySize = h.BlockAlign / h.NumChannels; - - // create output files - System.IO.FileStream[] outputFile = new System.IO.FileStream[h.NumChannels]; - - // each mono output file has the same header - WavFileHeader monoFileHeader = WavFileInfo.GetMonoWavFileHeader(h); - - // write output files header and create temp buffer for each channel + // set channel names + if (h.IsExtensible == false) + { for (int c = 0; c < h.NumChannels; c++) { - channelBuffer[c] = new byte[channelBufferSize]; - outputFile[c] = new System.IO.FileStream(outputFileNames[c], System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite); - - WavFileInfo.WriteFileHeader(outputFile[c], monoFileHeader); + string chNum = (c + 1).ToString("D2"); + var ch = new WavChannel("Channel" + chNum, "CH" + chNum, 0); + channels[c] = ch; } - - // cleanup action - var cleanUp = new Action(() => + } + else + { + foreach (WavChannel ch in WavFileHeader.WavMultiChannelTypes) { - // close input file - f.Close(); - f.Dispose(); + if (((uint)ch.Mask & h.ChannelMask) != 0) + channels[countChannels++] = ch; + } + } - // close output files - for (int c = 0; c < h.NumChannels; c++) - { - outputFile[c].Close(); - outputFile[c].Dispose(); - } - }); + // join: input path + input file name without extension + ''. + short channel name + '.wav' extension + for (int p = 0; p < channels.Count(); p++) + { + outputFileNames[p] = filePath + fileNameOnly + "." + channels[p].ShortName + ".wav"; + } - // read data from input file and write to multiple-output files - for (long i = 0; i < dataSize; i += bufferSize) + // create data buffers + long dataSize = h.Subchunk2Size; + int bufferSize = (int)h.ByteRate; + int channelBufferSize = (int)(h.ByteRate / h.NumChannels); + byte[] buffer = new byte[bufferSize]; + byte[][] channelBuffer = new byte[h.NumChannels][]; + int copySize = h.BlockAlign / h.NumChannels; + + // create output files + System.IO.FileStream[] outputFile = new System.IO.FileStream[h.NumChannels]; + + // each mono output file has the same header + WavFileHeader mh = WavFileInfo.GetMonoWavFileHeader(h); + + // write output files header and create temp buffer for each channel + for (int c = 0; c < h.NumChannels; c++) + { + channelBuffer[c] = new byte[channelBufferSize]; + outputFile[c] = new System.IO.FileStream(outputFileNames[c], System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite); + + WavFileInfo.WriteFileHeader(outputFile[c], mh); + } + + // cleanup action + var cleanUp = new Action(() => + { + // close input file + f.Close(); + f.Dispose(); + + // close output files + for (int c = 0; c < h.NumChannels; c++) { - int n = f.Read(buffer, 0, bufferSize); - if (n > 0) + outputFile[c].Close(); + outputFile[c].Dispose(); + } + }); + + // read data from input file and write to multiple-output files + for (long i = 0; i < dataSize; i += bufferSize) + { + int n = f.Read(buffer, 0, bufferSize); + if (n > 0) + { + // split channel data + int[] count = new int[h.NumChannels]; + + for (int j = 0; j < n; j += h.BlockAlign) { - // split channel data - int[] count = new int[h.NumChannels]; - - for (int j = 0; j < n; j += h.BlockAlign) - { - for (int c = 0; c < h.NumChannels; c++) - { - for (int k = 0; k < copySize; k++) - { - channelBuffer[c][count[c]++] = buffer[j + (c * copySize) + k]; - } - } - } - - // write single channel data to a file for (int c = 0; c < h.NumChannels; c++) { - outputFile[c].Write(channelBuffer[c], 0, count[c]); + for (int k = 0; k < copySize; k++) + { + channelBuffer[c][count[c]++] = buffer[j + (c * copySize) + k]; + } } - - // cancel background job - if (worker.CancellationPending) - { - cleanUp(); - - // cancel job - args.Cancel = true; - return; - } - - // update stats - countBytes += n; - countBytesTotal += n; - - // update progress - Dispatcher.Invoke((Action)delegate() - { - progress.Value = ((double)countBytes / (double)f.Length) * 100; - }); } + + // write single channel data to a file + for (int c = 0; c < h.NumChannels; c++) + { + outputFile[c].Write(channelBuffer[c], 0, count[c]); + } + + // cancel background job + if (worker.CancellationPending) + { + cleanUp(); + + // cancel job + args.Cancel = true; + return; + } + + // update stats + countBytes += n; + countBytesTotal += n; + + // update progress + Dispatcher.Invoke((Action)delegate() + { + progress.Value = ((double)countBytes / (double)f.Length) * 100; + }); } + } - cleanUp(); - } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); - } + cleanUp(); } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + } - sw.Stop(); + sw.Stop(); - args.Result = new Tuple(sw.Elapsed, countBytesTotal); - }; + args.Result = new Tuple(sw.Elapsed, countBytesTotal); + }; - worker.RunWorkerCompleted += (s, args) => + worker.RunWorkerCompleted += (s, args) => + { + if (args.Cancelled == false) { - if (args.Cancelled == false) - { - //SplitWorkResult result = (SplitWorkResult)args.Result; - Tuple result = (Tuple)args.Result; + //SplitWorkResult result = (SplitWorkResult)args.Result; + Tuple result = (Tuple)args.Result; - string stats = string.Format("Total data bytes processed: {0} ({1} MB)\nTotal elapsed time: {2}", - result.Item2, - Math.Round((double)result.Item2 / (1024 * 1024), 1), - result.Item1); + string stats = string.Format("Total data bytes processed: {0} ({1} MB)\nTotal elapsed time: {2}", + result.Item2, + Math.Round((double)result.Item2 / (1024 * 1024), 1), + result.Item1); - // show statistics to user - MessageBox.Show(stats, "Done", MessageBoxButton.OK, MessageBoxImage.Information); - } - else - { - progress.Value = 0; - } - }; + // show statistics to user + MessageBox.Show(stats, "Done", MessageBoxButton.OK, MessageBoxImage.Information); + } + else + { + progress.Value = 0; + } + }; - worker.RunWorkerAsync(dlg.FileNames); - } + worker.RunWorkerAsync(dlgFileNames); } private void CancelSplitWorker() diff --git a/WavFile/WavFileInfo.cs b/WavFile/WavFileInfo.cs index 7e10661..0634189 100644 --- a/WavFile/WavFileInfo.cs +++ b/WavFile/WavFileInfo.cs @@ -23,11 +23,12 @@ namespace WavFile /// public static WavFileHeader ReadFileHeader(System.IO.FileStream f) { - WavFileHeader h = new WavFileHeader(); + var h = new WavFileHeader(); + h.HeaderSize = 0; // read WAV header - System.IO.BinaryReader b = new System.IO.BinaryReader(f); + var b = new System.IO.BinaryReader(f); // WAVE h.ChunkID = b.ReadUInt32(); // 0x46464952, "RIFF" @@ -148,7 +149,7 @@ namespace WavFile public static void WriteFileHeader(System.IO.FileStream f, WavFileHeader h) { // write WAV header - System.IO.BinaryWriter b = new System.IO.BinaryWriter(f); + var b = new System.IO.BinaryWriter(f); // WAVE b.Write((UInt32)0x46464952); // 0x46464952, "RIFF" @@ -197,42 +198,40 @@ namespace WavFile public static WavFileHeader GetMonoWavFileHeader(WavFileHeader h) { // each mono output file has the same header - WavFileHeader monoFileHeader = new WavFileHeader(); + var mh = new WavFileHeader(); // WAVE - monoFileHeader.ChunkID = (UInt32)0x46464952; // 0x46464952, "RIFF" - monoFileHeader.ChunkSize = 36 + (h.Subchunk2Size / h.NumChannels); // 36 + SubChunk2Size, 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) - monoFileHeader.Format = (UInt32)0x45564157; // 0x45564157, "WAVE" + mh.ChunkID = (UInt32)0x46464952; // 0x46464952, "RIFF" + mh.ChunkSize = 36 + (h.Subchunk2Size / h.NumChannels); // 36 + SubChunk2Size, 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) + mh.Format = (UInt32)0x45564157; // 0x45564157, "WAVE" // fmt - monoFileHeader.Subchunk1ID = (UInt32)0x20746d66; // 0x20746d66, "fmt " - monoFileHeader.Subchunk1Size = 16; // 16 for PCM, 40 for WAVEFORMATEXTENSIBLE - monoFileHeader.AudioFormat = (UInt16)1; // PCM = 1, WAVEFORMATEXTENSIBLE.SubFormat = 0xFFFE - monoFileHeader.NumChannels = (UInt16)1; // Mono = 1, Stereo = 2, etc. - monoFileHeader.SampleRate = h.SampleRate; // 8000, 44100, etc. - monoFileHeader.ByteRate = (UInt32)((h.SampleRate * 1 * h.BitsPerSample) / 8); // SampleRate * NumChannels * BitsPerSample/8 - monoFileHeader.BlockAlign = (UInt16)((1 * h.BitsPerSample) / 8); // NumChannels * BitsPerSample/8 - monoFileHeader.BitsPerSample = h.BitsPerSample; // 8 bits = 8, 16 bits = 16, etc. + mh.Subchunk1ID = (UInt32)0x20746d66; // 0x20746d66, "fmt " + mh.Subchunk1Size = 16; // 16 for PCM, 40 for WAVEFORMATEXTENSIBLE + mh.AudioFormat = (UInt16)1; // PCM = 1, WAVEFORMATEXTENSIBLE.SubFormat = 0xFFFE + mh.NumChannels = (UInt16)1; // Mono = 1, Stereo = 2, etc. + mh.SampleRate = h.SampleRate; // 8000, 44100, etc. + mh.ByteRate = (UInt32)((h.SampleRate * 1 * h.BitsPerSample) / 8); // SampleRate * NumChannels * BitsPerSample/8 + mh.BlockAlign = (UInt16)((1 * h.BitsPerSample) / 8); // NumChannels * BitsPerSample/8 + mh.BitsPerSample = h.BitsPerSample; // 8 bits = 8, 16 bits = 16, etc. // extensible - monoFileHeader.ExtraParamSize = (UInt16)0; - monoFileHeader.ChannelMask = (UInt32)0; - monoFileHeader.GuidSubFormat = new Guid(); + mh.ExtraParamSize = (UInt16)0; + mh.ChannelMask = (UInt32)0; + mh.GuidSubFormat = new Guid(); // data - monoFileHeader.Subchunk2ID = (UInt32)0x61746164; // 0x61746164, "data" - monoFileHeader.Subchunk2Size = (h.Subchunk2Size / h.NumChannels); // NumSamples * NumChannels * BitsPerSample/8 + mh.Subchunk2ID = (UInt32)0x61746164; // 0x61746164, "data" + mh.Subchunk2Size = (h.Subchunk2Size / h.NumChannels); // NumSamples * NumChannels * BitsPerSample/8 // info - monoFileHeader.IsExtensible = false; - monoFileHeader.HeaderSize = 44; - monoFileHeader.TotalSamples = (long)((double)monoFileHeader.Subchunk2Size / ((double)monoFileHeader.NumChannels * (double)monoFileHeader.BitsPerSample / 8)); - monoFileHeader.Duration = (1 / (double)monoFileHeader.SampleRate) * (double)monoFileHeader.TotalSamples; + mh.IsExtensible = false; + mh.HeaderSize = 44; + mh.TotalSamples = (long)((double)mh.Subchunk2Size / ((double)mh.NumChannels * (double)mh.BitsPerSample / 8)); + mh.Duration = (1 / (double)mh.SampleRate) * (double)mh.TotalSamples; - return monoFileHeader; + return mh; } - - } #endregion