private void MIDIConversionTbT(Control Form, Panel ThreadsPanel, String OPath) { try { Status = "prep"; Int32 MT = Properties.Settings.Default.MultiThreadedMode ? Properties.Settings.Default.MultiThreadedLimitV : 1; WaveFormat WF = new WaveFormat(Properties.Settings.Default.Frequency, 32, 2, AudioEncoding.IeeeFloat); // Initialize BASS Debug.PrintToConsole("ok", "Initializing BASS..."); if (!Bass.BASS_Init(0, WF.SampleRate, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)) { throw new Exception("Unable to initialize BASS!"); } LoadSoundFonts(); foreach (MIDI MFile in Program.MIDIList) { MultiStreamMerger MSM = new MultiStreamMerger(WF); if (StopRequested) { Debug.PrintToConsole("ok", "Stop requested. Stopping foreach loop..."); break; } MDV.SetTotalTracks(MFile.Tracks); MDV.ResetCurrentTrack(); // Begin conversion Status = "mconv"; try { CTS = new CancellationTokenSource(); Debug.PrintToConsole("ok", String.Format("Preparing loop... MaxDegreeOfParallelism = {0}", MT)); ParallelFor(0, MFile.Tracks, MT, CTS.Token, T => { if (StopRequested) { Debug.PrintToConsole("ok", "Stop requested. Stopping Parallel.For..."); //LS.Stop(); return; } if (MFile.NoteCount > 0) { TrackThreadStatus Trck = new TrackThreadStatus(T); Trck.Dock = DockStyle.Top; ThreadsPanel.Invoke((MethodInvoker) delegate { Debug.PrintToConsole("ok", "Added TrackThreadStatus control for MIDI."); ThreadsPanel.Controls.Add(Trck); }); ConvertWorker Worker = new ConvertWorker(MFile.GetSingleTrackTimeBased(T), MFile.TimeLength.TotalSeconds); ISampleWriter Writer; WaveWriter SDestination = null; FileStream SFOpen = null; if (Properties.Settings.Default.PerTrackSeparateFiles) { // Check if we need to export each track to a file String Folder = OPath; if (Properties.Settings.Default.PerTrackSeparateFiles) { // We do, create folder Folder += String.Format("\\{0}\\", Path.GetFileNameWithoutExtension(MFile.Name)); if (!Directory.Exists(Folder)) { Directory.CreateDirectory(Folder); } } else { Folder += " "; } // Prepare the filename String SOutputDir = String.Format("{0}Track {1}.{2}", Folder, T, Properties.Settings.Default.Codec); // Check if file already exists if (File.Exists(SOutputDir)) { SOutputDir = String.Format("{0}Track {1} - {2}.{3}", Folder, T, DateTime.Now.ToString("dd-MM-yyyy HHmmsstt"), Properties.Settings.Default.Codec); } Debug.PrintToConsole("ok", String.Format("{0} - Output file: {1}", T, SOutputDir)); SFOpen = File.Open(SOutputDir, FileMode.Create); SDestination = new WaveWriter(SFOpen, WF); Writer = new WaveSampleWriter(SDestination); } else { Writer = MSM.GetWriter(); } Task ConvThread = Task.Run(() => { Worker.Convert(Writer, WF, false, CTS.Token); }); while (!ConvThread.IsCompleted) { if (StopRequested) { break; } Trck.Invoke((MethodInvoker) delegate { Trck.UpdatePB(Convert.ToInt32(Math.Round(Worker.Progress * 100))); }); Thread.Sleep(10); } ConvThread.Wait(); if (SDestination != null) { SDestination.Dispose(); } if (SFOpen != null) { SFOpen.Dispose(); } ThreadsPanel.Invoke((MethodInvoker) delegate { Debug.PrintToConsole("ok", String.Format("{0} - Removed TrackThreadStatus control for MIDI.", T)); ThreadsPanel.Controls.Remove(Trck); }); if (!StopRequested) { MDV.AddTrack(); } } }); } catch (OperationCanceledException) { } finally { CTS.Dispose(); CTS = null; } if (StopRequested) { break; } else { MDV.AddValidMIDI(); } // Time to save the file String OutputDir = String.Format("{0}\\{1}.{2}", OPath, Path.GetFileNameWithoutExtension(MFile.Name), Properties.Settings.Default.Codec); // Check if file already exists if (File.Exists(OutputDir)) { OutputDir = String.Format("{0}\\{1} - {2}.{3}", OPath, Path.GetFileNameWithoutExtension(MFile.Name), DateTime.Now.ToString("dd-MM-yyyy HHmmsstt"), Properties.Settings.Default.Codec); } Debug.PrintToConsole("ok", String.Format("Output file: {0}", OutputDir)); // Reset MSM position MSM.Position = 0; // Prepare wave source IWaveSource MStream; if (Properties.Settings.Default.LoudMax) { Debug.PrintToConsole("ok", "LoudMax enabled."); AntiClipping BAC = new AntiClipping(MSM, 0.1); MStream = BAC.ToWaveSource(32); } else { MStream = MSM.ToWaveSource(32); } FileStream FOpen = File.Open(OutputDir, FileMode.Create); WaveWriter Destination = new WaveWriter(FOpen, WF); Debug.PrintToConsole("ok", "Output file is open."); Int32 FRead = 0; byte[] FBuffer = new byte[1024 * 16]; Status = "aout"; Debug.PrintToConsole("ok", String.Format("Writing data for {0} to disk...", OutputDir)); while ((FRead = MStream.Read(FBuffer, 0, FBuffer.Length)) != 0) { Destination.Write(FBuffer, 0, FRead); } Debug.PrintToConsole("ok", String.Format("Done writing {0}.", OutputDir)); Destination.Dispose(); FOpen.Dispose(); } FreeSoundFonts(); Debug.PrintToConsole("ok", "BASS freed."); Bass.BASS_Free(); } catch (Exception ex) { Status = "crsh"; StError = String.Format("The converter encountered an error during the conversion process.\nError: {0}", ex.Message.ToString()); IsCrash = true; Debug.PrintToConsole("err", String.Format("{0} - {1}", ex.InnerException.ToString(), ex.Message.ToString())); } if (!StopRequested && !IsCrash) { Form.Invoke((MethodInvoker) delegate { ((Form)Form).Close(); }); } }
private void MIDIConversion(Control Form, Panel ThreadsPanel, String OPath) { try { Status = "prep"; Int32 MT = Properties.Settings.Default.MultiThreadedMode ? Properties.Settings.Default.MultiThreadedLimitV : 1; WaveFormat WF = new WaveFormat(Properties.Settings.Default.Frequency, 32, 2, AudioEncoding.IeeeFloat); Debug.PrintToConsole("ok", "Initializing BASS..."); if (!Bass.BASS_Init(0, WF.SampleRate, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)) { throw new Exception("Unable to initialize BASS!"); } LoadSoundFonts(); try { Debug.PrintToConsole("ok", "Preparing Parallel.ForEach loop..."); CTS = new CancellationTokenSource(); ParallelOptions PO = new ParallelOptions { MaxDegreeOfParallelism = MT, CancellationToken = CTS.Token }; Debug.PrintToConsole("ok", String.Format("ParallelOptions prepared, MaxDegreeOfParallelism = {0}", MT)); Parallel.ForEach(Program.MIDIList, PO, (MFile, LS) => { if (StopRequested) { Debug.PrintToConsole("ok", "Stop requested. Stopping Parallel.ForEach..."); LS.Stop(); return; } IWaveSource Stream; // Begin conversion Status = "sconv"; MDV.SetCurrentMIDI(MFile.Path); // Prepare the filename String OutputDir = String.Format("{0}\\{1}.{2}", OPath, Path.GetFileNameWithoutExtension(MFile.Name), Properties.Settings.Default.Codec); // Check if file already exists if (File.Exists(OutputDir)) { OutputDir = String.Format("{0}\\{1} - {2}.{3}", OPath, Path.GetFileNameWithoutExtension(MFile.Name), DateTime.Now.ToString("dd-MM-yyyy HHmmsstt"), Properties.Settings.Default.Codec); } Debug.PrintToConsole("ok", String.Format("Output file: {0}", OutputDir)); MIDIThreadStatus MIDIT = new MIDIThreadStatus(MFile.Name); MIDIT.Dock = DockStyle.Top; ThreadsPanel.Invoke((MethodInvoker) delegate { Debug.PrintToConsole("ok", "Added MIDIThreadStatus control for MIDI."); ThreadsPanel.Controls.Add(MIDIT); }); ConvertWorker Worker = new ConvertWorker(MFile.GetFullMIDITimeBased(), MFile.TimeLength.TotalSeconds); Stream FOpen = new BufferedStream(File.Open(OutputDir, FileMode.Create), 65536); WaveWriter Destination = new WaveWriter(FOpen, WF); ISampleWriter Writer = new WaveSampleWriter(Destination); Debug.PrintToConsole("ok", "Output file is open."); Task ConvThread = Task.Run(() => { Worker.Convert(Writer, WF, Properties.Settings.Default.LoudMax, PO.CancellationToken); }); while (!ConvThread.IsCompleted) { if (StopRequested) { break; } MIDIT.Invoke((MethodInvoker) delegate { MIDIT.UpdatePB(Convert.ToInt32(Math.Round(Worker.Progress * 100))); }); Thread.Sleep(200); } ConvThread.Wait(); Debug.PrintToConsole("ok", String.Format("Thread for MIDI {0} is done rendering data.", OutputDir)); ThreadsPanel.Invoke((MethodInvoker) delegate { Debug.PrintToConsole("ok", "Removed MIDIThreadStatus control for MIDI."); ThreadsPanel.Controls.Remove(MIDIT); }); if (!StopRequested) { MDV.AddValidMIDI(); } Destination.Dispose(); FOpen.Dispose(); }); } catch (OperationCanceledException) { } finally { CTS.Dispose(); CTS = null; } FreeSoundFonts(); Debug.PrintToConsole("ok", "BASS freed."); Bass.BASS_Free(); } catch (Exception ex) { Status = "crsh"; StError = String.Format("The converter encountered an error during the conversion process.\nError: {0}", ex.Message.ToString()); IsCrash = true; Debug.PrintToConsole("err", String.Format("{0} - {1}", ex.InnerException.ToString(), ex.Message.ToString())); } if (!StopRequested && !IsCrash) { Form.Invoke((MethodInvoker) delegate { ((Form)Form).Close(); }); } }