diff --git a/..svnbridge/.svnbridge b/..svnbridge/.svnbridge new file mode 100644 index 00000000..047b5e87 --- /dev/null +++ b/..svnbridge/.svnbridge @@ -0,0 +1,19 @@ +svn:ignore*.docstates +*.suo +Release-1.4 +TestResult.xml +obj +svn:ignore*.docstates +*.suo +Release-1.4 +TestResult.xml +obj +BuildArtefacts +svn:ignore*.docstates +*.suo +BuildArtefacts +Packages +Release-1.4 +TestResult.xml +obj + \ No newline at end of file diff --git a/.build/MSBuild.Community.Tasks.dll b/.build/MSBuild.Community.Tasks.dll new file mode 100644 index 00000000..01d1b09c Binary files /dev/null and b/.build/MSBuild.Community.Tasks.dll differ diff --git a/.build/MSBuild.Community.Tasks.targets b/.build/MSBuild.Community.Tasks.targets new file mode 100644 index 00000000..15310059 --- /dev/null +++ b/.build/MSBuild.Community.Tasks.targets @@ -0,0 +1,147 @@ + + + + + + $(MSBuildExtensionsPath)\MSBuildCommunityTasks + MSBuild.Community.Tasks.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.hgignore b/.hgignore new file mode 100644 index 00000000..776fd33a --- /dev/null +++ b/.hgignore @@ -0,0 +1,14 @@ +syntax: glob +bin/ +obj/ +[pP]ackages/ +AppPackages/ +TestResults/ +TestResult.xml +BuildArtefacts/ +_ReSharper.*/ +*.suo +*.ncrunchsolution +*.user +*.ncrunchproject +*.orig \ No newline at end of file diff --git a/AudioFileInspector/AboutForm.Designer.cs b/AudioFileInspector/AboutForm.Designer.cs new file mode 100644 index 00000000..bd8cd680 --- /dev/null +++ b/AudioFileInspector/AboutForm.Designer.cs @@ -0,0 +1,144 @@ +namespace NAudio.Utils +{ + partial class AboutForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.linkLabelWebsite = new System.Windows.Forms.LinkLabel(); + this.buttonOK = new System.Windows.Forms.Button(); + this.labelProductName = new System.Windows.Forms.Label(); + this.labelCopyright = new System.Windows.Forms.Label(); + this.linkLabelFeedback = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.labelVersion = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // linkLabelWebsite + // + this.linkLabelWebsite.AutoSize = true; + this.linkLabelWebsite.Location = new System.Drawing.Point(13, 67); + this.linkLabelWebsite.Name = "linkLabelWebsite"; + this.linkLabelWebsite.Size = new System.Drawing.Size(168, 13); + this.linkLabelWebsite.TabIndex = 0; + this.linkLabelWebsite.TabStop = true; + this.linkLabelWebsite.Text = "http://www.codeplex.com/naudio"; + this.linkLabelWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelWebsite_LinkClicked); + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(111, 124); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // labelProductName + // + this.labelProductName.AutoSize = true; + this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelProductName.Location = new System.Drawing.Point(13, 13); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new System.Drawing.Size(196, 16); + this.labelProductName.TabIndex = 2; + this.labelProductName.Text = "{Application.ProductName}"; + // + // labelCopyright + // + this.labelCopyright.AutoSize = true; + this.labelCopyright.Location = new System.Drawing.Point(13, 51); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new System.Drawing.Size(149, 13); + this.labelCopyright.TabIndex = 2; + this.labelCopyright.Text = "Copyright © Mark Heath 2007"; + // + // linkLabelFeedback + // + this.linkLabelFeedback.AutoSize = true; + this.linkLabelFeedback.Location = new System.Drawing.Point(13, 101); + this.linkLabelFeedback.Name = "linkLabelFeedback"; + this.linkLabelFeedback.Size = new System.Drawing.Size(150, 13); + this.linkLabelFeedback.TabIndex = 3; + this.linkLabelFeedback.TabStop = true; + this.linkLabelFeedback.Text = "mark.heath@gmail.com"; + this.linkLabelFeedback.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelFeedback_LinkClicked); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 85); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(243, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Send feedback, feature requests and bug fixes to:"; + // + // labelVersion + // + this.labelVersion.AutoSize = true; + this.labelVersion.Location = new System.Drawing.Point(13, 33); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new System.Drawing.Size(93, 13); + this.labelVersion.TabIndex = 2; + this.labelVersion.Text = "{Version: X.X.X.X}"; + // + // AboutForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 159); + this.Controls.Add(this.linkLabelFeedback); + this.Controls.Add(this.label3); + this.Controls.Add(this.labelVersion); + this.Controls.Add(this.labelCopyright); + this.Controls.Add(this.labelProductName); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.linkLabelWebsite); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About {Application.ProductName}"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.LinkLabel linkLabelWebsite; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Label labelProductName; + private System.Windows.Forms.Label labelCopyright; + private System.Windows.Forms.LinkLabel linkLabelFeedback; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label labelVersion; + } +} \ No newline at end of file diff --git a/AudioFileInspector/AboutForm.cs b/AudioFileInspector/AboutForm.cs new file mode 100644 index 00000000..2d5861e0 --- /dev/null +++ b/AudioFileInspector/AboutForm.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NAudio.Utils +{ + /// + /// A standard about form + /// + public partial class AboutForm : Form + { + /// + /// Creates a new about form + /// + public AboutForm() + { + InitializeComponent(); + labelProductName.Text = Application.ProductName; + labelVersion.Text = String.Format("Version: {0}", Application.ProductVersion); + this.Text = String.Format("About {0}", Application.ProductName); + } + + private void linkLabelWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start(linkLabelWebsite.Text); + } + + private void linkLabelFeedback_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("mailto:" + linkLabelFeedback.Text); + } + + private void buttonOK_Click(object sender, EventArgs e) + { + this.Close(); + } + + /// + /// The URL of the website to use for help + /// e.g. http://www.codeplex.com/naudio + /// + public string Url + { + get { return linkLabelWebsite.Text; } + set { linkLabelWebsite.Text = value; } + } + + /// + /// The email address for feedback + /// + public string Email + { + get { return linkLabelFeedback.Text; } + set { linkLabelFeedback.Text = value; } + } + + /// + /// The copyright info + /// e.g. Copyright © 2007 Mark Heath + /// + public string Copyright + { + get { return labelCopyright.Text; } + set { labelCopyright.Text = value; } + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/AboutForm.resx b/AudioFileInspector/AboutForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/AudioFileInspector/AboutForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspector.csproj b/AudioFileInspector/AudioFileInspector.csproj new file mode 100644 index 00000000..64617ce3 --- /dev/null +++ b/AudioFileInspector/AudioFileInspector.csproj @@ -0,0 +1,186 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {D29C1659-635C-497B-847E-FE9A5A69ED03} + WinExe + Properties + AudioFileInspector + AudioFileInspector + + + + + + + + + + + + + 3.5 + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + AnyCPU + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + x86 + + + + + False + ..\Lib\MEF\System.ComponentModel.Composition.dll + + + 3.5 + + + + + + + + + + Form + + + AboutForm.cs + + + Form + + + AudioFileInspectorForm.cs + + + + + + Form + + + FindForm.cs + + + + + Form + + + OptionsForm.cs + + + + + AboutForm.cs + Designer + + + Designer + AudioFileInspectorForm.cs + + + Designer + FindForm.cs + + + Designer + OptionsForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + Always + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {DA4F02E3-0B5E-42CD-B8D9-5583FA51D66E} + NAudio + + + + + \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspectorForm.Designer.cs b/AudioFileInspector/AudioFileInspectorForm.Designer.cs new file mode 100644 index 00000000..ed3ab328 --- /dev/null +++ b/AudioFileInspector/AudioFileInspectorForm.Designer.cs @@ -0,0 +1,203 @@ +namespace AudioFileInspector +{ + partial class AudioFileInspectorForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.textLog = new System.Windows.Forms.RichTextBox(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem, + this.toolsToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(513, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openToolStripMenuItem, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openToolStripMenuItem + // + this.openToolStripMenuItem.Name = "openToolStripMenuItem"; + this.openToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.openToolStripMenuItem.Text = "&Open..."; + this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.findToolStripMenuItem}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.editToolStripMenuItem.Text = "&Edit"; + // + // findToolStripMenuItem + // + this.findToolStripMenuItem.Name = "findToolStripMenuItem"; + this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); + this.findToolStripMenuItem.Size = new System.Drawing.Size(155, 22); + this.findToolStripMenuItem.Text = "&Find..."; + this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click); + // + // toolsToolStripMenuItem + // + this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.saveLogToolStripMenuItem, + this.clearLogToolStripMenuItem}); + this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.toolsToolStripMenuItem.Text = "&Tools"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(141, 22); + this.optionsToolStripMenuItem.Text = "&Options..."; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click); + // + // saveLogToolStripMenuItem + // + this.saveLogToolStripMenuItem.Name = "saveLogToolStripMenuItem"; + this.saveLogToolStripMenuItem.Size = new System.Drawing.Size(141, 22); + this.saveLogToolStripMenuItem.Text = "&Save Log..."; + this.saveLogToolStripMenuItem.Click += new System.EventHandler(this.saveLogToolStripMenuItem_Click); + // + // clearLogToolStripMenuItem + // + this.clearLogToolStripMenuItem.Name = "clearLogToolStripMenuItem"; + this.clearLogToolStripMenuItem.Size = new System.Drawing.Size(141, 22); + this.clearLogToolStripMenuItem.Text = "&Clear Log"; + this.clearLogToolStripMenuItem.Click += new System.EventHandler(this.clearLogToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.aboutToolStripMenuItem, + this.contentsToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(129, 22); + this.aboutToolStripMenuItem.Text = "&About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // contentsToolStripMenuItem + // + this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; + this.contentsToolStripMenuItem.Size = new System.Drawing.Size(129, 22); + this.contentsToolStripMenuItem.Text = "&Contents"; + this.contentsToolStripMenuItem.Click += new System.EventHandler(this.contentsToolStripMenuItem_Click); + // + // textLog + // + this.textLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.textLog.HideSelection = false; + this.textLog.Location = new System.Drawing.Point(0, 24); + this.textLog.Name = "textLog"; + this.textLog.Size = new System.Drawing.Size(513, 409); + this.textLog.TabIndex = 1; + this.textLog.Text = ""; + // + // AudioFileInspectorForm + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(513, 433); + this.Controls.Add(this.textLog); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; + this.Name = "AudioFileInspectorForm"; + this.Text = "Audio File Inspector"; + this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.AudioFileInspectorForm_FormClosed); + this.DragDrop += new System.Windows.Forms.DragEventHandler(this.AudioFileInspectorForm_DragDrop); + this.DragOver += new System.Windows.Forms.DragEventHandler(this.AudioFileInspectorForm_DragOver); + this.Load += new System.EventHandler(this.AudioFileInspectorForm_Load); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveLogToolStripMenuItem; + private System.Windows.Forms.RichTextBox textLog; + private System.Windows.Forms.ToolStripMenuItem clearLogToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem findToolStripMenuItem; + } +} \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspectorForm.cs b/AudioFileInspector/AudioFileInspectorForm.cs new file mode 100644 index 00000000..0ee3d51a --- /dev/null +++ b/AudioFileInspector/AudioFileInspectorForm.cs @@ -0,0 +1,229 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(AudioFileInspectorForm))] + public partial class AudioFileInspectorForm : Form + { + + public ICollection Inspectors { get; private set; } + string filterString; + int filterIndex; + string currentFile; + FindForm findForm; + + public string[] CommandLineArguments { get; set; } + + [ImportingConstructor] + public AudioFileInspectorForm([ImportMany(typeof(IAudioFileInspector))] IEnumerable inspectors) + { + InitializeComponent(); + this.Inspectors = new List(inspectors); + } + + private void DescribeFile(string fileName) + { + currentFile = fileName; + textLog.Text = String.Format("Opening {0}\r\n", fileName); + + try + { + string extension = System.IO.Path.GetExtension(fileName).ToLower(); + bool described = false; + foreach (IAudioFileInspector inspector in Inspectors) + { + if (extension == inspector.FileExtension) + { + textLog.AppendText(inspector.Describe(fileName)); + described = true; + break; + } + } + if (!described) + { + textLog.AppendText("Unrecognised file type"); + } + } + catch (Exception ex) + { + textLog.AppendText(ex.ToString()); + } + } + + private void CreateFilterString() + { + StringBuilder stringBuilder = new StringBuilder(); + if (Inspectors.Count > 0) + { + stringBuilder.Append("All Supported Files|"); + foreach (IAudioFileInspector inspector in Inspectors) + { + stringBuilder.AppendFormat("*{0};", inspector.FileExtension); + } + stringBuilder.Length--; + stringBuilder.Append("|"); + foreach (IAudioFileInspector inspector in Inspectors) + { + stringBuilder.AppendFormat("{0}|*{1}|", inspector.FileTypeDescription, inspector.FileExtension); + } + } + stringBuilder.Append("All files (*.*)|*.*"); + filterString = stringBuilder.ToString(); + filterIndex = 1; + } + + private void openToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + + ofd.Filter = filterString; + ofd.FilterIndex = filterIndex; + + if (ofd.ShowDialog() == DialogResult.OK) + { + filterIndex = ofd.FilterIndex; + DescribeFile(ofd.FileName); + textLog.SelectionStart = 0; + textLog.SelectionLength = 0; + } + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void aboutToolStripMenuItem_Click(object sender, EventArgs e) + { + NAudio.Utils.AboutForm aboutForm = new NAudio.Utils.AboutForm(); + aboutForm.ShowDialog(); + } + + private void AudioFileInspectorForm_Load(object sender, EventArgs e) + { + CreateFilterString(); + if (CommandLineArguments != null && CommandLineArguments.Length > 0) + { + DescribeFile(CommandLineArguments[0]); + } + } + + private void optionsToolStripMenuItem_Click(object sender, EventArgs e) + { + OptionsForm optionsForm = new OptionsForm(Inspectors); + optionsForm.ShowDialog(); + + } + + private void AudioFileInspectorForm_DragOver(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + e.Effect = DragDropEffects.Copy; + } + } + + private void AudioFileInspectorForm_DragDrop(object sender, DragEventArgs e) + { + if (!e.Data.GetDataPresent(DataFormats.FileDrop)) + { + return; + } + string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (files.Length > 0) + { + DescribeFile(files[0]); + } + } + + private void saveLogToolStripMenuItem_Click(object sender, EventArgs args) + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.DefaultExt = ".txt"; + if (currentFile != null) + { + saveFileDialog.InitialDirectory = Path.GetDirectoryName(currentFile); + saveFileDialog.FileName = Path.GetFileNameWithoutExtension(currentFile) + ".txt"; + } + saveFileDialog.Filter = "Text Files (*.txt)|*.txt"; + saveFileDialog.FilterIndex = 1; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + try + { + + using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName)) + { + string text = textLog.Text; + if (!text.Contains("\r")) + { + text = text.Replace("\n", "\r\n"); + } + writer.Write(text); + } + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Error saving conversion log\r\n{0}", e.Message), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + + } + + private void contentsToolStripMenuItem_Click(object sender, EventArgs e) + { + string helpFilePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "audio_file_inspector.html"); + try + { + System.Diagnostics.Process.Start(helpFilePath); + } + catch (Win32Exception) + { + MessageBox.Show("Could not display the help file", Application.ProductName); + } + } + + private void clearLogToolStripMenuItem_Click(object sender, EventArgs e) + { + textLog.Clear(); + } + + private void findToolStripMenuItem_Click(object sender, EventArgs e) + { + if (findForm == null) + { + findForm = new FindForm(textLog); + findForm.Disposed += new EventHandler(findForm_Disposed); + } + findForm.Show(this); + } + + void findForm_Disposed(object sender, EventArgs e) + { + findForm = null; + } + + private void AudioFileInspectorForm_FormClosed(object sender, FormClosedEventArgs e) + { + if (findForm != null) + { + findForm.Close(); + } + } + + } +} \ No newline at end of file diff --git a/AudioFileInspector/AudioFileInspectorForm.resx b/AudioFileInspector/AudioFileInspectorForm.resx new file mode 100644 index 00000000..69c56499 --- /dev/null +++ b/AudioFileInspector/AudioFileInspectorForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/AudioFileInspector/FileAssociations.cs b/AudioFileInspector/FileAssociations.cs new file mode 100644 index 00000000..76642e82 --- /dev/null +++ b/AudioFileInspector/FileAssociations.cs @@ -0,0 +1,379 @@ +using System; +using Microsoft.Win32; + +namespace AudioFileInspector +{ + /// + /// Helper class for registering Windows Explorer File associations + /// + public class FileAssociations + { + + [System.Runtime.InteropServices.DllImport("shell32.dll")] + static extern void SHChangeNotify(HChangeNotifyEventID wEventId, + HChangeNotifyFlags uFlags, + IntPtr dwItem1, + IntPtr dwItem2); + + /// + /// Determines if the specified file type is registered + /// + /// The file extension including the leading period (e.g. ".wav") + /// True if it is registered + public static bool IsFileTypeRegistered(string extension) + { + RegistryKey key = Registry.ClassesRoot.OpenSubKey(extension); + if(key == null) + return false; + key.Close(); + return true; + } + + /// + /// Gets the HKCR key name for the extenstion + /// + /// The file extension including the leading period (e.g. ".wav") + /// The HKCR key name or null if not registered + public static string GetFileTypeKey(string extension) + { + RegistryKey key = Registry.ClassesRoot.OpenSubKey(extension); + string fileTypeKey = null; + if (key != null) + { + fileTypeKey = (string) key.GetValue(null); + key.Close(); + } + return fileTypeKey; + } + + /// + /// Registers a file type in Windows + /// + /// Extension include leading '.' + /// The description of this file type + /// Null for no icon or e.g c:\windows\regedit.exe,0 + public static void RegisterFileType(string extension, string description, string iconPath) + { + if (IsFileTypeRegistered(extension)) + throw new ArgumentException(extension + "is already registered"); + + RegistryKey key = Registry.ClassesRoot.CreateSubKey(extension); + string fileKey = extension.Substring(1) + "File"; + key.SetValue(null, fileKey); + key.Close(); + key = Registry.ClassesRoot.CreateSubKey(fileKey); + key.SetValue(null, description); + key.Close(); + if (iconPath != null) + { + key = Registry.ClassesRoot.CreateSubKey(fileKey + "\\DefaultIcon"); + key.SetValue(null, iconPath); + key.Close(); + } + SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero); + } + + /// + /// Adds a new explorer context menu action for this file type + /// Will overwrite any existing action with this key + /// + /// The file extension (include the leading dot) + /// A unique key for this action + /// What will appear on the context menu + /// The command to execute + public static void AddAction(string extension, string actionKey, string actionDescription, string command) + { + // command e.g. notepad.exe "%1" + string fileTypeKey = GetFileTypeKey(extension); + if (fileTypeKey == null) + throw new ArgumentException(extension + "is not a registered file type"); + RegistryKey key = Registry.ClassesRoot.CreateSubKey(fileTypeKey + "\\shell\\" + actionKey); + key.SetValue(null, actionDescription); + key.Close(); + + key = Registry.ClassesRoot.CreateSubKey(fileTypeKey + "\\shell\\" + actionKey + "\\command"); + key.SetValue(null, command); + key.Close(); + SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero); + } + + /// + /// Removes an explorer context menu action from a file extension + /// + /// The file extension (include the leading dot) + /// The unique key used to register this action + public static void RemoveAction(string extension, string actionKey) + { + string fileTypeKey = GetFileTypeKey(extension); + if (fileTypeKey == null) + { + return; + //throw new ArgumentException(extension + "is not a registered file type"); + } + Registry.ClassesRoot.DeleteSubKey(fileTypeKey + "\\shell\\" + actionKey + "\\command"); + Registry.ClassesRoot.DeleteSubKey(fileTypeKey + "\\shell\\" + actionKey); + } + + // TODO: add ourselves as an "Open With" application + // TODO: better error handling + // TODO: unregistering stuff + // TODO: set default action + + } + + #region enum HChangeNotifyEventID + /// + /// Describes the event that has occurred. + /// Typically, only one event is specified at a time. + /// If more than one event is specified, the values contained + /// in the dwItem1 and dwItem2 + /// parameters must be the same, respectively, for all specified events. + /// This parameter can be one or more of the following values. + /// + /// + /// Windows NT/2000/XP: dwItem2 contains the index + /// in the system image list that has changed. + /// dwItem1 is not used and should be . + /// Windows 95/98: dwItem1 contains the index + /// in the system image list that has changed. + /// dwItem2 is not used and should be . + /// + [Flags] + enum HChangeNotifyEventID + { + /// + /// All events have occurred. + /// + SHCNE_ALLEVENTS = 0x7FFFFFFF, + + /// + /// A file type association has changed. + /// must be specified in the uFlags parameter. + /// dwItem1 and dwItem2 are not used and must be . + /// + SHCNE_ASSOCCHANGED = 0x08000000, + + /// + /// The attributes of an item or folder have changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the item or folder that has changed. + /// dwItem2 is not used and should be . + /// + SHCNE_ATTRIBUTES = 0x00000800, + + /// + /// A nonfolder item has been created. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the item that was created. + /// dwItem2 is not used and should be . + /// + SHCNE_CREATE = 0x00000002, + + /// + /// A nonfolder item has been deleted. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the item that was deleted. + /// dwItem2 is not used and should be . + /// + SHCNE_DELETE = 0x00000004, + + /// + /// A drive has been added. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that was added. + /// dwItem2 is not used and should be . + /// + SHCNE_DRIVEADD = 0x00000100, + + /// + /// A drive has been added and the Shell should create a new window for the drive. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that was added. + /// dwItem2 is not used and should be . + /// + SHCNE_DRIVEADDGUI = 0x00010000, + + /// + /// A drive has been removed. or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that was removed. + /// dwItem2 is not used and should be . + /// + SHCNE_DRIVEREMOVED = 0x00000080, + + /// + /// Not currently used. + /// + SHCNE_EXTENDED_EVENT = 0x04000000, + + /// + /// The amount of free space on a drive has changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive on which the free space changed. + /// dwItem2 is not used and should be . + /// + SHCNE_FREESPACE = 0x00040000, + + /// + /// Storage media has been inserted into a drive. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive that contains the new media. + /// dwItem2 is not used and should be . + /// + SHCNE_MEDIAINSERTED = 0x00000020, + + /// + /// Storage media has been removed from a drive. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the root of the drive from which the media was removed. + /// dwItem2 is not used and should be . + /// + SHCNE_MEDIAREMOVED = 0x00000040, + + /// + /// A folder has been created. + /// or must be specified in uFlags. + /// dwItem1 contains the folder that was created. + /// dwItem2 is not used and should be . + /// + SHCNE_MKDIR = 0x00000008, + + /// + /// A folder on the local computer is being shared via the network. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that is being shared. + /// dwItem2 is not used and should be . + /// + SHCNE_NETSHARE = 0x00000200, + + /// + /// A folder on the local computer is no longer being shared via the network. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that is no longer being shared. + /// dwItem2 is not used and should be . + /// + SHCNE_NETUNSHARE = 0x00000400, + + /// + /// The name of a folder has changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the previous pointer to an item identifier list (PIDL) or name of the folder. + /// dwItem2 contains the new PIDL or name of the folder. + /// + SHCNE_RENAMEFOLDER = 0x00020000, + + /// + /// The name of a nonfolder item has changed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the previous PIDL or name of the item. + /// dwItem2 contains the new PIDL or name of the item. + /// + SHCNE_RENAMEITEM = 0x00000001, + + /// + /// A folder has been removed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that was removed. + /// dwItem2 is not used and should be . + /// + SHCNE_RMDIR = 0x00000010, + + /// + /// The computer has disconnected from a server. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the server from which the computer was disconnected. + /// dwItem2 is not used and should be . + /// + SHCNE_SERVERDISCONNECT = 0x00004000, + + /// + /// The contents of an existing folder have changed, + /// but the folder still exists and has not been renamed. + /// or + /// must be specified in uFlags. + /// dwItem1 contains the folder that has changed. + /// dwItem2 is not used and should be . + /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or + /// SHCNE_RENAMEFOLDER, respectively, instead. + /// + SHCNE_UPDATEDIR = 0x00001000, + + /// + /// An image in the system image list has changed. + /// must be specified in uFlags. + /// + SHCNE_UPDATEIMAGE = 0x00008000, + + } + #endregion // enum HChangeNotifyEventID + + #region public enum HChangeNotifyFlags + /// + /// Flags that indicate the meaning of the dwItem1 and dwItem2 parameters. + /// The uFlags parameter must be one of the following values. + /// + [Flags] + public enum HChangeNotifyFlags + { + /// + /// The dwItem1 and dwItem2 parameters are DWORD values. + /// + SHCNF_DWORD = 0x0003, + /// + /// dwItem1 and dwItem2 are the addresses of ITEMIDLIST structures that + /// represent the item(s) affected by the change. + /// Each ITEMIDLIST must be relative to the desktop folder. + /// + SHCNF_IDLIST = 0x0000, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings of + /// maximum length MAX_PATH that contain the full path names + /// of the items affected by the change. + /// + SHCNF_PATHA = 0x0001, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings of + /// maximum length MAX_PATH that contain the full path names + /// of the items affected by the change. + /// + SHCNF_PATHW = 0x0005, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings that + /// represent the friendly names of the printer(s) affected by the change. + /// + SHCNF_PRINTERA = 0x0002, + /// + /// dwItem1 and dwItem2 are the addresses of null-terminated strings that + /// represent the friendly names of the printer(s) affected by the change. + /// + SHCNF_PRINTERW = 0x0006, + /// + /// The function should not return until the notification + /// has been delivered to all affected components. + /// As this flag modifies other data-type flags, it cannot by used by itself. + /// + SHCNF_FLUSH = 0x1000, + /// + /// The function should begin delivering notifications to all affected components + /// but should return as soon as the notification process has begun. + /// As this flag modifies other data-type flags, it cannot by used by itself. + /// + SHCNF_FLUSHNOWAIT = 0x2000 + } + #endregion // enum HChangeNotifyFlags + +} diff --git a/AudioFileInspector/FileInspectors/CakewalkMapInspector.cs b/AudioFileInspector/FileInspectors/CakewalkMapInspector.cs new file mode 100644 index 00000000..c2402149 --- /dev/null +++ b/AudioFileInspector/FileInspectors/CakewalkMapInspector.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NAudio.FileFormats.Map; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class CakewalkMapInspector : IAudioFileInspector + { + #region IAudioFileInspector Members + + public string FileExtension + { + get { return ".map"; } + } + + public string FileTypeDescription + { + get { return "Cakewalk Drum Map"; } + } + + public string Describe(string fileName) + { + CakewalkMapFile mapFile = new CakewalkMapFile(fileName); + return mapFile.ToString(); + } + + #endregion + } +} diff --git a/AudioFileInspector/FileInspectors/MidiFileInspector.cs b/AudioFileInspector/FileInspectors/MidiFileInspector.cs new file mode 100644 index 00000000..d71618d7 --- /dev/null +++ b/AudioFileInspector/FileInspectors/MidiFileInspector.cs @@ -0,0 +1,78 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; +using NAudio.Midi; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class MidiFileInspector : IAudioFileInspector + { + #region IAudioFileInspector Members + + public string FileExtension + { + get { return ".mid"; } + } + + public string FileTypeDescription + { + get { return "Standard MIDI File"; } + } + + public string Describe(string fileName) + { + MidiFile mf = new MidiFile(fileName, false); + + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Format {0}, Tracks {1}, Delta Ticks Per Quarter Note {2}\r\n", + mf.FileFormat, mf.Tracks, mf.DeltaTicksPerQuarterNote); + var timeSignature = mf.Events[0].OfType().FirstOrDefault(); + for (int n = 0; n < mf.Tracks; n++) + { + foreach (MidiEvent midiEvent in mf.Events[n]) + { + if(!MidiEvent.IsNoteOff(midiEvent)) + { + sb.AppendFormat("{0} {1}\r\n", ToMBT(midiEvent.AbsoluteTime, mf.DeltaTicksPerQuarterNote, timeSignature), midiEvent); + } + } + } + return sb.ToString(); + } + + private string ToMBT(long eventTime, int ticksPerQuarterNote, TimeSignatureEvent timeSignature) + { + int beatsPerBar = timeSignature == null ? 4 : timeSignature.Numerator; + int ticksPerBar = timeSignature == null ? ticksPerQuarterNote * 4 : (timeSignature.Numerator * ticksPerQuarterNote * 4) / (1 << timeSignature.Denominator); + int ticksPerBeat = ticksPerBar / beatsPerBar; + long bar = 1 + (eventTime / ticksPerBar); + long beat = 1 + ((eventTime % ticksPerBar) / ticksPerBeat); + long tick = eventTime % ticksPerBeat; + return String.Format("{0}:{1}:{2}", bar, beat, tick); + } + + /// + /// Find the number of beats per measure + /// (for now assume just one TimeSignature per MIDI track) + /// + private int FindBeatsPerMeasure(IEnumerable midiEvents) + { + int beatsPerMeasure = 4; + foreach (MidiEvent midiEvent in midiEvents) + { + TimeSignatureEvent tse = midiEvent as TimeSignatureEvent; + if (tse != null) + { + beatsPerMeasure = tse.Numerator; + } + } + return beatsPerMeasure; + } + + + #endregion + } +} diff --git a/AudioFileInspector/FileInspectors/Mp3FileInspector.cs b/AudioFileInspector/FileInspectors/Mp3FileInspector.cs new file mode 100644 index 00000000..b96b8711 --- /dev/null +++ b/AudioFileInspector/FileInspectors/Mp3FileInspector.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; +using NAudio.Utils; +using NAudio.Wave; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class Mp3FileInspector : IAudioFileInspector + { + public string FileExtension + { + get { return ".mp3"; } + } + + public string FileTypeDescription + { + get { return "MP3 File"; } + } + + public string Describe(string fileName) + { + var stringBuilder = new StringBuilder(); + using (var reader = new Mp3FileReader(fileName)) + { + Mp3WaveFormat wf = reader.Mp3WaveFormat; + stringBuilder.AppendFormat("MP3 File WaveFormat: {0} {1}Hz {2} channels {3} bits per sample\r\n", + wf.Encoding, wf.SampleRate, + wf.Channels, wf.BitsPerSample); + stringBuilder.AppendFormat("Extra Size: {0} Block Align: {1} Average Bytes Per Second: {2}\r\n", + wf.ExtraSize, wf.BlockAlign, + wf.AverageBytesPerSecond); + stringBuilder.AppendFormat("ID: {0} Flags: {1} Block Size: {2} Frames per Block: {3}\r\n", + wf.id, wf.flags, wf.blockSize, wf.framesPerBlock + ); + + stringBuilder.AppendFormat("Length: {0} bytes: {1} \r\n", reader.Length, reader.TotalTime); + stringBuilder.AppendFormat("ID3v1 Tag: {0}\r\n", reader.Id3v1Tag == null ? "None" : reader.Id3v1Tag.ToString()); + stringBuilder.AppendFormat("ID3v2 Tag: {0}\r\n", reader.Id3v2Tag == null ? "None" : reader.Id3v2Tag.ToString()); + Mp3Frame frame; + while ((frame = reader.ReadNextFrame()) != null) + { + stringBuilder.AppendFormat("{0},{1},{2}Hz,{3},{4}bps, length {5}\r\n", + frame.MpegVersion, frame.MpegLayer, + frame.SampleRate, frame.ChannelMode, + frame.BitRate, frame.FrameLength); + } + } + return stringBuilder.ToString(); + } + } +} diff --git a/AudioFileInspector/FileInspectors/SoundFontInspector.cs b/AudioFileInspector/FileInspectors/SoundFontInspector.cs new file mode 100644 index 00000000..e2876687 --- /dev/null +++ b/AudioFileInspector/FileInspectors/SoundFontInspector.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NAudio.SoundFont; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class SoundFontInspector : IAudioFileInspector + { + #region IAudioFileInspector Members + + public string FileExtension + { + get { return ".sf2"; } + } + + public string FileTypeDescription + { + get { return "SoundFont File"; } + } + + public string Describe(string fileName) + { + SoundFont sf = new SoundFont(fileName); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.AppendFormat("{0}\r\n",sf.FileInfo); + stringBuilder.Append("Presets\r\n"); + foreach(Preset p in sf.Presets) + { + stringBuilder.AppendFormat("{0}\r\n",p); + foreach(Zone z in p.Zones) + { + stringBuilder.AppendFormat(" {0}\r\n",z); + foreach(Generator g in z.Generators) + { + stringBuilder.AppendFormat(" {0}\r\n",g); + } + foreach(Modulator m in z.Modulators) + { + stringBuilder.AppendFormat(" {0}\r\n",m); + } + } + } + + stringBuilder.Append("Instruments\r\n"); + foreach(Instrument i in sf.Instruments) + { + stringBuilder.AppendFormat("{0}\r\n",i); + foreach(Zone z in i.Zones) + { + stringBuilder.AppendFormat(" {0}\r\n",z); + foreach(Generator g in z.Generators) + { + stringBuilder.AppendFormat(" {0}\r\n",g); + } + foreach(Modulator m in z.Modulators) + { + stringBuilder.AppendFormat(" {0}\r\n",m); + } + } + } + return stringBuilder.ToString(); + } + + #endregion + } +} diff --git a/AudioFileInspector/FileInspectors/WaveFileInspector.cs b/AudioFileInspector/FileInspectors/WaveFileInspector.cs new file mode 100644 index 00000000..4f28cced --- /dev/null +++ b/AudioFileInspector/FileInspectors/WaveFileInspector.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NAudio.Wave; +using NAudio.Utils; +using System.Diagnostics; +using System.ComponentModel.Composition; + +namespace AudioFileInspector +{ + [Export(typeof(IAudioFileInspector))] + public class WaveFileInspector : IAudioFileInspector + { + + public string FileExtension + { + get { return ".wav"; } + } + + public string FileTypeDescription + { + get { return "Wave File"; } + } + + public string Describe(string fileName) + { + StringBuilder stringBuilder = new StringBuilder(); + using (WaveFileReader wf = new WaveFileReader(fileName)) + { + stringBuilder.AppendFormat("{0} {1}Hz {2} channels {3} bits per sample\r\n", + wf.WaveFormat.Encoding, wf.WaveFormat.SampleRate, + wf.WaveFormat.Channels, wf.WaveFormat.BitsPerSample); + stringBuilder.AppendFormat("Extra Size: {0} Block Align: {1} Average Bytes Per Second: {2}\r\n", + wf.WaveFormat.ExtraSize, wf.WaveFormat.BlockAlign, + wf.WaveFormat.AverageBytesPerSecond); + stringBuilder.AppendFormat("WaveFormat: {0}\r\n",wf.WaveFormat); + + stringBuilder.AppendFormat("Length: {0} bytes: {1} \r\n", wf.Length, wf.TotalTime); + foreach (RiffChunk chunk in wf.ExtraChunks) + { + stringBuilder.AppendFormat("Chunk: {0}, length {1}\r\n", chunk.IdentifierAsString, chunk.Length); + byte[] data = wf.GetChunkData(chunk); + DescribeChunk(chunk, stringBuilder, data); + } + } + return stringBuilder.ToString(); + } + + private static void DescribeChunk(RiffChunk chunk, StringBuilder stringBuilder, byte[] data) + { + switch(chunk.IdentifierAsString) + { + case "strc": + DescribeStrc(stringBuilder, data); + break; + case "bext": + DescribeBext(stringBuilder, data); + break; + case "iXML": + stringBuilder.Append(UTF8Encoding.UTF8.GetString(data)); + break; + default: + { + if (ByteArrayExtensions.IsEntirelyNull(data)) + { + stringBuilder.AppendFormat("{0} null bytes\r\n", data.Length); + } + else + { + stringBuilder.AppendFormat("{0}\r\n", ByteArrayExtensions.DescribeAsHex(data," ",32)); + } + } + break; + } + } + + private static void DescribeBext(StringBuilder sb, byte[] data) + { + int offset = 0; + sb.AppendFormat("Description: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, 0, 256, ASCIIEncoding.ASCII)); + offset += 256; + sb.AppendFormat("Originator: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 32, ASCIIEncoding.ASCII)); + offset += 32; + sb.AppendFormat("Originator Reference: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 32, ASCIIEncoding.ASCII)); + offset += 32; + sb.AppendFormat("Origination Date: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 10, ASCIIEncoding.ASCII)); + offset += 10; + sb.AppendFormat("Origination Time: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 8, ASCIIEncoding.ASCII)); + offset += 8; + sb.AppendFormat("Time Reference Low: {0}\r\n", BitConverter.ToUInt32(data, offset)); + offset += 4; + sb.AppendFormat("Time Reference High: {0}\r\n", BitConverter.ToUInt32(data, offset)); + offset += 4; + sb.AppendFormat("Version: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("SMPTE UMID: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, 64, Encoding.ASCII)); + //byte[] smpteumid = 64 bytes; + offset += 64; + sb.AppendFormat("Loudness Value: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Loudness Range: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Max True Peak Level: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Max Momentary Loudness: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + sb.AppendFormat("Max short term loudness: {0}\r\n", BitConverter.ToUInt16(data, offset)); + offset += 2; + //byte[] reserved = 180 bytes; + offset += 180; + sb.AppendFormat("Coding History: {0}\r\n", ByteArrayExtensions.DecodeAsString(data, offset, data.Length-offset, Encoding.ASCII)); + + } + + + + + private static void DescribeStrc(StringBuilder stringBuilder, byte[] data) + { + // First 28 bytes are header + int header1 = BitConverter.ToInt32(data, 0); // always 0x1C? + int sliceCount = BitConverter.ToInt32(data, 4); + int header2 = BitConverter.ToInt32(data, 8); // 0x19 or 0x41? + int header3 = BitConverter.ToInt32(data, 12); // 0x05 or 0x0A? (linked with header 2 - 0x41 0x05 go together and 0x19 0x0A go together) + int header4 = BitConverter.ToInt32(data, 16); // always 1? + int header5 = BitConverter.ToInt32(data, 20); // 0x00, 0x01 or 0x0A? + int header6 = BitConverter.ToInt32(data, 24); // 0x02, 0x04. 0x05 + + stringBuilder.AppendFormat("{0} slices. unknown: {1},{2},{3},{4},{5},{6}\r\n", + sliceCount,header1,header2,header3,header4,header5,header6); + + int offset = 28; + + for (int slice = 0; slice < sliceCount; slice++) + { + int unknown1 = BitConverter.ToInt32(data, offset); // 0 or 2 + int uniqueId1 = BitConverter.ToInt32(data, offset + 4); // another unique ID - doesn't change? + + long samplePosition = BitConverter.ToInt64(data, offset + 8); + long samplePos2 = BitConverter.ToInt64(data, offset + 16); // is zero the first time through, equal to sample position next time round + int unknown5 = BitConverter.ToInt32(data, offset + 24); // large number first time through, zero second time through, not flags, not a float + int uniqueId2 = BitConverter.ToInt32(data, offset + 28); // always the same + offset += 32; + stringBuilder.AppendFormat("Pos: {2},{3} unknown: {0},{4}\r\n", + unknown1, uniqueId1, samplePosition, samplePos2, unknown5, uniqueId2); + } + } + } +} diff --git a/AudioFileInspector/FindForm.Designer.cs b/AudioFileInspector/FindForm.Designer.cs new file mode 100644 index 00000000..1da68918 --- /dev/null +++ b/AudioFileInspector/FindForm.Designer.cs @@ -0,0 +1,88 @@ +namespace AudioFileInspector +{ + partial class FindForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.textBoxFind = new System.Windows.Forms.TextBox(); + this.buttonFind = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(56, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Find what:"; + // + // textBoxFind + // + this.textBoxFind.Location = new System.Drawing.Point(74, 6); + this.textBoxFind.Name = "textBoxFind"; + this.textBoxFind.Size = new System.Drawing.Size(206, 20); + this.textBoxFind.TabIndex = 1; + // + // buttonFind + // + this.buttonFind.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonFind.Location = new System.Drawing.Point(205, 32); + this.buttonFind.Name = "buttonFind"; + this.buttonFind.Size = new System.Drawing.Size(75, 23); + this.buttonFind.TabIndex = 2; + this.buttonFind.Text = "Find Next"; + this.buttonFind.UseVisualStyleBackColor = true; + this.buttonFind.Click += new System.EventHandler(this.buttonFind_Click); + // + // FindForm + // + this.AcceptButton = this.buttonFind; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 64); + this.Controls.Add(this.buttonFind); + this.Controls.Add(this.textBoxFind); + this.Controls.Add(this.label1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FindForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Find"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBoxFind; + private System.Windows.Forms.Button buttonFind; + } +} \ No newline at end of file diff --git a/AudioFileInspector/FindForm.cs b/AudioFileInspector/FindForm.cs new file mode 100644 index 00000000..77bfa692 --- /dev/null +++ b/AudioFileInspector/FindForm.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace AudioFileInspector +{ + public partial class FindForm : Form + { + RichTextBox richTextBox; + public FindForm(RichTextBox richTextBox) + { + InitializeComponent(); + this.richTextBox = richTextBox; + } + + private void buttonFind_Click(object sender, EventArgs e) + { + richTextBox.Find(textBoxFind.Text, + richTextBox.SelectionStart + + richTextBox.SelectionLength, + RichTextBoxFinds.None); + richTextBox.ScrollToCaret(); + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/FindForm.resx b/AudioFileInspector/FindForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/AudioFileInspector/FindForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/IAudioFileInspector.cs b/AudioFileInspector/IAudioFileInspector.cs new file mode 100644 index 00000000..70fdaea4 --- /dev/null +++ b/AudioFileInspector/IAudioFileInspector.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AudioFileInspector +{ + public interface IAudioFileInspector + { + string FileExtension { get; } + string FileTypeDescription { get; } + string Describe(string fileName); + } +} diff --git a/AudioFileInspector/InstallScript.nsi b/AudioFileInspector/InstallScript.nsi new file mode 100644 index 00000000..e1a1bef2 --- /dev/null +++ b/AudioFileInspector/InstallScript.nsi @@ -0,0 +1,154 @@ +; Audio File Inspector install script +; originally based on example2 that comes with nsis +; +; This script is based on example1.nsi, but it remember the directory, +; has uninstall support and (optionally) installs start menu shortcuts. +; +; It will install example2.nsi into a directory that the user selects, + +;-------------------------------- +!include WordFunc.nsh +!insertmacro VersionCompare + +!include LogicLib.nsh + +!define VERSION "0.1" +!define FULLVERSION "0.1.1.0" +!define PRODUCT_NAME "Audio File Inspector" +!define EXECUTABLE_NAME "AudioFileInspector.exe" + +; The name of the installer +Name "Audio File Inspector" + +; The file to write +;OutFile "${PRODUCT_NAME} v${VERSION} Install.exe" +OutFile "audio_file_inspector_0_1_install.exe" + +; The default installation directory +InstallDir "$PROGRAMFILES\Mark Heath\${PRODUCT_NAME}" + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" "Install_Dir" + +VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "${PRODUCT_NAME}" +VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "" +VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Mark Heath" +VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "© 2006-2009 Mark Heath" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "${PRODUCT_NAME} Installer" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${VERSION}" +VIProductVersion "${FULLVERSION}" + + + +;-------------------------------- + +; Utils + +Function .onInit + Call GetDotNETVersion + Pop $0 + ${If} $0 == "not found" + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} + + StrCpy $0 $0 "" 1 # skip "v" + + ${VersionCompare} $0 "2.0" $1 + ${If} $1 == 2 + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required. You have $0." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} +FunctionEnd + +Function GetDotNETVersion + Push $0 + Push $1 + + System::Call "mscoree::GetCORVersion(w .r0, i ${NSIS_MAX_STRLEN}, *i) i .r1" + StrCmp $1 "error" 0 +2 + StrCpy $0 "not found" + + Pop $1 + Exch $0 +FunctionEnd + +;-------------------------------- + +; Pages + +Page components +Page directory +Page instfiles + +UninstPage uninstConfirm +UninstPage instfiles + +;-------------------------------- + +; The stuff to install +Section "Program Files (required)" + + SectionIn RO + + ; Set output path to the installation directory. + SetOutPath $INSTDIR + + ; Put file there + File "${EXECUTABLE_NAME}" + ; File "${EXECUTABLE_NAME}.config" + File "NAudio.dll" + File "audio_file_inspector.html" + + ; Write the installation path into the registry + WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + + ExecWait '"$INSTDIR\${EXECUTABLE_NAME}" -install' $0 + DetailPrint "Associating File Types returned $0" +SectionEnd + +; Optional section (can be disabled by the user) +Section "Start Menu Shortcuts" + + CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${EXECUTABLE_NAME}" "" "$INSTDIR\${EXECUTABLE_NAME}" 0 + +SectionEnd + +;-------------------------------- + +; Uninstaller + +Section "Uninstall" + ExecWait '"$INSTDIR\${EXECUTABLE_NAME}" -uninstall' $0 + DetailPrint "Removing Explorer Context Action returned $0" + ; Remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" + + ; Remove files and uninstaller + Delete "$INSTDIR\uninstall.exe" + Delete "$INSTDIR\${EXECUTABLE_NAME}" + Delete "$INSTDIR\${EXECUTABLE_NAME}.config" + Delete "$INSTDIR\NAudio.dll" + Delete "$INSTDIR\audio_file_inspector.html" + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*" + + ; Remove directories used + RMDir "$SMPROGRAMS\${PRODUCT_NAME}" + RMDir "$INSTDIR" + +SectionEnd diff --git a/AudioFileInspector/OptionsForm.Designer.cs b/AudioFileInspector/OptionsForm.Designer.cs new file mode 100644 index 00000000..737a304b --- /dev/null +++ b/AudioFileInspector/OptionsForm.Designer.cs @@ -0,0 +1,94 @@ +namespace AudioFileInspector +{ + partial class OptionsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.buttonAssociate = new System.Windows.Forms.Button(); + this.buttonDisassociate = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // buttonAssociate + // + this.buttonAssociate.Location = new System.Drawing.Point(73, 64); + this.buttonAssociate.Name = "buttonAssociate"; + this.buttonAssociate.Size = new System.Drawing.Size(164, 23); + this.buttonAssociate.TabIndex = 0; + this.buttonAssociate.Text = "Recreate File Associations"; + this.buttonAssociate.UseVisualStyleBackColor = true; + this.buttonAssociate.Click += new System.EventHandler(this.buttonAssociate_Click); + // + // buttonDisassociate + // + this.buttonDisassociate.Location = new System.Drawing.Point(73, 93); + this.buttonDisassociate.Name = "buttonDisassociate"; + this.buttonDisassociate.Size = new System.Drawing.Size(164, 23); + this.buttonDisassociate.TabIndex = 1; + this.buttonDisassociate.Text = "Remove File Associations"; + this.buttonDisassociate.UseVisualStyleBackColor = true; + this.buttonDisassociate.Click += new System.EventHandler(this.buttonDisassociate_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(290, 52); + this.label1.TabIndex = 2; + this.label1.Text = "Audio File Inspector can be set up to appear as a right-click \r\ncontext menu opti" + + "on in Windows explorer. You can recreate\r\nor remove the file associations at any" + + " time using the buttons\r\nbelow."; + // + // OptionsForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(309, 128); + this.Controls.Add(this.label1); + this.Controls.Add(this.buttonDisassociate); + this.Controls.Add(this.buttonAssociate); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "OptionsForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Options"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button buttonAssociate; + private System.Windows.Forms.Button buttonDisassociate; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/AudioFileInspector/OptionsForm.cs b/AudioFileInspector/OptionsForm.cs new file mode 100644 index 00000000..e61dad40 --- /dev/null +++ b/AudioFileInspector/OptionsForm.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using NAudio.Utils; + +namespace AudioFileInspector +{ + partial class OptionsForm : Form + { + IEnumerable inspectors; + + public OptionsForm(IEnumerable inspectors) + { + InitializeComponent(); + this.inspectors = inspectors; + } + + private void buttonAssociate_Click(object sender, EventArgs args) + { + try + { + Associate(inspectors); + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Unable to create file associations\r\n{0}", e), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + + private void buttonDisassociate_Click(object sender, EventArgs args) + { + try + { + Disassociate(inspectors); + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Unable to remove file associations\r\n{0}", e), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + + public static void Disassociate(IEnumerable inspectors) + { + foreach (IAudioFileInspector inspector in inspectors) + { + if (!FileAssociations.IsFileTypeRegistered(inspector.FileExtension)) + { + FileAssociations.RegisterFileType(inspector.FileExtension, inspector.FileTypeDescription, null); + } + string command = "\"" + Application.ExecutablePath + "\" \"%1\""; + FileAssociations.RemoveAction( + inspector.FileExtension, + "AudioFileInspector"); + } + } + + public static void Associate(IEnumerable inspectors) + { + foreach (IAudioFileInspector inspector in inspectors) + { + if (!FileAssociations.IsFileTypeRegistered(inspector.FileExtension)) + { + FileAssociations.RegisterFileType(inspector.FileExtension, inspector.FileTypeDescription, null); + } + string command = "\"" + Application.ExecutablePath + "\" \"%1\""; + FileAssociations.AddAction( + inspector.FileExtension, + "AudioFileInspector", + "Describe", + command); + } + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/OptionsForm.resx b/AudioFileInspector/OptionsForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/AudioFileInspector/OptionsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/Program.cs b/AudioFileInspector/Program.cs new file mode 100644 index 00000000..79a228c4 --- /dev/null +++ b/AudioFileInspector/Program.cs @@ -0,0 +1,65 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Windows.Forms; +using System.ComponentModel.Composition; +using System.ComponentModel.Composition.Hosting; + +namespace AudioFileInspector +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static int Main(string[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); + var container = new CompositionContainer(catalog); + var inspectors = container.GetExportedValues(); + + if (args.Length > 0) + { + if (args[0] == "-install") + { + try + { + OptionsForm.Associate(inspectors); + Console.WriteLine("Created {0} file associations", inspectors.Count()); + } + catch (Exception e) + { + Console.WriteLine("Unable to create file associations"); + Console.WriteLine(e.ToString()); + return -1; + } + + return 0; + } + else if (args[0] == "-uninstall") + { + try + { + OptionsForm.Disassociate(inspectors); + Console.WriteLine("Removed {0} file associations", inspectors.Count()); + } + catch (Exception e) + { + Console.WriteLine("Unable to remove file associations"); + Console.WriteLine(e.ToString()); + return -1; + } + return 0; + } + } + var mainForm = container.GetExportedValue(); + mainForm.CommandLineArguments = args; + Application.Run(mainForm); + return 0; + } + } +} \ No newline at end of file diff --git a/AudioFileInspector/Properties/AssemblyInfo.cs b/AudioFileInspector/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..fab0c400 --- /dev/null +++ b/AudioFileInspector/Properties/AssemblyInfo.cs @@ -0,0 +1,77 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Audio File Inspector")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Mark Heath")] +[assembly: AssemblyProduct("Audio File Inspector")] +[assembly: AssemblyCopyright("Copyright © Mark Heath 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8bb855c5-ddfc-4596-a5df-aa9059be7705")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.1.7.0")] +[assembly: AssemblyFileVersion("0.1.7.0")] + +// build 1 - 1 Nov 2006 +// initial version - moved out of WavePlayer +// extracted file describing logic into classes +// drag and drop support +// command line support +// explorer context menu support +// save analysis to text file +// installer +// command line register and unregister file associations +// build 2 - 2 Nov 2006 +// fixed some installer problems +// build 3 - 10 Nov 2006 +// MIDI note off events are not displayed +// Initial M:B:T support for MIDI +// build 4 - 26 Apr 2007 +// Updated to work with latest code in CodePlex +// Beginnings of a find feature +// build 5 - 8 Jun 2008 +// Shows length of Wave file as a TimeSpan as well as bytes +// build 6 - 13 Jan 2009 +// can report on strc chunks in ACID wav files +// build 7 - 13 Jan 2012 +// better MBT calculation for MIDI files + +// TODO list +// help file + +// better error handling +// possibly: a plugin format +// options for each inspector +// describe on a separate thread + + +// Enhance existing: +// MIDI: riff, M:B:T +// WAV: ACID format +// Additional formats: +// WAV 64 +// AIFF +// REX +// MP3 +// OGG +// Project 5 pattern diff --git a/AudioFileInspector/Properties/Resources.Designer.cs b/AudioFileInspector/Properties/Resources.Designer.cs new file mode 100644 index 00000000..63e68a94 --- /dev/null +++ b/AudioFileInspector/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AudioFileInspector.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AudioFileInspector.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/AudioFileInspector/Properties/Resources.resx b/AudioFileInspector/Properties/Resources.resx new file mode 100644 index 00000000..ffecec85 --- /dev/null +++ b/AudioFileInspector/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AudioFileInspector/Properties/Settings.Designer.cs b/AudioFileInspector/Properties/Settings.Designer.cs new file mode 100644 index 00000000..89cacc5a --- /dev/null +++ b/AudioFileInspector/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.1 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace AudioFileInspector.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/AudioFileInspector/Properties/Settings.settings b/AudioFileInspector/Properties/Settings.settings new file mode 100644 index 00000000..abf36c5d --- /dev/null +++ b/AudioFileInspector/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/AudioFileInspector/audio_file_inspector.html b/AudioFileInspector/audio_file_inspector.html new file mode 100644 index 00000000..65a17b92 --- /dev/null +++ b/AudioFileInspector/audio_file_inspector.html @@ -0,0 +1,84 @@ + + + + Audio File Inspector + + +

+ Audio File Inspector

+

+ Audio File Inspector is a simple utility that describes the contents of various + types of audio file (for example WAV files or MIDI sequences). It started out as + a developer tool to aid in writing code that reads these various formats, but has + been released because some people may find it useful for diagnosing problems playing + back various media files.

+

+ Audio File Formats are notoriously vague and it is likely that you will have some + files on your computer that cause Audio File Inspector to generate an error message. + If you encounter a problem, then feel free to zip the file up and email it to me + and I will consider updating the utility to support your file.

+

+ Supported File Types

+

+ The current version of Audio File Inspector supports the following file types:

+
    +
  • MID - This will enumerate each event in the MIDI file. At the moment it + reports the time of the event in terms of "absolute time". A future update will turn + this into measures, beats and ticks (M:B:T)
  • +
  • SF2 - This examines a SoundFont file, reporting all the instruments, zones + and audio files contained within
  • +
  • WAV - This will report the format of the audio data, as well as providing + binary dumps of any extra chunks of information.
  • +
  • MAP - This can extract some information from a Cakewalk drum map file. +
  • +
+ +

+ Download

+ +

A link to the latest version of Audio File Inspector can be found + here.

+

+ Installation

+ +

Audio File Inspector requires the .NET framework version 3.5 to be installed. + You can download this + here. Once you have done this you can run the installer which will add a right-click "Describe" + action to Windows Explorer for each of the supported file types.

+

+ Usage

+

+ There are a variety of ways in which you can load a file into Audio File Inspector for + analysis.

+
    +
  • Right-click a supported file in Windows explorer and click "Describe"
  • +
  • Use the File|Open menu option to select a file to analyse
  • +
  • Drag a file from Windows explorer onto the title-bar of Audio File Inspector
  • +
  • You can also drag a file over the executable itself or run Audio File Inspector + from the command line with a filename as an argument.
  • +
+

+ Tools Menu

+

+ On the tools menu you can find commands that allow you to clear the log or to save its + contents to disk (you are of course free to edit the contents in any way you like before + saving it). + + There is also an options form, which in this version simply allows you to recreate or remove + the right-click "Describe" option in Windows Explorer.

+

+ Version History

+

+ The latest version of Audio File Inspector can be found at + http://naudio.codeplex.com. +

+
    +
  • v0.1 2 Nov 2006 +
      +
    • First public beta release
    • +
    • Support for WAV, MID, SF2 and MAP
    • +
    +
  • +
+ + diff --git a/Build.proj b/Build.proj new file mode 100644 index 00000000..f2dd1b46 --- /dev/null +++ b/Build.proj @@ -0,0 +1,65 @@ + + + + $(MSBuildProjectDirectory)\.build + + + + + + + 1.0.0.0 + 1.0.0.0 + 1.0.0.0 + + + + + 1.0.0.0 + $(BUILD_NUMBER) + $(BUILD_NUMBER) + + + + Release + + + + + + + + + + + + + + + + + + + + Configuration=$(BuildConfiguration) + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildProcessTemplates/DefaultTemplate.xaml b/BuildProcessTemplates/DefaultTemplate.xaml new file mode 100644 index 00000000..eae035b2 --- /dev/null +++ b/BuildProcessTemplates/DefaultTemplate.xaml @@ -0,0 +1,602 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Assembly references and imported namespaces serialized as XML namespaces + + + True + + + + + + + + + True + + + + + + + True + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + True + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + True + + + + + + + + + + + + + + + True + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildProcessTemplates/UpgradeTemplate.xaml b/BuildProcessTemplates/UpgradeTemplate.xaml new file mode 100644 index 00000000..4877aa35 --- /dev/null +++ b/BuildProcessTemplates/UpgradeTemplate.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + [New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }] + + + + [Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto] + [False] + [False] + + + + + + + + + + [Microsoft.TeamFoundation.VersionControl.Client.RecursionType.OneLevel] + [Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal] + + + + All + Assembly references and imported namespaces serialized as XML namespaces + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Lib/MEF/Microsoft.ComponentModel.Composition.Initialization.Desktop.dll b/Lib/MEF/Microsoft.ComponentModel.Composition.Initialization.Desktop.dll new file mode 100644 index 00000000..60a974d7 Binary files /dev/null and b/Lib/MEF/Microsoft.ComponentModel.Composition.Initialization.Desktop.dll differ diff --git a/Lib/MEF/System.ComponentModel.Composition.dll b/Lib/MEF/System.ComponentModel.Composition.dll new file mode 100644 index 00000000..bbbae1e1 Binary files /dev/null and b/Lib/MEF/System.ComponentModel.Composition.dll differ diff --git a/Lib/MEF/readme.txt b/Lib/MEF/readme.txt new file mode 100644 index 00000000..879a2926 --- /dev/null +++ b/Lib/MEF/readme.txt @@ -0,0 +1,2 @@ +had to get a special build of Composition.Initialization.Desktop.zip to be able to use ExportFactory with .NET 3.5 +http://cid-f8b2fd72406fb218.office.live.com/self.aspx/blog/Composition.Initialization.Desktop.zip \ No newline at end of file diff --git a/Lib/NSpeex/NSpeex.dll b/Lib/NSpeex/NSpeex.dll new file mode 100644 index 00000000..5de7848e Binary files /dev/null and b/Lib/NSpeex/NSpeex.dll differ diff --git a/MidiFileConverter/AboutForm.Designer.cs b/MidiFileConverter/AboutForm.Designer.cs new file mode 100644 index 00000000..bd8cd680 --- /dev/null +++ b/MidiFileConverter/AboutForm.Designer.cs @@ -0,0 +1,144 @@ +namespace NAudio.Utils +{ + partial class AboutForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.linkLabelWebsite = new System.Windows.Forms.LinkLabel(); + this.buttonOK = new System.Windows.Forms.Button(); + this.labelProductName = new System.Windows.Forms.Label(); + this.labelCopyright = new System.Windows.Forms.Label(); + this.linkLabelFeedback = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.labelVersion = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // linkLabelWebsite + // + this.linkLabelWebsite.AutoSize = true; + this.linkLabelWebsite.Location = new System.Drawing.Point(13, 67); + this.linkLabelWebsite.Name = "linkLabelWebsite"; + this.linkLabelWebsite.Size = new System.Drawing.Size(168, 13); + this.linkLabelWebsite.TabIndex = 0; + this.linkLabelWebsite.TabStop = true; + this.linkLabelWebsite.Text = "http://www.codeplex.com/naudio"; + this.linkLabelWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelWebsite_LinkClicked); + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(111, 124); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // labelProductName + // + this.labelProductName.AutoSize = true; + this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelProductName.Location = new System.Drawing.Point(13, 13); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new System.Drawing.Size(196, 16); + this.labelProductName.TabIndex = 2; + this.labelProductName.Text = "{Application.ProductName}"; + // + // labelCopyright + // + this.labelCopyright.AutoSize = true; + this.labelCopyright.Location = new System.Drawing.Point(13, 51); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new System.Drawing.Size(149, 13); + this.labelCopyright.TabIndex = 2; + this.labelCopyright.Text = "Copyright © Mark Heath 2007"; + // + // linkLabelFeedback + // + this.linkLabelFeedback.AutoSize = true; + this.linkLabelFeedback.Location = new System.Drawing.Point(13, 101); + this.linkLabelFeedback.Name = "linkLabelFeedback"; + this.linkLabelFeedback.Size = new System.Drawing.Size(150, 13); + this.linkLabelFeedback.TabIndex = 3; + this.linkLabelFeedback.TabStop = true; + this.linkLabelFeedback.Text = "mark.heath@gmail.com"; + this.linkLabelFeedback.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelFeedback_LinkClicked); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 85); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(243, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Send feedback, feature requests and bug fixes to:"; + // + // labelVersion + // + this.labelVersion.AutoSize = true; + this.labelVersion.Location = new System.Drawing.Point(13, 33); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new System.Drawing.Size(93, 13); + this.labelVersion.TabIndex = 2; + this.labelVersion.Text = "{Version: X.X.X.X}"; + // + // AboutForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 159); + this.Controls.Add(this.linkLabelFeedback); + this.Controls.Add(this.label3); + this.Controls.Add(this.labelVersion); + this.Controls.Add(this.labelCopyright); + this.Controls.Add(this.labelProductName); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.linkLabelWebsite); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About {Application.ProductName}"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.LinkLabel linkLabelWebsite; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Label labelProductName; + private System.Windows.Forms.Label labelCopyright; + private System.Windows.Forms.LinkLabel linkLabelFeedback; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label labelVersion; + } +} \ No newline at end of file diff --git a/MidiFileConverter/AboutForm.cs b/MidiFileConverter/AboutForm.cs new file mode 100644 index 00000000..2d5861e0 --- /dev/null +++ b/MidiFileConverter/AboutForm.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NAudio.Utils +{ + /// + /// A standard about form + /// + public partial class AboutForm : Form + { + /// + /// Creates a new about form + /// + public AboutForm() + { + InitializeComponent(); + labelProductName.Text = Application.ProductName; + labelVersion.Text = String.Format("Version: {0}", Application.ProductVersion); + this.Text = String.Format("About {0}", Application.ProductName); + } + + private void linkLabelWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start(linkLabelWebsite.Text); + } + + private void linkLabelFeedback_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("mailto:" + linkLabelFeedback.Text); + } + + private void buttonOK_Click(object sender, EventArgs e) + { + this.Close(); + } + + /// + /// The URL of the website to use for help + /// e.g. http://www.codeplex.com/naudio + /// + public string Url + { + get { return linkLabelWebsite.Text; } + set { linkLabelWebsite.Text = value; } + } + + /// + /// The email address for feedback + /// + public string Email + { + get { return linkLabelFeedback.Text; } + set { linkLabelFeedback.Text = value; } + } + + /// + /// The copyright info + /// e.g. Copyright © 2007 Mark Heath + /// + public string Copyright + { + get { return labelCopyright.Text; } + set { labelCopyright.Text = value; } + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/AboutForm.resx b/MidiFileConverter/AboutForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/MidiFileConverter/AboutForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MidiFileConverter/AdvancedOptionsForm.Designer.cs b/MidiFileConverter/AdvancedOptionsForm.Designer.cs new file mode 100644 index 00000000..7874856f --- /dev/null +++ b/MidiFileConverter/AdvancedOptionsForm.Designer.cs @@ -0,0 +1,169 @@ +namespace MarkHeath.MidiUtils +{ + partial class AdvancedOptionsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.checkBoxRemoveSequencerSpecific = new System.Windows.Forms.CheckBox(); + this.checkBoxRecreateEndTrack = new System.Windows.Forms.CheckBox(); + this.checkBoxAddNameMarker = new System.Windows.Forms.CheckBox(); + this.checkBoxTrimTextEvents = new System.Windows.Forms.CheckBox(); + this.checkBoxRemoveEmptyTracks = new System.Windows.Forms.CheckBox(); + this.buttonOK = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.checkBoxRemoveExtraTempoEvents = new System.Windows.Forms.CheckBox(); + this.checkBoxRemoveExtraMarkers = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // checkBoxRemoveSequencerSpecific + // + this.checkBoxRemoveSequencerSpecific.AutoSize = true; + this.checkBoxRemoveSequencerSpecific.Location = new System.Drawing.Point(13, 13); + this.checkBoxRemoveSequencerSpecific.Name = "checkBoxRemoveSequencerSpecific"; + this.checkBoxRemoveSequencerSpecific.Size = new System.Drawing.Size(198, 17); + this.checkBoxRemoveSequencerSpecific.TabIndex = 0; + this.checkBoxRemoveSequencerSpecific.Text = "Remove Sequencer Specific Events"; + this.checkBoxRemoveSequencerSpecific.UseVisualStyleBackColor = true; + // + // checkBoxRecreateEndTrack + // + this.checkBoxRecreateEndTrack.AutoSize = true; + this.checkBoxRecreateEndTrack.Location = new System.Drawing.Point(13, 37); + this.checkBoxRecreateEndTrack.Name = "checkBoxRecreateEndTrack"; + this.checkBoxRecreateEndTrack.Size = new System.Drawing.Size(159, 17); + this.checkBoxRecreateEndTrack.TabIndex = 1; + this.checkBoxRecreateEndTrack.Text = "Recreate End Track Events"; + this.checkBoxRecreateEndTrack.UseVisualStyleBackColor = true; + // + // checkBoxAddNameMarker + // + this.checkBoxAddNameMarker.AutoSize = true; + this.checkBoxAddNameMarker.Location = new System.Drawing.Point(13, 61); + this.checkBoxAddNameMarker.Name = "checkBoxAddNameMarker"; + this.checkBoxAddNameMarker.Size = new System.Drawing.Size(112, 17); + this.checkBoxAddNameMarker.TabIndex = 2; + this.checkBoxAddNameMarker.Text = "Add Name Marker"; + this.checkBoxAddNameMarker.UseVisualStyleBackColor = true; + // + // checkBoxTrimTextEvents + // + this.checkBoxTrimTextEvents.AutoSize = true; + this.checkBoxTrimTextEvents.Location = new System.Drawing.Point(13, 85); + this.checkBoxTrimTextEvents.Name = "checkBoxTrimTextEvents"; + this.checkBoxTrimTextEvents.Size = new System.Drawing.Size(106, 17); + this.checkBoxTrimTextEvents.TabIndex = 3; + this.checkBoxTrimTextEvents.Text = "Trim Text Events"; + this.checkBoxTrimTextEvents.UseVisualStyleBackColor = true; + // + // checkBoxRemoveEmptyTracks + // + this.checkBoxRemoveEmptyTracks.AutoSize = true; + this.checkBoxRemoveEmptyTracks.Location = new System.Drawing.Point(13, 109); + this.checkBoxRemoveEmptyTracks.Name = "checkBoxRemoveEmptyTracks"; + this.checkBoxRemoveEmptyTracks.Size = new System.Drawing.Size(134, 17); + this.checkBoxRemoveEmptyTracks.TabIndex = 4; + this.checkBoxRemoveEmptyTracks.Text = "Remove Empty Tracks"; + this.checkBoxRemoveEmptyTracks.UseVisualStyleBackColor = true; + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(60, 182); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 5; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // buttonCancel + // + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(141, 182); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(75, 23); + this.buttonCancel.TabIndex = 6; + this.buttonCancel.Text = "Cancel"; + this.buttonCancel.UseVisualStyleBackColor = true; + // + // checkBoxRemoveExtraTempoEvents + // + this.checkBoxRemoveExtraTempoEvents.AutoSize = true; + this.checkBoxRemoveExtraTempoEvents.Location = new System.Drawing.Point(13, 132); + this.checkBoxRemoveExtraTempoEvents.Name = "checkBoxRemoveExtraTempoEvents"; + this.checkBoxRemoveExtraTempoEvents.Size = new System.Drawing.Size(165, 17); + this.checkBoxRemoveExtraTempoEvents.TabIndex = 4; + this.checkBoxRemoveExtraTempoEvents.Text = "Remove Extra Tempo Events"; + this.checkBoxRemoveExtraTempoEvents.UseVisualStyleBackColor = true; + // + // checkBoxRemoveExtraMarkers + // + this.checkBoxRemoveExtraMarkers.AutoSize = true; + this.checkBoxRemoveExtraMarkers.Location = new System.Drawing.Point(13, 155); + this.checkBoxRemoveExtraMarkers.Name = "checkBoxRemoveExtraMarkers"; + this.checkBoxRemoveExtraMarkers.Size = new System.Drawing.Size(134, 17); + this.checkBoxRemoveExtraMarkers.TabIndex = 4; + this.checkBoxRemoveExtraMarkers.Text = "Remove Extra Markers"; + this.checkBoxRemoveExtraMarkers.UseVisualStyleBackColor = true; + // + // AdvancedOptionsForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.buttonCancel; + this.ClientSize = new System.Drawing.Size(227, 217); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.checkBoxRemoveExtraMarkers); + this.Controls.Add(this.checkBoxRemoveExtraTempoEvents); + this.Controls.Add(this.checkBoxRemoveEmptyTracks); + this.Controls.Add(this.checkBoxTrimTextEvents); + this.Controls.Add(this.checkBoxAddNameMarker); + this.Controls.Add(this.checkBoxRecreateEndTrack); + this.Controls.Add(this.checkBoxRemoveSequencerSpecific); + this.MinimumSize = new System.Drawing.Size(235, 210); + this.Name = "AdvancedOptionsForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Advanced Options"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox checkBoxRemoveSequencerSpecific; + private System.Windows.Forms.CheckBox checkBoxRecreateEndTrack; + private System.Windows.Forms.CheckBox checkBoxAddNameMarker; + private System.Windows.Forms.CheckBox checkBoxTrimTextEvents; + private System.Windows.Forms.CheckBox checkBoxRemoveEmptyTracks; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Button buttonCancel; + private System.Windows.Forms.CheckBox checkBoxRemoveExtraTempoEvents; + private System.Windows.Forms.CheckBox checkBoxRemoveExtraMarkers; + } +} \ No newline at end of file diff --git a/MidiFileConverter/AdvancedOptionsForm.cs b/MidiFileConverter/AdvancedOptionsForm.cs new file mode 100644 index 00000000..cb6db858 --- /dev/null +++ b/MidiFileConverter/AdvancedOptionsForm.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace MarkHeath.MidiUtils +{ + public partial class AdvancedOptionsForm : Form + { + private Properties.Settings settings; + public AdvancedOptionsForm() + { + InitializeComponent(); + settings = Properties.Settings.Default; + LoadSettings(); + } + + private void LoadSettings() + { + checkBoxAddNameMarker.Checked = settings.AddNameMarker; + checkBoxRecreateEndTrack.Checked = settings.RecreateEndTrackMarkers; + checkBoxRemoveEmptyTracks.Checked = settings.RemoveEmptyTracks; + checkBoxRemoveSequencerSpecific.Checked = settings.RemoveSequencerSpecific; + checkBoxTrimTextEvents.Checked = settings.TrimTextEvents; + checkBoxRemoveExtraTempoEvents.Checked = settings.RemoveExtraTempoEvents; + checkBoxRemoveExtraMarkers.Checked = settings.RemoveExtraMarkers; + } + + private void buttonOK_Click(object sender, EventArgs e) + { + settings.AddNameMarker = checkBoxAddNameMarker.Checked; + settings.RecreateEndTrackMarkers = checkBoxRecreateEndTrack.Checked; + settings.RemoveEmptyTracks =checkBoxRemoveEmptyTracks.Checked; + settings.RemoveSequencerSpecific = checkBoxRemoveSequencerSpecific.Checked; + settings.TrimTextEvents = checkBoxTrimTextEvents.Checked; + settings.RemoveExtraTempoEvents = checkBoxRemoveExtraTempoEvents.Checked; + settings.RemoveExtraMarkers = checkBoxRemoveExtraMarkers.Checked; + settings.Save(); + this.Close(); + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/AdvancedOptionsForm.resx b/MidiFileConverter/AdvancedOptionsForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/MidiFileConverter/AdvancedOptionsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MidiFileConverter/InstallScript.nsi b/MidiFileConverter/InstallScript.nsi new file mode 100644 index 00000000..bd86a437 --- /dev/null +++ b/MidiFileConverter/InstallScript.nsi @@ -0,0 +1,153 @@ +; MIDI File Converter install script +; originally based on example2 that comes with nsis +; +; This script is based on example1.nsi, but it remember the directory, +; has uninstall support and (optionally) installs start menu shortcuts. +; +; It will install example2.nsi into a directory that the user selects, + +;-------------------------------- +!include WordFunc.nsh +!insertmacro VersionCompare + +!include LogicLib.nsh +RequestExecutionLevel highest +!define VERSION "0.3" +!define FULLVERSION "0.3.9.0" +!define PRODUCT_NAME "MIDI File Converter" +!define EXECUTABLE_NAME "MIDI File Converter.exe" + +; The name of the installer +Name "MIDI File Converter" + +; The file to write +; OutFile "${PRODUCT_NAME} v${VERSION} Install.exe" +OutFile "midi_file_converter_0_3_install.exe" + +; The default installation directory +InstallDir "$PROGRAMFILES\Mark Heath\${PRODUCT_NAME}" + +; Registry key to check for directory (so if you install again, it will +; overwrite the old one automatically) +InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" "Install_Dir" + +VIAddVersionKey /LANG=1033-English "ProductName" "${PRODUCT_NAME}" +VIAddVersionKey /LANG=1033-English "Comments" "" +VIAddVersionKey /LANG=1033-English "CompanyName" "Mark Heath" +VIAddVersionKey /LANG=1033-English "LegalCopyright" "© 2007 Mark Heath" +VIAddVersionKey /LANG=1033-English "FileDescription" "${PRODUCT_NAME} Installer" +VIAddVersionKey /LANG=1033-English "FileVersion" "${VERSION}" +VIProductVersion "${FULLVERSION}" + + + +;-------------------------------- + +; Utils + +Function .onInit + Call GetDotNETVersion + Pop $0 + ${If} $0 == "not found" + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} + + StrCpy $0 $0 "" 1 # skip "v" + + ${VersionCompare} $0 "2.0" $1 + ${If} $1 == 2 + MessageBox MB_OK|MB_ICONSTOP ".NET runtime library v2.0 or newer is required. You have $0." + ExecShell "open" "http://msdn.microsoft.com/netframework/downloads/updates/default.aspx" + Abort + ${EndIf} +FunctionEnd + +Function GetDotNETVersion + Push $0 + Push $1 + + System::Call "mscoree::GetCORVersion(w .r0, i ${NSIS_MAX_STRLEN}, *i) i .r1" + StrCmp $1 "error" 0 +2 + StrCpy $0 "not found" + + Pop $1 + Exch $0 +FunctionEnd + +;-------------------------------- + +; Pages + +Page components +Page directory +Page instfiles + +UninstPage uninstConfirm +UninstPage instfiles + +;-------------------------------- + +; The stuff to install +Section "Program Files (required)" + + SectionIn RO + + ; Set output path to the installation directory. + SetOutPath $INSTDIR + + ; Put file there + File "MIDI File Converter.exe" + File "MIDI File Converter.exe.config" + File "NAudio.dll" + File "midi_file_converter.html" + File "NamingRules.xml" + + ; Write the installation path into the registry + WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "Install_Dir" "$INSTDIR" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_NAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" '"$INSTDIR\uninstall.exe"' + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoRepair" 1 + WriteUninstaller "uninstall.exe" + +SectionEnd + +; Optional section (can be disabled by the user) +Section "Start Menu Shortcuts" + + CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}" + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 + CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\${EXECUTABLE_NAME}" "" "$INSTDIR\${EXECUTABLE_NAME}" 0 + +SectionEnd + +;-------------------------------- + +; Uninstaller + +Section "Uninstall" + + ; Remove registry keys + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" + + ; Remove files and uninstaller + Delete "$INSTDIR\uninstall.exe" + Delete "$INSTDIR\MIDI File Converter.exe" + Delete "$INSTDIR\MIDI File Converter.exe.config" + Delete "$INSTDIR\NAudio.dll" + Delete "$INSTDIR\midi_file_converter.html" + Delete "$INSTDIR\NamingRules.xml" + + ; Remove shortcuts, if any + Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*" + + ; Remove directories used + RMDir "$SMPROGRAMS\${PRODUCT_NAME}" + RMDir "$INSTDIR" + +SectionEnd diff --git a/MidiFileConverter/MainForm.Designer.cs b/MidiFileConverter/MainForm.Designer.cs new file mode 100644 index 00000000..17bd0aa0 --- /dev/null +++ b/MidiFileConverter/MainForm.Designer.cs @@ -0,0 +1,449 @@ +namespace MarkHeath.MidiUtils +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.textBoxInputFolder = new System.Windows.Forms.TextBox(); + this.textBoxOutputFolder = new System.Windows.Forms.TextBox(); + this.buttonBrowseEZDrummer = new System.Windows.Forms.Button(); + this.buttonBrowseOutputFolder = new System.Windows.Forms.Button(); + this.buttonConvert = new System.Windows.Forms.Button(); + this.label3 = new System.Windows.Forms.Label(); + this.checkBoxVerbose = new System.Windows.Forms.CheckBox(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.radioButtonType1 = new System.Windows.Forms.RadioButton(); + this.radioButtonTypeUnchanged = new System.Windows.Forms.RadioButton(); + this.radioButtonType0 = new System.Windows.Forms.RadioButton(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.radioButtonChannel10 = new System.Windows.Forms.RadioButton(); + this.radioButtonChannelUnchanged = new System.Windows.Forms.RadioButton(); + this.radioButtonChannel1 = new System.Windows.Forms.RadioButton(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.checkBoxUseFilename = new System.Windows.Forms.CheckBox(); + this.checkBoxApplyNamingRules = new System.Windows.Forms.CheckBox(); + this.progressLog1 = new NAudio.Utils.ProgressLog(); + this.menuStrip1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 34); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(66, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Input Folder:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 64); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(74, 13); + this.label2.TabIndex = 3; + this.label2.Text = "Output Folder:"; + // + // textBoxInputFolder + // + this.textBoxInputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxInputFolder.Location = new System.Drawing.Point(144, 31); + this.textBoxInputFolder.Name = "textBoxInputFolder"; + this.textBoxInputFolder.ReadOnly = true; + this.textBoxInputFolder.Size = new System.Drawing.Size(310, 20); + this.textBoxInputFolder.TabIndex = 1; + // + // textBoxOutputFolder + // + this.textBoxOutputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxOutputFolder.Location = new System.Drawing.Point(144, 61); + this.textBoxOutputFolder.Name = "textBoxOutputFolder"; + this.textBoxOutputFolder.ReadOnly = true; + this.textBoxOutputFolder.Size = new System.Drawing.Size(310, 20); + this.textBoxOutputFolder.TabIndex = 4; + // + // buttonBrowseEZDrummer + // + this.buttonBrowseEZDrummer.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonBrowseEZDrummer.Location = new System.Drawing.Point(460, 29); + this.buttonBrowseEZDrummer.Name = "buttonBrowseEZDrummer"; + this.buttonBrowseEZDrummer.Size = new System.Drawing.Size(75, 23); + this.buttonBrowseEZDrummer.TabIndex = 2; + this.buttonBrowseEZDrummer.Text = "Browse..."; + this.buttonBrowseEZDrummer.UseVisualStyleBackColor = true; + this.buttonBrowseEZDrummer.Click += new System.EventHandler(this.buttonBrowseEZDrummer_Click); + // + // buttonBrowseOutputFolder + // + this.buttonBrowseOutputFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonBrowseOutputFolder.Location = new System.Drawing.Point(460, 59); + this.buttonBrowseOutputFolder.Name = "buttonBrowseOutputFolder"; + this.buttonBrowseOutputFolder.Size = new System.Drawing.Size(75, 23); + this.buttonBrowseOutputFolder.TabIndex = 5; + this.buttonBrowseOutputFolder.Text = "Browse..."; + this.buttonBrowseOutputFolder.UseVisualStyleBackColor = true; + this.buttonBrowseOutputFolder.Click += new System.EventHandler(this.buttonBrowseOutputFolder_Click); + // + // buttonConvert + // + this.buttonConvert.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonConvert.Location = new System.Drawing.Point(460, 204); + this.buttonConvert.Name = "buttonConvert"; + this.buttonConvert.Size = new System.Drawing.Size(75, 23); + this.buttonConvert.TabIndex = 11; + this.buttonConvert.Text = "Convert"; + this.buttonConvert.UseVisualStyleBackColor = true; + this.buttonConvert.Click += new System.EventHandler(this.buttonConvert_Click); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 209); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(319, 13); + this.label3.TabIndex = 9; + this.label3.Text = "When you have verified the above settings, click Convert to begin"; + // + // checkBoxVerbose + // + this.checkBoxVerbose.AutoSize = true; + this.checkBoxVerbose.Checked = true; + this.checkBoxVerbose.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxVerbose.Location = new System.Drawing.Point(351, 208); + this.checkBoxVerbose.Name = "checkBoxVerbose"; + this.checkBoxVerbose.Size = new System.Drawing.Size(100, 17); + this.checkBoxVerbose.TabIndex = 10; + this.checkBoxVerbose.Text = "Verbose Output"; + this.checkBoxVerbose.UseVisualStyleBackColor = true; + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.toolsToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(551, 24); + this.menuStrip1.TabIndex = 10; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(103, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // toolsToolStripMenuItem + // + this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.optionsToolStripMenuItem, + this.clearLogToolStripMenuItem, + this.saveLogToolStripMenuItem}); + this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; + this.toolsToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.toolsToolStripMenuItem.Text = "&Tools"; + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.optionsToolStripMenuItem.Text = "Advanced &Options..."; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click); + // + // clearLogToolStripMenuItem + // + this.clearLogToolStripMenuItem.Name = "clearLogToolStripMenuItem"; + this.clearLogToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.clearLogToolStripMenuItem.Text = "&Clear Log"; + this.clearLogToolStripMenuItem.Click += new System.EventHandler(this.clearLogToolStripMenuItem_Click); + // + // saveLogToolStripMenuItem + // + this.saveLogToolStripMenuItem.Enabled = false; + this.saveLogToolStripMenuItem.Name = "saveLogToolStripMenuItem"; + this.saveLogToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.saveLogToolStripMenuItem.Text = "&Save Log..."; + this.saveLogToolStripMenuItem.Click += new System.EventHandler(this.saveLogToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.contentsToolStripMenuItem, + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // contentsToolStripMenuItem + // + this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; + this.contentsToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.contentsToolStripMenuItem.Text = "&Contents"; + this.contentsToolStripMenuItem.Click += new System.EventHandler(this.contentsToolStripMenuItem_Click); + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.aboutToolStripMenuItem.Text = "&About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.radioButtonType1); + this.groupBox1.Controls.Add(this.radioButtonTypeUnchanged); + this.groupBox1.Controls.Add(this.radioButtonType0); + this.groupBox1.Location = new System.Drawing.Point(337, 96); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(148, 100); + this.groupBox1.TabIndex = 8; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Output File Type"; + // + // radioButtonType1 + // + this.radioButtonType1.AutoSize = true; + this.radioButtonType1.Checked = true; + this.radioButtonType1.Location = new System.Drawing.Point(6, 65); + this.radioButtonType1.Name = "radioButtonType1"; + this.radioButtonType1.Size = new System.Drawing.Size(84, 17); + this.radioButtonType1.TabIndex = 2; + this.radioButtonType1.TabStop = true; + this.radioButtonType1.Text = "MIDI Type 1"; + this.radioButtonType1.UseVisualStyleBackColor = true; + // + // radioButtonTypeUnchanged + // + this.radioButtonTypeUnchanged.AutoSize = true; + this.radioButtonTypeUnchanged.Location = new System.Drawing.Point(6, 19); + this.radioButtonTypeUnchanged.Name = "radioButtonTypeUnchanged"; + this.radioButtonTypeUnchanged.Size = new System.Drawing.Size(114, 17); + this.radioButtonTypeUnchanged.TabIndex = 0; + this.radioButtonTypeUnchanged.Text = "Leave Unchanged"; + this.radioButtonTypeUnchanged.UseVisualStyleBackColor = true; + // + // radioButtonType0 + // + this.radioButtonType0.AutoSize = true; + this.radioButtonType0.Location = new System.Drawing.Point(6, 42); + this.radioButtonType0.Name = "radioButtonType0"; + this.radioButtonType0.Size = new System.Drawing.Size(84, 17); + this.radioButtonType0.TabIndex = 1; + this.radioButtonType0.Text = "MIDI Type 0"; + this.radioButtonType0.UseVisualStyleBackColor = true; + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.radioButtonChannel10); + this.groupBox2.Controls.Add(this.radioButtonChannelUnchanged); + this.groupBox2.Controls.Add(this.radioButtonChannel1); + this.groupBox2.Location = new System.Drawing.Point(187, 96); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(144, 100); + this.groupBox2.TabIndex = 7; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "MIDI Note Channel"; + // + // radioButtonChannel10 + // + this.radioButtonChannel10.AutoSize = true; + this.radioButtonChannel10.Location = new System.Drawing.Point(6, 65); + this.radioButtonChannel10.Name = "radioButtonChannel10"; + this.radioButtonChannel10.Size = new System.Drawing.Size(134, 17); + this.radioButtonChannel10.TabIndex = 5; + this.radioButtonChannel10.Text = "Force all to Channel 10"; + this.radioButtonChannel10.UseVisualStyleBackColor = true; + // + // radioButtonChannelUnchanged + // + this.radioButtonChannelUnchanged.AutoSize = true; + this.radioButtonChannelUnchanged.Checked = true; + this.radioButtonChannelUnchanged.Location = new System.Drawing.Point(6, 19); + this.radioButtonChannelUnchanged.Name = "radioButtonChannelUnchanged"; + this.radioButtonChannelUnchanged.Size = new System.Drawing.Size(114, 17); + this.radioButtonChannelUnchanged.TabIndex = 3; + this.radioButtonChannelUnchanged.TabStop = true; + this.radioButtonChannelUnchanged.Text = "Leave Unchanged"; + this.radioButtonChannelUnchanged.UseVisualStyleBackColor = true; + // + // radioButtonChannel1 + // + this.radioButtonChannel1.AutoSize = true; + this.radioButtonChannel1.Location = new System.Drawing.Point(6, 42); + this.radioButtonChannel1.Name = "radioButtonChannel1"; + this.radioButtonChannel1.Size = new System.Drawing.Size(128, 17); + this.radioButtonChannel1.TabIndex = 4; + this.radioButtonChannel1.Text = "Force all to Channel 1"; + this.radioButtonChannel1.UseVisualStyleBackColor = true; + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.checkBoxUseFilename); + this.groupBox4.Controls.Add(this.checkBoxApplyNamingRules); + this.groupBox4.Location = new System.Drawing.Point(15, 96); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(163, 100); + this.groupBox4.TabIndex = 6; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "Clip Naming"; + // + // checkBoxUseFilename + // + this.checkBoxUseFilename.AutoSize = true; + this.checkBoxUseFilename.Checked = true; + this.checkBoxUseFilename.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxUseFilename.Location = new System.Drawing.Point(6, 55); + this.checkBoxUseFilename.Name = "checkBoxUseFilename"; + this.checkBoxUseFilename.Size = new System.Drawing.Size(117, 30); + this.checkBoxUseFilename.TabIndex = 2; + this.checkBoxUseFilename.Text = "Use filename for\r\nother MIDI patterns"; + this.checkBoxUseFilename.UseVisualStyleBackColor = true; + // + // checkBoxApplyNamingRules + // + this.checkBoxApplyNamingRules.AutoSize = true; + this.checkBoxApplyNamingRules.Checked = true; + this.checkBoxApplyNamingRules.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxApplyNamingRules.Location = new System.Drawing.Point(6, 19); + this.checkBoxApplyNamingRules.Name = "checkBoxApplyNamingRules"; + this.checkBoxApplyNamingRules.Size = new System.Drawing.Size(153, 30); + this.checkBoxApplyNamingRules.TabIndex = 1; + this.checkBoxApplyNamingRules.Text = "Apply XML naming rules\r\nto Toontrack EZD patterns"; + this.checkBoxApplyNamingRules.UseVisualStyleBackColor = true; + // + // progressLog1 + // + this.progressLog1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.progressLog1.BackColor = System.Drawing.SystemColors.InactiveCaption; + this.progressLog1.Location = new System.Drawing.Point(15, 234); + this.progressLog1.Name = "progressLog1"; + this.progressLog1.Padding = new System.Windows.Forms.Padding(1); + this.progressLog1.Size = new System.Drawing.Size(520, 161); + this.progressLog1.TabIndex = 12; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(551, 407); + this.Controls.Add(this.progressLog1); + this.Controls.Add(this.groupBox4); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.checkBoxVerbose); + this.Controls.Add(this.label3); + this.Controls.Add(this.buttonConvert); + this.Controls.Add(this.buttonBrowseOutputFolder); + this.Controls.Add(this.buttonBrowseEZDrummer); + this.Controls.Add(this.textBoxOutputFolder); + this.Controls.Add(this.textBoxInputFolder); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; + this.MinimumSize = new System.Drawing.Size(559, 441); + this.Name = "MainForm"; + this.Text = "MIDI File Converter"; + this.Load += new System.EventHandler(this.MainForm_Load); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox2.PerformLayout(); + this.groupBox4.ResumeLayout(false); + this.groupBox4.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBoxInputFolder; + private System.Windows.Forms.TextBox textBoxOutputFolder; + private System.Windows.Forms.Button buttonBrowseEZDrummer; + private System.Windows.Forms.Button buttonBrowseOutputFolder; + private System.Windows.Forms.Button buttonConvert; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.CheckBox checkBoxVerbose; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RadioButton radioButtonType1; + private System.Windows.Forms.RadioButton radioButtonTypeUnchanged; + private System.Windows.Forms.RadioButton radioButtonType0; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.RadioButton radioButtonChannel10; + private System.Windows.Forms.RadioButton radioButtonChannelUnchanged; + private System.Windows.Forms.RadioButton radioButtonChannel1; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.CheckBox checkBoxUseFilename; + private System.Windows.Forms.CheckBox checkBoxApplyNamingRules; + private NAudio.Utils.ProgressLog progressLog1; + private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem clearLogToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveLogToolStripMenuItem; + } +} + diff --git a/MidiFileConverter/MainForm.cs b/MidiFileConverter/MainForm.cs new file mode 100644 index 00000000..089af592 --- /dev/null +++ b/MidiFileConverter/MainForm.cs @@ -0,0 +1,376 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Threading; +using System.Xml; +using System.Configuration; +using MarkHeath.MidiUtils.Properties; +using NAudio.Utils; + +namespace MarkHeath.MidiUtils +{ + public partial class MainForm : Form + { + bool workQueued; + NamingRules namingRules; + MidiConverter midiConverter; + + Properties.Settings settings; + + public MainForm() + { + InitializeComponent(); + + settings = Properties.Settings.Default; + + if (Settings.Default.FirstTime) + { + UpgradeSettings(); + } + + // could look in HKLM \ Software \ Toontrack \ Superior \ EZDrummer \ HomePath + LoadSettings(); + } + + private void UpgradeSettings() + { + string productVersion = (string)settings.GetPreviousVersion("ProductVersion"); + if ((productVersion != null) && (productVersion.Length > 0)) + { + settings.InputFolder = (string)settings.GetPreviousVersion("InputFolder"); + settings.OutputFolder = (string)settings.GetPreviousVersion("OutputFolder"); + settings.OutputChannelNumber = (int)settings.GetPreviousVersion("OutputChannelNumber"); + settings.OutputMidiType = (OutputMidiType)settings.GetPreviousVersion("OutputMidiType"); + settings.VerboseOutput = (bool)settings.GetPreviousVersion("VerboseOutput"); + settings.UseFileName = (bool)settings.GetPreviousVersion("UseFileName"); + try + { + settings.AddNameMarker = (bool)settings.GetPreviousVersion("AddNameMarker"); + settings.TrimTextEvents = (bool)settings.GetPreviousVersion("TrimTextEvents"); + settings.RemoveEmptyTracks = (bool)settings.GetPreviousVersion("RemoveEmptyTracks"); + settings.RemoveSequencerSpecific = (bool)settings.GetPreviousVersion("RemoveSequencerSpecific"); + settings.RecreateEndTrackMarkers = (bool)settings.GetPreviousVersion("RecreateEndTrackMarkers"); + settings.RemoveExtraTempoEvents = (bool)settings.GetPreviousVersion("RemoveExtraTempoEvents"); + settings.RemoveExtraMarkers = (bool)settings.GetPreviousVersion("RemoveExtraMarkers"); + // add new settings at the bottom + } + catch (SettingsPropertyNotFoundException) + { + } + } + } + + + private void LoadSettings() + { + string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); + + if (settings.InputFolder.Length == 0) + textBoxInputFolder.Text = Path.Combine(programFiles, "Toontrack\\EZDrummer\\Midi"); + else + textBoxInputFolder.Text = settings.InputFolder; + + if(settings.OutputFolder.Length == 0) + textBoxOutputFolder.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); + else + textBoxOutputFolder.Text = settings.OutputFolder; + + checkBoxApplyNamingRules.Checked = settings.ApplyNamingRules; + checkBoxUseFilename.Checked = settings.UseFileName; + checkBoxVerbose.Checked = settings.VerboseOutput; + if (settings.OutputMidiType == OutputMidiType.Type0) + radioButtonType0.Checked = true; + else if (settings.OutputMidiType == OutputMidiType.Type1) + radioButtonType1.Checked = true; + else + radioButtonTypeUnchanged.Checked = true; + + if (settings.OutputChannelNumber == 1) + radioButtonChannel1.Checked = true; + else if (settings.OutputChannelNumber == 10) + radioButtonChannel10.Checked = true; + else + radioButtonChannelUnchanged.Checked = true; + } + + private void UpdateSettings() + { + settings.InputFolder = textBoxInputFolder.Text; + settings.OutputFolder = textBoxOutputFolder.Text; + settings.ApplyNamingRules = checkBoxApplyNamingRules.Checked; + settings.VerboseOutput = checkBoxVerbose.Checked; + settings.UseFileName = checkBoxUseFilename.Checked; + if(radioButtonType0.Checked) + settings.OutputMidiType = OutputMidiType.Type0; + else if(radioButtonType1.Checked) + settings.OutputMidiType = OutputMidiType.Type1; + else + settings.OutputMidiType = OutputMidiType.LeaveUnchanged; + + if (radioButtonChannel1.Checked) + settings.OutputChannelNumber = 1; + else if (radioButtonChannel10.Checked) + settings.OutputChannelNumber = 10; + else + settings.OutputChannelNumber = -1; + } + + + private void MainForm_Load(object sender, EventArgs args) + { + string executableFolder = Path.GetDirectoryName(Application.ExecutablePath); + try + { + namingRules = NamingRules.LoadRules(Path.Combine(executableFolder, "NamingRules.xml")); + } + catch (Exception e) + { + MessageBox.Show(String.Format("Error reading NamingRules.xml\r\n{0}", e.ToString()), Application.ProductName); + Close(); + } + } + private void buttonConvert_Click(object sender, EventArgs e) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + } + else + { + UpdateSettings(); + if (!CheckInputFolderExists()) + return; + if (!CheckOutputFolderExists()) + return; + if (!CheckOutputFolderIsEmpty()) + return; + this.Cursor = Cursors.WaitCursor; + UpdateSettings(); + workQueued = ThreadPool.QueueUserWorkItem(new WaitCallback(ConvertThreadProc)); + if (workQueued) + { + this.Cursor = Cursors.WaitCursor; + } + } + } + + protected override void OnClosing(CancelEventArgs e) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + e.Cancel = true; + } + else + { + UpdateSettings(); + + settings.FirstTime = false; + settings.ProductVersion = Application.ProductVersion; + settings.Save(); + } + base.OnClosing(e); + } + + private void ConvertThreadProc(object state) + { + try + { + progressLog1.ClearLog(); + midiConverter = new MidiConverter(namingRules); + midiConverter.Progress += new EventHandler(midiConverter_Progress); + midiConverter.Start(); + } + finally + { + workQueued = false; + this.Invoke(new FinishedDelegate(ShowFinishedMessage)); + } + } + + void midiConverter_Progress(object sender, ProgressEventArgs e) + { + var color = Color.Black; + if (e.MessageType == ProgressMessageType.Warning) + { + color = Color.Blue; + } + else if (e.MessageType == ProgressMessageType.Error) + { + color = Color.Red; + } + else if (e.MessageType == ProgressMessageType.Trace) + { + color = Color.Purple; + } + + progressLog1.LogMessage(color, e.Message); + } + + delegate void FinishedDelegate(); + + void ShowFinishedMessage() + { + this.Cursor = Cursors.Default; + saveLogToolStripMenuItem.Enabled = true; + MessageBox.Show(String.Format("Finished:\r\n{0}", midiConverter.Summary), Application.ProductName); + } + + private bool CheckInputFolderExists() + { + if (!Directory.Exists(textBoxInputFolder.Text)) + { + DialogResult result = MessageBox.Show("Your selected input folder does not exist.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); + return false; + } + return true; + } + + private bool CheckOutputFolderExists() + { + if (!Directory.Exists(textBoxOutputFolder.Text)) + { + DialogResult result = MessageBox.Show("Your selected output folder does not exist.\r\nWould you like to create it now?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (result == DialogResult.Yes) + { + Directory.CreateDirectory(textBoxOutputFolder.Text); + } + else + { + return false; + } + } + return true; + } + + private bool CheckOutputFolderIsEmpty() + { + if ((Directory.GetFiles(textBoxOutputFolder.Text).Length > 0) || + (Directory.GetDirectories(textBoxOutputFolder.Text).Length > 0)) + { + MessageBox.Show("Your output folder is not empty.\r\n" + + "You must select an empty folder to store the converted MIDI files.", + Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); + return false; + } + return true; + } + + private void buttonBrowseEZDrummer_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderBrowser = new FolderBrowserDialog(); + folderBrowser.Description = "Select Input Folder"; + folderBrowser.SelectedPath = textBoxInputFolder.Text; + if (folderBrowser.ShowDialog() == DialogResult.OK) + { + textBoxInputFolder.Text = folderBrowser.SelectedPath; + } + } + + private void buttonBrowseOutputFolder_Click(object sender, EventArgs e) + { + FolderBrowserDialog folderBrowser = new FolderBrowserDialog(); + folderBrowser.Description = "Select Output Folder"; + folderBrowser.SelectedPath = textBoxOutputFolder.Text; + if (folderBrowser.ShowDialog() == DialogResult.OK) + { + textBoxOutputFolder.Text = folderBrowser.SelectedPath; + if (CheckOutputFolderExists()) + { + CheckOutputFolderIsEmpty(); + } + } + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void contentsToolStripMenuItem_Click(object sender, EventArgs e) + { + string helpFilePath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "midi_file_converter.html"); + try + { + System.Diagnostics.Process.Start(helpFilePath); + } + catch (Win32Exception) + { + MessageBox.Show("Could not display the help file", Application.ProductName); + } + } + + private void aboutToolStripMenuItem_Click(object sender, EventArgs e) + { + NAudio.Utils.AboutForm aboutForm = new NAudio.Utils.AboutForm(); + aboutForm.ShowDialog(); + } + + private void clearLogToolStripMenuItem_Click(object sender, EventArgs e) + { + progressLog1.ClearLog(); + saveLogToolStripMenuItem.Enabled = false; + } + + private void optionsToolStripMenuItem_Click(object sender, EventArgs e) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + } + else + { + AdvancedOptionsForm optionsForm = new AdvancedOptionsForm(); + optionsForm.ShowDialog(); + } + } + + private void saveLogToolStripMenuItem_Click(object sender, EventArgs args) + { + if (workQueued) + { + MessageBox.Show("Please wait until the current operation has finished", Application.ProductName); + } + else + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.InitialDirectory = textBoxOutputFolder.Text; + saveFileDialog.DefaultExt = ".txt"; + saveFileDialog.FileName = "Conversion Log.txt"; + saveFileDialog.Filter = "Text Files (*.txt)|*.txt"; + saveFileDialog.FilterIndex = 1; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + try + { + + using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName)) + { + string text = progressLog1.Text; + if (!text.Contains("\r")) + { + text = text.Replace("\n", "\r\n"); + } + writer.Write(text); + } + } + catch (Exception e) + { + MessageBox.Show( + String.Format("Error saving conversion log\r\n{0}", e.Message), + Application.ProductName, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } + } + + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/MainForm.resx b/MidiFileConverter/MainForm.resx new file mode 100644 index 00000000..69c56499 --- /dev/null +++ b/MidiFileConverter/MainForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/MidiFileConverter/MidiConverter.cs b/MidiFileConverter/MidiConverter.cs new file mode 100644 index 00000000..686cbb53 --- /dev/null +++ b/MidiFileConverter/MidiConverter.cs @@ -0,0 +1,483 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Text.RegularExpressions; +using NAudio.Utils; +using NAudio.Midi; + +namespace MarkHeath.MidiUtils +{ + class MidiConverter + { + public event EventHandler Progress; + int filesConverted; + int filesCopied; + int directoriesCreated; + int errors; + DateTime startTime; + Properties.Settings settings; + Regex ezdFileName; + NamingRules namingRules; + + public MidiConverter(NamingRules namingRules) + { + settings = Properties.Settings.Default; + this.namingRules = namingRules; + ezdFileName = new Regex(namingRules.FilenameRegex); + } + + public void Start() + { + filesConverted = 0; + filesCopied = 0; + directoriesCreated = 0; + errors = 0; + startTime = DateTime.Now; + LogInformation("{0} Beginning to Convert MIDI Files...", startTime); + LogInformation("Processing using EZdrummer MIDI Converter v{0}", System.Windows.Forms.Application.ProductVersion); + LogInformation("Output MIDI type {0}", settings.OutputMidiType); + LogInformation("Output Channel Number {0}", settings.OutputChannelNumber == -1 ? "Unchanged" : settings.OutputChannelNumber.ToString()); + + // warn user if they are using hidden settings + if (settings.RemoveSequencerSpecific) + { + LogWarning("Sequencer Specific Messages will be turned off"); + } + if (settings.RemoveEmptyTracks) + { + LogWarning("Empty type 1 tracks will be removed"); + } + if (!settings.RecreateEndTrackMarkers) + { + LogWarning("End track markers will be left where they are"); + } + if (settings.TrimTextEvents) + { + LogWarning("Text events will have whitespace trimmed"); + } + if (settings.AddNameMarker) + { + LogWarning("Name markers will be added"); + } + if (settings.RemoveExtraTempoEvents) + { + LogWarning("Extra tempo events will be removed"); + } + if (settings.RemoveExtraMarkers) + { + LogWarning("Extra markers will be removed"); + } + + ProcessFolder(settings.InputFolder, settings.OutputFolder, new string[0]); + TimeSpan timeTaken = DateTime.Now - startTime; + LogInformation("Finished in {0}", timeTaken); + LogInformation(Summary); + + } + + private string[] CreateNewContext(string[] oldContext, string newContextItem) + { + string[] newContext = new string[oldContext.Length + 1]; + for (int n = 0; n < oldContext.Length; n++) + { + newContext[n] = oldContext[n]; + } + newContext[oldContext.Length] = newContextItem; + return newContext; + } + + private void ProcessFolder(string folder, string outputFolder, string[] context) + { + string[] midiFiles = Directory.GetFiles(folder); + foreach (string midiFile in midiFiles) + { + try + { + ProcessFile(midiFile, outputFolder, context); + } + catch (Exception e) + { + LogError("Unexpected error processing file {0}", midiFile); + LogError(e.ToString()); + errors++; + } + } + + string[] subfolders = Directory.GetDirectories(folder); + foreach (string subfolder in subfolders) + { + string folderName = Path.GetFileName(subfolder); + string newOutputFolder = Path.Combine(outputFolder, folderName); + string[] newContext = CreateNewContext(context, folderName); + + if (!Directory.Exists(newOutputFolder)) + { + if (settings.VerboseOutput) + { + LogTrace("Creating folder {0}", newOutputFolder); + } + Directory.CreateDirectory(newOutputFolder); + directoriesCreated++; + } + + ProcessFolder(subfolder, newOutputFolder, newContext); + } + } + + private void ProcessFile(string file, string outputFolder, string[] context) + { + bool copy = false; + string fileName = Path.GetFileName(file); + string target = Path.Combine(outputFolder, fileName); + + if (Path.GetExtension(file).ToLower() == ".mid") + { + MidiFile midiFile = new MidiFile(file); + ConvertMidi(midiFile, target, CreateNewContext(context, Path.GetFileNameWithoutExtension(file))); + filesConverted++; + } + else + { + copy = true; + } + + if (copy) + { + if (settings.VerboseOutput) + { + LogTrace("Copying File {0} to {1}", fileName, target); + } + File.Copy(file, target); + filesCopied++; + } + } + + + private void ConvertMidi(MidiFile midiFile, string target, string[] context) + { + string fileNameWithoutExtension = context[context.Length - 1]; + string name = null; + long endTrackTime = -1; + if (settings.UseFileName) + { + name = fileNameWithoutExtension; + } + if (settings.ApplyNamingRules) + { + if (ezdFileName.Match(fileNameWithoutExtension).Success) + { + name = CreateEzdName(context); + } + } + + int outputFileType = midiFile.FileFormat; + int outputTrackCount; + if (settings.OutputMidiType == OutputMidiType.Type0) + { + outputFileType = 0; + } + else if (settings.OutputMidiType == OutputMidiType.Type1) + { + outputFileType = 1; + } + + if (outputFileType == 0) + { + outputTrackCount = 1; + } + else + { + if (midiFile.FileFormat == 0) + outputTrackCount = 2; + else + outputTrackCount = midiFile.Tracks; + } + + + MidiEventCollection events = new MidiEventCollection(outputFileType, midiFile.DeltaTicksPerQuarterNote); + for (int track = 0; track < outputTrackCount; track++) + { + events.AddTrack(); + } + if (name != null) + { + for (int track = 0; track < outputTrackCount; track++) + { + events[track].Add(new TextEvent(name, MetaEventType.SequenceTrackName, 0)); + } + if (settings.AddNameMarker) + { + events[0].Add(new TextEvent(name, MetaEventType.Marker, 0)); + } + } + + foreach (MidiEvent midiEvent in midiFile.Events[0]) + { + if (settings.OutputChannelNumber != -1) + midiEvent.Channel = settings.OutputChannelNumber; + MetaEvent metaEvent = midiEvent as MetaEvent; + if (metaEvent != null) + { + bool exclude = false; + switch (metaEvent.MetaEventType) + { + case MetaEventType.SequenceTrackName: + if (name != null) + { + exclude = true; + } + break; + case MetaEventType.SequencerSpecific: + exclude = settings.RemoveSequencerSpecific; + break; + case MetaEventType.EndTrack: + exclude = settings.RecreateEndTrackMarkers; + endTrackTime = metaEvent.AbsoluteTime; + break; + case MetaEventType.SetTempo: + if (metaEvent.AbsoluteTime != 0 && settings.RemoveExtraTempoEvents) + { + LogWarning("Removing a tempo event ({0}bpm) at {1} from {2}", ((TempoEvent)metaEvent).Tempo, metaEvent.AbsoluteTime, target); + exclude = true; + } + break; + case MetaEventType.TextEvent: + if (settings.TrimTextEvents) + { + TextEvent textEvent = (TextEvent)midiEvent; + textEvent.Text = textEvent.Text.Trim(); + if (textEvent.Text.Length == 0) + { + exclude = true; + } + } + break; + case MetaEventType.Marker: + if (settings.AddNameMarker && midiEvent.AbsoluteTime == 0) + { + exclude = true; + } + if (settings.RemoveExtraMarkers && midiEvent.AbsoluteTime > 0) + { + LogWarning("Removing a marker ({0}) at {1} from {2}", ((TextEvent)metaEvent).Text, metaEvent.AbsoluteTime, target); + exclude = true; + } + break; + } + if (!exclude) + { + events[0].Add(midiEvent); + } + } + else + { + if (outputFileType == 1) + events[1].Add(midiEvent); + else + events[0].Add(midiEvent); + } + } + + // now do track 1 (Groove Monkee) + for (int inputTrack = 1; inputTrack < midiFile.Tracks; inputTrack++) + { + int outputTrack; + if(outputFileType == 1) + outputTrack = inputTrack; + else + outputTrack = 0; + + foreach (MidiEvent midiEvent in midiFile.Events[inputTrack]) + { + if (settings.OutputChannelNumber != -1) + midiEvent.Channel = settings.OutputChannelNumber; + bool exclude = false; + MetaEvent metaEvent = midiEvent as MetaEvent; + if (metaEvent != null) + { + switch (metaEvent.MetaEventType) + { + case MetaEventType.SequenceTrackName: + if (name != null) + { + exclude = true; + } + break; + case MetaEventType.SequencerSpecific: + exclude = settings.RemoveSequencerSpecific; + break; + case MetaEventType.EndTrack: + exclude = settings.RecreateEndTrackMarkers; + break; + } + } + if (!exclude) + { + events[outputTrack].Add(midiEvent); + } + } + if(outputFileType == 1 && settings.RecreateEndTrackMarkers) + { + AppendEndMarker(events[outputTrack]); + } + } + + if (settings.RecreateEndTrackMarkers) + { + if (outputFileType == 1) + { + // if we are converting type 0 to type 1 and recreating end markers, + if (midiFile.FileFormat == 0) + { + AppendEndMarker(events[1]); + } + } + // make sure that track zero has an end track marker + AppendEndMarker(events[0]); + } + else + { + // if we are converting type 0 to type 1 without recreating end markers, + // then we still need to add an end marker to track 1 + if (midiFile.FileFormat == 0) + { + // use the time we got from track 0 as the end track time for track 1 + if (endTrackTime == -1) + { + LogError("Error adding track 1 end marker"); + // make it a valid MIDI file anyway + AppendEndMarker(events[1]); + } + else + { + events[1].Add(new MetaEvent(MetaEventType.EndTrack, 0, endTrackTime)); + } + } + } + + if (settings.VerboseOutput) + { + LogTrace("Processing {0}: {1}", name, target); + } + + if (settings.RemoveEmptyTracks) + { + MidiEventCollection newList = new MidiEventCollection(events.MidiFileType, events.DeltaTicksPerQuarterNote); + + int removed = 0; + for (int track = 0; track < events.Tracks; track++) + { + IList trackEvents = events[track]; + if (track < 2) + { + newList.AddTrack(events[track]); + } + else + { + if(HasNotes(trackEvents)) + { + newList.AddTrack(trackEvents); + } + else + { + removed++; + } + } + + } + if (removed > 0) + { + events = newList; + LogWarning("Removed {0} empty tracks from {1} ({2} remain)", removed, target, events.Tracks); + } + } + MidiFile.Export(target, events); + } + + private bool HasNotes(IList midiEvents) + { + foreach (MidiEvent midiEvent in midiEvents) + { + if (midiEvent.CommandCode == MidiCommandCode.NoteOn) + return true; + } + return false; + } + + private void AppendEndMarker(IList eventList) + { + long absoluteTime = 0; + if (eventList.Count > 0) + absoluteTime = eventList[eventList.Count - 1].AbsoluteTime; + eventList.Add(new MetaEvent(MetaEventType.EndTrack, 0, absoluteTime)); + } + + private string CreateEzdName(string[] context) + { + StringBuilder name = new StringBuilder(); + int contextLevels = Math.Min(namingRules.ContextDepth, context.Length); + for (int n = 0; n < contextLevels; n++) + { + string filtered = ApplyNameFilters(context[context.Length - contextLevels + n]); + if (filtered.Length > 0) + { + name.Append(filtered); + + if (n != contextLevels - 1) + name.Append(namingRules.ContextSeparator); + } + } + return name.ToString(); + } + + private string ApplyNameFilters(string name) + { + foreach (NamingRule rule in namingRules.Rules) + { + name = Regex.Replace(name, rule.Regex, rule.Replacement); + } + return name; + } + + private void LogTrace(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Trace, + message, args)); + } + + private void LogInformation(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Information, + message, args)); + } + + private void LogWarning(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Warning, + message, args)); + } + + private void LogError(string message, params object[] args) + { + OnProgress(this, new ProgressEventArgs(ProgressMessageType.Error, + message, args)); + } + + protected void OnProgress(object sender, ProgressEventArgs args) + { + if (Progress != null) + { + Progress(sender, args); + } + } + + public string Summary + { + get + { + return String.Format("Files Converted {0}\r\nFiles Copied {1}\r\nFolders Created {2}\r\nErrors {3}", filesConverted, filesCopied, directoriesCreated, errors); + } + } + } +} diff --git a/MidiFileConverter/MidiFileConverter.csproj b/MidiFileConverter/MidiFileConverter.csproj new file mode 100644 index 00000000..6f2e6581 --- /dev/null +++ b/MidiFileConverter/MidiFileConverter.csproj @@ -0,0 +1,169 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {5B5897BD-A423-4AF8-8A59-1C1372ED77DB} + WinExe + Properties + MarkHeath.MidiUtils + MIDI File Converter + + + + + + + + + + + + + 3.5 + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + Client + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + + + + + + + + Form + + + AboutForm.cs + + + Form + + + AdvancedOptionsForm.cs + + + Form + + + MainForm.cs + + + + + + + + + AboutForm.cs + Designer + + + Designer + AdvancedOptionsForm.cs + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {DA4F02E3-0B5E-42CD-B8D9-5583FA51D66E} + NAudio + + + + + Always + + + Always + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/MidiFileConverter/MidiFileConverter.csproj.vspscc b/MidiFileConverter/MidiFileConverter.csproj.vspscc new file mode 100644 index 00000000..feffdeca --- /dev/null +++ b/MidiFileConverter/MidiFileConverter.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/MidiFileConverter/NamingRule.cs b/MidiFileConverter/NamingRule.cs new file mode 100644 index 00000000..57338a4f --- /dev/null +++ b/MidiFileConverter/NamingRule.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace MarkHeath.MidiUtils +{ + class NamingRules + { + string filenameRegex; + int contextDepth; + string contextSeparator; + List rules; + + public static NamingRules LoadRules(string xmlPath) + { + NamingRules namingRules = new NamingRules(); + namingRules.rules = new List(); + + using (XmlReader reader = new XmlTextReader(xmlPath)) + { + reader.ReadStartElement("Rules"); + reader.ReadStartElement("GeneralSettings"); + + reader.ReadStartElement("FilenameRegex"); + namingRules.filenameRegex = reader.ReadString(); + reader.ReadEndElement(); + + reader.ReadStartElement("ContextDepth"); + namingRules.contextDepth = reader.ReadContentAsInt(); + if (namingRules.ContextDepth < 1 || namingRules.ContextDepth > 4) + throw new FormatException("Context Depth must be between 1 and 4"); + reader.ReadEndElement(); + + reader.ReadStartElement("ContextSeparator"); + namingRules.contextSeparator = reader.ReadString(); + reader.ReadEndElement(); + + reader.ReadEndElement(); + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.EndElement) + { + System.Diagnostics.Debug.Assert(reader.Name == "Rules"); + break; + } + //if (reader.IsStartElement()) + // System.Diagnostics.Debug.Assert(reader.Name == "Rule"); + reader.ReadStartElement("Rule"); + //reader.Read(); + + reader.ReadStartElement("SearchString"); + string regex = reader.ReadString(); + reader.ReadEndElement(); + reader.ReadStartElement("Replacement"); + string replacement = reader.ReadString(); + reader.ReadEndElement(); + reader.ReadEndElement(); + namingRules.rules.Add(new NamingRule(regex, replacement)); + } + reader.ReadEndElement(); + } + return namingRules; + } + + public string ContextSeparator + { + get { return contextSeparator; } + } + + public int ContextDepth + { + get { return contextDepth; } + } + + public string FilenameRegex + { + get { return filenameRegex; } + } + + public List Rules + { + get { return rules; } + } + } + + class NamingRule + { + string regex; + string replacement; + + public NamingRule(string regex, string replacement) + { + this.regex = regex; + this.replacement = replacement; + } + + public string Regex + { + get { return regex; } + } + + public string Replacement + { + get { return replacement; } + } + + + } +} diff --git a/MidiFileConverter/NamingRules.xml b/MidiFileConverter/NamingRules.xml new file mode 100644 index 00000000..306ba3ac --- /dev/null +++ b/MidiFileConverter/NamingRules.xml @@ -0,0 +1,76 @@ + + + + ^[A-Z]\@ + 3 + - + + + ^[0-9A-Z]+\@[0-9][0-9]\. + + + + ^[0-9A-Z]+\@ + + + + _ + + + + # + / + + + GROOVE + G + + + FILL + F + + + Fill + F + + + POP/ROCK + P/R + + + FUNK/ROCK + F/R + + + BALLAD + BLD + + + ^FILLS + + + + FILLS + F + + + MOTOWN + MTN + + + SIDESTICK + STK + + + EZX COCKTAIL + Cocktail + + + SAMBA + + + + BAIAO + + + \ No newline at end of file diff --git a/MidiFileConverter/OutputMidiType.cs b/MidiFileConverter/OutputMidiType.cs new file mode 100644 index 00000000..bd5d180b --- /dev/null +++ b/MidiFileConverter/OutputMidiType.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MarkHeath.MidiUtils +{ + enum OutputMidiType + { + LeaveUnchanged, + Type0, + Type1 + } +} diff --git a/MidiFileConverter/Program.cs b/MidiFileConverter/Program.cs new file mode 100644 index 00000000..bdc95af7 --- /dev/null +++ b/MidiFileConverter/Program.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace MarkHeath.MidiUtils +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} \ No newline at end of file diff --git a/MidiFileConverter/ProgressEventArgs.cs b/MidiFileConverter/ProgressEventArgs.cs new file mode 100644 index 00000000..74beb53e --- /dev/null +++ b/MidiFileConverter/ProgressEventArgs.cs @@ -0,0 +1,81 @@ +using System; + +namespace MarkHeath.MidiUtils +{ + /// + /// Progress Event Arguments + /// + public class ProgressEventArgs : EventArgs + { + private string message; + private ProgressMessageType messageType; + + /// + /// New progress event arguments + /// + /// The message type + /// The message + public ProgressEventArgs(ProgressMessageType messageType, string message) + { + this.message = message; + this.messageType = messageType; + } + + /// + /// New progress event arguments + /// + /// The message type + /// the message format string + /// format arguments + public ProgressEventArgs(ProgressMessageType messageType, string message, params object[] args) + { + this.messageType = messageType; + this.message = String.Format(message, args); + } + + /// + /// The message + /// + public string Message + { + get + { + return message; + } + } + + /// + /// The message type + /// + public ProgressMessageType MessageType + { + get + { + return messageType; + } + } + } + + /// + /// Progress Message Type + /// + public enum ProgressMessageType + { + /// + /// Trace + /// + Trace, + /// + /// Information + /// + Information, + /// + /// Warning + /// + Warning, + /// + /// Error + /// + Error, + } +} diff --git a/MidiFileConverter/Properties/AssemblyInfo.cs b/MidiFileConverter/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..1452e8bb --- /dev/null +++ b/MidiFileConverter/Properties/AssemblyInfo.cs @@ -0,0 +1,89 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MIDI File Converter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Mark Heath")] +[assembly: AssemblyProduct("MIDI File Converter")] +[assembly: AssemblyCopyright("Copyright © Mark Heath 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c25a6f6b-abf0-4460-a49e-d73c069f80e3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("0.3.10.0")] +[assembly: AssemblyFileVersion("0.3.10.0")] + +// build 1 29 Oct 2006 +// build 1 is experimental +// updated for Groove Monkee loops so it works on all incoming files +// build 2 30 Oct 2006 +// setting to leave MIDI file type unchanged +// settings to force notes to a specific channel +// added clip naming option +// uses new generic about box +// uses new generic progress log +// decoupled logic from Main Form UI +// option not to rename files at all +// Hidden option to trim text markers and remove blank +// Hidden option to insert a name marker and delete all others +// Hidden option to recreate end track markers +// basic install script +// should now be able to cope with multi-track type 1s as input as well +// show hourglass +// remove empty tracks option added +// settings upgrade option +// Update help file +// build 3 +// fixed a bug removing blank tracks +// build 4 +// advanced options dialog +// clear log on start +// build 5 31 Oct 2006 +// Remove extra tempo events option +// Remove extra markers option +// build 6 31 Oct 2006 +// option to save conversion log +// build 7 2 Nov 2006 +// final build for release +// build 8 3 Nov 2006 +// minor changes +// build 9 6 Mar 2007 +// renamed to MIDI file converter +// now hosted on CodePlex +// fixed a bug where track 1 didn't have an end track marker if Recreate Track End Markers wasn't set, +// and converting from type 0 to type 1 +// build 10 5 Apr 2007 +// updated to use new MidiEventCollection + +// revamp help for advanced options + +// Next version +// support changing note length +// perhaps allow markers less than final note event +// work out times in measures and beats +// review error handling +// Consider a command line interface +// Selecting what to copy & what to process (somehow) +// Protect against output folder being a subfolder of input folder + +// Testing +// Public release \ No newline at end of file diff --git a/MidiFileConverter/Properties/Resources.Designer.cs b/MidiFileConverter/Properties/Resources.Designer.cs new file mode 100644 index 00000000..455e7cd2 --- /dev/null +++ b/MidiFileConverter/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MarkHeath.MidiUtils.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MarkHeath.MidiUtils.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/MidiFileConverter/Properties/Resources.resx b/MidiFileConverter/Properties/Resources.resx new file mode 100644 index 00000000..ffecec85 --- /dev/null +++ b/MidiFileConverter/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MidiFileConverter/Properties/Settings.Designer.cs b/MidiFileConverter/Properties/Settings.Designer.cs new file mode 100644 index 00000000..c6ae9b8e --- /dev/null +++ b/MidiFileConverter/Properties/Settings.Designer.cs @@ -0,0 +1,218 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MarkHeath.MidiUtils.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string InputFolder { + get { + return ((string)(this["InputFolder"])); + } + set { + this["InputFolder"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string OutputFolder { + get { + return ((string)(this["OutputFolder"])); + } + set { + this["OutputFolder"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ApplyNamingRules { + get { + return ((bool)(this["ApplyNamingRules"])); + } + set { + this["ApplyNamingRules"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool VerboseOutput { + get { + return ((bool)(this["VerboseOutput"])); + } + set { + this["VerboseOutput"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveSequencerSpecific { + get { + return ((bool)(this["RemoveSequencerSpecific"])); + } + set { + this["RemoveSequencerSpecific"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Type1")] + public global::MarkHeath.MidiUtils.OutputMidiType OutputMidiType { + get { + return ((global::MarkHeath.MidiUtils.OutputMidiType)(this["OutputMidiType"])); + } + set { + this["OutputMidiType"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("-1")] + public int OutputChannelNumber { + get { + return ((int)(this["OutputChannelNumber"])); + } + set { + this["OutputChannelNumber"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool UseFileName { + get { + return ((bool)(this["UseFileName"])); + } + set { + this["UseFileName"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool TrimTextEvents { + get { + return ((bool)(this["TrimTextEvents"])); + } + set { + this["TrimTextEvents"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool AddNameMarker { + get { + return ((bool)(this["AddNameMarker"])); + } + set { + this["AddNameMarker"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool RecreateEndTrackMarkers { + get { + return ((bool)(this["RecreateEndTrackMarkers"])); + } + set { + this["RecreateEndTrackMarkers"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveEmptyTracks { + get { + return ((bool)(this["RemoveEmptyTracks"])); + } + set { + this["RemoveEmptyTracks"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool FirstTime { + get { + return ((bool)(this["FirstTime"])); + } + set { + this["FirstTime"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ProductVersion { + get { + return ((string)(this["ProductVersion"])); + } + set { + this["ProductVersion"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveExtraTempoEvents { + get { + return ((bool)(this["RemoveExtraTempoEvents"])); + } + set { + this["RemoveExtraTempoEvents"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool RemoveExtraMarkers { + get { + return ((bool)(this["RemoveExtraMarkers"])); + } + set { + this["RemoveExtraMarkers"] = value; + } + } + } +} diff --git a/MidiFileConverter/Properties/Settings.settings b/MidiFileConverter/Properties/Settings.settings new file mode 100644 index 00000000..4f321f15 --- /dev/null +++ b/MidiFileConverter/Properties/Settings.settings @@ -0,0 +1,54 @@ + + + + + + + + + + + + True + + + True + + + False + + + Type1 + + + -1 + + + True + + + False + + + False + + + True + + + False + + + True + + + + + + False + + + False + + + \ No newline at end of file diff --git a/MidiFileConverter/app.config b/MidiFileConverter/app.config new file mode 100644 index 00000000..802eb0a3 --- /dev/null +++ b/MidiFileConverter/app.config @@ -0,0 +1,60 @@ + + + + +
+ + + + + + + + + + + + True + + + True + + + False + + + Type1 + + + -1 + + + True + + + False + + + False + + + True + + + False + + + True + + + + + + False + + + False + + + + diff --git a/MidiFileConverter/midi_file_converter.html b/MidiFileConverter/midi_file_converter.html new file mode 100644 index 00000000..37c32036 --- /dev/null +++ b/MidiFileConverter/midi_file_converter.html @@ -0,0 +1,307 @@ + + + MIDI File Converter + + +

MIDI File Converter

+

+ MIDI File Converter is a utility designed to convert the MIDI file library + included with Toontrack's EZdrummer virtual + instrument from MIDI type 0 to MIDI type 1, with a customisable name as the track + 1 name. This has the advantage that users of Cakewalk's + SONAR + will find that the MIDI clips created when they drag and drop into + the track pane are given a meaningful default name. It also supports the option + to leave the files as type 0 and simply change the track name, which is supported + by SONAR 6 and above. +

+ +

This utility has now been expanded to alter other MIDI files + that you might be using with EZD to adjust their end time markers so that they loop + correctly with EZdrummer's built in loop browser. (EZD version 1.0.3 introduced + some problems in this area).

+

+ Download

+

+ A link to the latest version of MIDI File converter can be found + here.

+

+ Installation and Requirements

+

+ MIDI File Converter requires the .NET framework version 2.0 to be installed. + You can download this + here. Once you have done this you can run the installer (or download the zip archive, + decompress it and run MIDI File Converter.exe).

+ +

Settings

+ + MIDI File Converter Screenshot + +

Input Folder

+

+ Normally you would choose the EZdrummer MIDI folder as the input folder. This is + typically located at C:\Program Files\Toontrack\EZDrummer\Midi. However, if you + want to specifically choose which MIDI files will be processed, you can select a + subfolder or a new folder into which you have copied in the exact files you want to be processed.

+

+ Output Folder

+

+ MIDI File Converter will not modify any existing files or folders on your PC. + What it does is recreates all the contents of the input folder into an empty output + folder you have specified. This folder must be initially blank, and its contents + can be copied into the Toontrack MIDI folder when you have finished the conversion + (you must do this part yourself).

+

+ Clip Naming

+

+ These settings govern the clip name you will see when dragging into your host sequencer. + Please note that in certain circumstances, EZD will generate its own clip name instead + of the one in the file. You will need to experiment with your own host sequencer + to see how it behaves.

+

+ If the Apply XML Naming Rules to Toontrack EZD Patterns option is selected, then + whenever a MIDI file that was supplied with EZdrummer is processed, it will be given + a MIDI clip name that is calculated according to the rules in the NamingRules.xml + file (see "Advanced Customisation" below for more details). This setting is turned + on by default.

+

+ If the Use filename for other MIDI patterns option is selected, then all other + MIDI files in the input folder will have their clip name set to the name of the + file (minus the .mid extension). This setting is on by default. If you turn it off, + MIDI files will retain whatever clip names they already had (which may be blank).

+

+ MIDI Note Channel

+

+ You will normally want to leave MIDI notes on whatever channel they were already + on. However, you can move them all to track 1 to be just like the ones in the included + EZD libraries. Or you can move them all to track 10, so that when you play them + in Windows Media Player, or through a GM module, it will play drum sounds instead + of piano sounds.

+

+ Output File Type

+

+ MIDI File Converter was written to convert Toontrack's type 0 files into type + 1, so that their clip names would display correctly in SONAR 5. However, users of + different hosts may find that they can use type 0 without problems. Choose type + 1 to force all MIDI files to type 1, type 0 to force them all to type 0, and leave + unchanged if you want them to stay as they are.

+

+ Verbose Output

+

+ Select this option if you want a detailed run-down of everything that EZdrummer + MIDI Converter is doing. If it is turned off, you will still be informed of any + errors encountered.

+

+ How to make MIDI clip names appear in SONAR

+

Note: these are for users of SONAR 5 or previous versions. SONAR 6 can display + EZdrummers own clip names. You may still be able to use this utility with SONAR 6 though + if you want to customise what those clip names will be.

+
    +
  • First, make sure you have no running instances of EZdrummer.
  • +
  • MIDI File Converter will not modify, delete or rename any files on your computer. + It will only create new ones. So now, create an empty folder somewhere to contain + the created library. A good example would be on your desktop, in a subfolder called + Midi.
  • +
  • Make sure that the EZdrummer MIDI folder is pointing at EZdrummer's own MIDI folder.
  • +
  • Point the output folder at your desired output path. MIDI File Converter will + insist that this is a blank folder, to avoid confusion.
  • +
  • You want to select type 1 as the ouput file type.
  • +
  • If you have user MIDI files you would like to be given clip names as well then select + the Use filename for other MIDI patterns option.
  • +
  • By default Apply XML Naming Rules is enabled. If you turn this off, the track name + for converted EZdrummer MIDI files will simply be the filename minus the .mid extension. + It is possible to extensively customise the naming rules, but this is for advanced + users only. See the next section for more details. If you just have the EZdrummer + included MIDI files, and no expansion packs, the default naming rules will probably + be just fine for you.
  • +
  • When you are ready, click Convert. The process will take a few minutes, depending + on the speed of your computer.
  • +
  • When it has finished, you will be informed of how many files were processed, as + well as the number of errors encountered. If you have any errors at all, it is recommended + that you report them to mark.heath@gmail.com. +
  • +
  • If you are happy that the output folder contains the MIDI files you want, you are + ready to replace EZdrummer's MIDI files with the converted ones. Please make a backup + first. One way would simply be to rename the existing MIDI folder to something + else (e.g. Original MIDI).
  • +
  • Now copy the entire contents of the output directory into the Toontrack MIDI folder + (by default this will be C:\Program Files\Toontrack\EZDrummer\Midi.
  • +
+

+ How to make user MIDI files loop correctly in EZD 1.0.3

+
    +
  • First, copy all the folders of MIDI files that have the looping problem into an + empty folder. This will be your input folder.
  • +
  • Create another blank folder to use as your output folder.
  • +
  • If you would like them to be given MIDI clip names based on their filename at the + same time, ensure that "Use filename for other MIDI patterns" is selected.
  • +
  • You can also take the opportunity to modify the MIDI file type or the channel number + for the notes. This may be helpful depending on your host.
  • +
  • You may also wish to turn on some options in the advanced options screen, available + on the Tools menu.
  • +
  • When you are ready click Convert. If the process completes without errors, you can + replace your user MIDI files with those in the output folder.
  • +
+

+ Advanced Customisation

+

+ MIDI File Converter allows extensive customisation of the filenames it creates. + If you are comfortable with editing XML files and using regular expressions, you + will be able to customise these settings. This allows the flexibility to support + any EZX expansion pack MIDI files you may purchase. The settings are all stored + in NamingRules.xml, which should be in the same folder as the EZdrummer MIDI + Converter application. Please be careful modifying these settings and always check + that the output is what you wanted before replacing your EZdrummer MIDI files.

+
    +
  • General Settings - This section contains some global settings. Do not change + the order of the keys in this section.
  • +
  • FilenameRegex - This pattern is matched against all the filenames. If a match + is found, then MIDI File Converter considers this to be an EZdrummer MIDI file, + and will attempt to apply naming rules. The default setting looks for a filename + that starts with one uppercase letter followed by an @ symbol. You only need to + change this setting if files you wanted naming rules applied on are being missed + out, or files you didn't want the naming rules applied on were being included.
  • +
  • ContextDepth - This is the number of components (folders and filename) that + will be used to formulate the track 1 name. This is normally set to 3 (4 is the + maximum), but can be set lower if desired.
  • +
  • ContextSeparator - This string will be inserted between the converted name + of each item in the context hierarchy. If the naming rules have caused the length + of a section to be set to zero, then the context separator is not added. The default + will be just fine for most people.
  • +
  • Rules - The rules section allows you to specify a number of string substitutions + to be applied to each part of the name. This consists of two parts - the SearchString + and the Replacement (see below). Each rule is applied in turn on each folder + name or filename used to form the track name. The order is very important in this + section - the rules will be applied in the order they appear in the NamingRules.xml + file.
  • +
  • SearchString - this is a regular expression that defines a string to look + for within the file or folder name.
  • +
  • Replacement - this is a literal string that will replace all occurences of + the search string in the file or folder name being processed.
  • +
+

+ Some example rules from the default NamingRules.xml file:

+ <Rule>
+    <SearchString>^[0-9A-Z]+\@[0-9][0-9]\.</SearchString>
+    <Replacement></Replacement>
+ </Rule>
+

+ This rule looks for all file or folder names that start with one or more digits + or upper case letters followed by an @ sign, followed by exactly two digits and + then a full stop. It replaces it with a blank string. This effectively strips off + the start of EZdrummer folder and filenames.

+ <Rule>
+    <SearchString>POP/ROCK</SearchString>
+    <Replacement>P/R</Replacement>
+ </Rule>
+

+ This rule abbreviates any instances of the upper case string "POP/ROCK" to "P/R". + Note that this will only operate if it follows the rule that converts the '#' character + to a '/' character.

+ <Rule>
+    <SearchString>GROOVE </SearchString>
+    <Replacement>G</Replacement>
+ </Rule>
+

+ This rule abbreviates any instances of the upper case string "GROOVE" followed by + a trailing space to simply "G". Note that this only works because we have already + converted all underscore characters to spaces with a previous rule.

+ <Rule>
+    <SearchString>SAMBA</SearchString>
+    <Replacement></Replacement>
+ </Rule>
+

+ The Samba MIDI files included with the Cocktail kit EZX will have the word Samba + in their name twice by default. This rule strips out the fully capitalised folder + name, so the mixed case "Samba" in the filename can be used on its own.

+

+ Advanced Options

+

+ There are some extra settings available that may be useful for some third party + add-on MIDI libraries. These are accessed from the Tools menu. They are recommended + for advanced users only. Messages will appear in the output window to inform you + of these settings being modified from their default values.

+
    +
  • Remove Sequencer Specific Events - The Toontrack EZD files each have a sequencer + specific event in them. I don't know what it is for, but you can remove it if you + want (maybe to trick EZD into thinking this is a user file instead). Default is + False.
  • +
  • Recreate End Track Events - This is what will fix most looping issues in + EZD v1.03. It deletes the existing end track markers and puts new ones in that fall + exactly after the last note event. Default is True. If this is set to False, + then end track markers are left exactly where they were.
  • +
  • Add Name Marker - In addition to naming the tracks, this will add a marker + to track zero with the name of the clip. Any existing markers at position 0 on track + 0 will be removed. Default is False
  • +
  • Trim Text Events - Trims the whitespace of Text events and removes them if + they are zero length. Default is False
  • +
  • Remove Empty Tracks - If the input file is type 1 and has tracks containing + no note events, these tracks can be removed. The control track and the first track + are never removed. Default is False.
  • +
  • Remove Extra Tempo Events - Most MIDI files have just one tempo event on + the first tick. This option removes any subsequent ones (this is sometimes needed + to fix the looping issue in EZD v1.0.3). Default is False.
  • +
  • Remove Extra Markers - This will remove any markers that are not at the first + tick. This is sometimes needed to fix the looping issue in EZD v1.0.3. Default is + False.
  • +
+

+ Notes

+
    +
  • This software is not affiliated in any way with Toontrack. It is not guaranteed + to work on future versions of EZdrummer, or with EZX expansion packs (although I + expect it will work just fine).
  • +
  • I recommend that if you are installing any patches or updates to EZdrummer, that + you restore the original Midi directory before doing so, and then re-run the EZdrummer + MIDI Converter afterwards.
  • +
  • If you have some user MIDI patterns that you do not want MIDI File Converter + to attempt to convert, simply remove them from the input directory before running + the conversion process. You do not have to point it to the real EZdrummer MIDI directory + if you don't want to. You could create your own folder with only the files you want + converted in.
  • +
  • For the technically inclined, here is an explanation of what happens to your MIDI + events when converting to type 1. All meta-events are placed on track 0. All note + events are placed on track 1. In addition a track name (the one worked out by the + naming rules) and a track end marker are added to track 1.
  • +
+

+ Version History

+

+ The latest version of MIDI File Converter can be found at + http://www.codeplex.com/naudio. +

+
    +
  • v0.1 9 Oct 2006 +
      +
    • First public beta release
    • +
    +
  • +
  • v0.2 2 Nov 2006 +
      +
    • Now processes all MIDI files in the input folder, rather than just copying type + 1
    • +
    • Allow processing of non-EZD files (to move end track markers to work with EZD v1.03)
    • +
    • Ability to select output file type
    • +
    • Both tracks in a type 1 file will be given the same track name
    • +
    • An advanced options dialog added with extra options
    • +
    • Can optionally force all MIDI note events onto channel 1 or 10
    • +
    • Properly handles non-ASCII characters (such as copyright symbol)
    • +
    • Has an installer
    • +
    • Can save the conversion log
    • +
    +
  • +
  • v0.3 16 Mar 2007 +
      +
    • Name changed to MIDI File Converter to reflect its use for more general-purpose tasks
    • +
    • Fixed a bug where track 1 didn't have an end track marker when converting from type 0 to type 1
    • +
    +
  • +
  • v0.4 - t.b.a. +
      +
    • Fixed a sysex writing bug
    • +
    • Better preserving of event ordering
    • +
    +
  • +
+ + diff --git a/MixDiff/AboutForm.Designer.cs b/MixDiff/AboutForm.Designer.cs new file mode 100644 index 00000000..bd8cd680 --- /dev/null +++ b/MixDiff/AboutForm.Designer.cs @@ -0,0 +1,144 @@ +namespace NAudio.Utils +{ + partial class AboutForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.linkLabelWebsite = new System.Windows.Forms.LinkLabel(); + this.buttonOK = new System.Windows.Forms.Button(); + this.labelProductName = new System.Windows.Forms.Label(); + this.labelCopyright = new System.Windows.Forms.Label(); + this.linkLabelFeedback = new System.Windows.Forms.LinkLabel(); + this.label3 = new System.Windows.Forms.Label(); + this.labelVersion = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // linkLabelWebsite + // + this.linkLabelWebsite.AutoSize = true; + this.linkLabelWebsite.Location = new System.Drawing.Point(13, 67); + this.linkLabelWebsite.Name = "linkLabelWebsite"; + this.linkLabelWebsite.Size = new System.Drawing.Size(168, 13); + this.linkLabelWebsite.TabIndex = 0; + this.linkLabelWebsite.TabStop = true; + this.linkLabelWebsite.Text = "http://www.codeplex.com/naudio"; + this.linkLabelWebsite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelWebsite_LinkClicked); + // + // buttonOK + // + this.buttonOK.Location = new System.Drawing.Point(111, 124); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 1; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // labelProductName + // + this.labelProductName.AutoSize = true; + this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelProductName.Location = new System.Drawing.Point(13, 13); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new System.Drawing.Size(196, 16); + this.labelProductName.TabIndex = 2; + this.labelProductName.Text = "{Application.ProductName}"; + // + // labelCopyright + // + this.labelCopyright.AutoSize = true; + this.labelCopyright.Location = new System.Drawing.Point(13, 51); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new System.Drawing.Size(149, 13); + this.labelCopyright.TabIndex = 2; + this.labelCopyright.Text = "Copyright © Mark Heath 2007"; + // + // linkLabelFeedback + // + this.linkLabelFeedback.AutoSize = true; + this.linkLabelFeedback.Location = new System.Drawing.Point(13, 101); + this.linkLabelFeedback.Name = "linkLabelFeedback"; + this.linkLabelFeedback.Size = new System.Drawing.Size(150, 13); + this.linkLabelFeedback.TabIndex = 3; + this.linkLabelFeedback.TabStop = true; + this.linkLabelFeedback.Text = "mark.heath@gmail.com"; + this.linkLabelFeedback.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelFeedback_LinkClicked); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 85); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(243, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Send feedback, feature requests and bug fixes to:"; + // + // labelVersion + // + this.labelVersion.AutoSize = true; + this.labelVersion.Location = new System.Drawing.Point(13, 33); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new System.Drawing.Size(93, 13); + this.labelVersion.TabIndex = 2; + this.labelVersion.Text = "{Version: X.X.X.X}"; + // + // AboutForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 159); + this.Controls.Add(this.linkLabelFeedback); + this.Controls.Add(this.label3); + this.Controls.Add(this.labelVersion); + this.Controls.Add(this.labelCopyright); + this.Controls.Add(this.labelProductName); + this.Controls.Add(this.buttonOK); + this.Controls.Add(this.linkLabelWebsite); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About {Application.ProductName}"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.LinkLabel linkLabelWebsite; + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Label labelProductName; + private System.Windows.Forms.Label labelCopyright; + private System.Windows.Forms.LinkLabel linkLabelFeedback; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label labelVersion; + } +} \ No newline at end of file diff --git a/MixDiff/AboutForm.cs b/MixDiff/AboutForm.cs new file mode 100644 index 00000000..2d5861e0 --- /dev/null +++ b/MixDiff/AboutForm.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NAudio.Utils +{ + /// + /// A standard about form + /// + public partial class AboutForm : Form + { + /// + /// Creates a new about form + /// + public AboutForm() + { + InitializeComponent(); + labelProductName.Text = Application.ProductName; + labelVersion.Text = String.Format("Version: {0}", Application.ProductVersion); + this.Text = String.Format("About {0}", Application.ProductName); + } + + private void linkLabelWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start(linkLabelWebsite.Text); + } + + private void linkLabelFeedback_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + System.Diagnostics.Process.Start("mailto:" + linkLabelFeedback.Text); + } + + private void buttonOK_Click(object sender, EventArgs e) + { + this.Close(); + } + + /// + /// The URL of the website to use for help + /// e.g. http://www.codeplex.com/naudio + /// + public string Url + { + get { return linkLabelWebsite.Text; } + set { linkLabelWebsite.Text = value; } + } + + /// + /// The email address for feedback + /// + public string Email + { + get { return linkLabelFeedback.Text; } + set { linkLabelFeedback.Text = value; } + } + + /// + /// The copyright info + /// e.g. Copyright © 2007 Mark Heath + /// + public string Copyright + { + get { return labelCopyright.Text; } + set { labelCopyright.Text = value; } + } + } +} \ No newline at end of file diff --git a/MixDiff/AboutForm.resx b/MixDiff/AboutForm.resx new file mode 100644 index 00000000..ff31a6db --- /dev/null +++ b/MixDiff/AboutForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MixDiff/Images.Designer.cs b/MixDiff/Images.Designer.cs new file mode 100644 index 00000000..8be93219 --- /dev/null +++ b/MixDiff/Images.Designer.cs @@ -0,0 +1,143 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MarkHeath.AudioUtils { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Images { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Images() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MarkHeath.AudioUtils.Images", typeof(Images).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Back { + get { + object obj = ResourceManager.GetObject("Back", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Forward { + get { + object obj = ResourceManager.GetObject("Forward", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Loop { + get { + object obj = ResourceManager.GetObject("Loop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Pause { + get { + object obj = ResourceManager.GetObject("Pause", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Play { + get { + object obj = ResourceManager.GetObject("Play", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Rewind { + get { + object obj = ResourceManager.GetObject("Rewind", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Shuffle { + get { + object obj = ResourceManager.GetObject("Shuffle", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Stop { + get { + object obj = ResourceManager.GetObject("Stop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/MixDiff/Images.resx b/MixDiff/Images.resx new file mode 100644 index 00000000..7e225022 --- /dev/null +++ b/MixDiff/Images.resx @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Resources\Back.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Forward.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Loop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Pause.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Play.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Rewind.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Shuffle.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Resources\Stop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/MixDiff/MixDiff.csproj b/MixDiff/MixDiff.csproj new file mode 100644 index 00000000..71a099b0 --- /dev/null +++ b/MixDiff/MixDiff.csproj @@ -0,0 +1,202 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {1293DD10-378A-4370-AEE2-AA1E9E87039B} + WinExe + Properties + MarkHeath.AudioUtils + MixDiff + + + + + + + + + + + + + 3.5 + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + Client + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + + + + + + + + Form + + + AboutForm.cs + + + + True + True + Images.resx + + + Form + + + MixDiffForm.cs + + + + + Form + + + PropertiesForm.cs + + + + AboutForm.cs + Designer + + + Designer + ResXFileCodeGenerator + Images.Designer.cs + + + Designer + MixDiffForm.cs + + + Designer + PropertiesForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + Designer + SettingsForm.cs + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + Form + + + SettingsForm.cs + + + + + + + + + + + + + + + + + + + + + + + + + + {DA4F02E3-0B5E-42CD-B8D9-5583FA51D66E} + NAudio + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/MixDiff/MixDiff.csproj.vspscc b/MixDiff/MixDiff.csproj.vspscc new file mode 100644 index 00000000..979cc996 --- /dev/null +++ b/MixDiff/MixDiff.csproj.vspscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "relative:MixDiff" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" +} diff --git a/MixDiff/MixDiffForm.Designer.cs b/MixDiff/MixDiffForm.Designer.cs new file mode 100644 index 00000000..266d8373 --- /dev/null +++ b/MixDiff/MixDiffForm.Designer.cs @@ -0,0 +1,491 @@ +namespace MarkHeath.AudioUtils +{ + partial class MixDiffForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButtonPlay = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonPause = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonStop = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonBack = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonForward = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonRewind = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonLoop = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonShuffle = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel(); + this.toolStripLabelPosition = new System.Windows.Forms.ToolStripLabel(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel(); + this.toolStripLabelLength = new System.Windows.Forms.ToolStripLabel(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.buttonA = new System.Windows.Forms.Button(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.selectFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.buttonB = new System.Windows.Forms.Button(); + this.buttonC = new System.Windows.Forms.Button(); + this.buttonD = new System.Windows.Forms.Button(); + this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openSavedComparisonToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveComparisonToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.compareModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.currentPositionToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.skipBackToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.restartToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1.SuspendLayout(); + this.contextMenuStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButtonPlay, + this.toolStripButtonPause, + this.toolStripButtonStop, + this.toolStripButtonBack, + this.toolStripButtonForward, + this.toolStripButtonRewind, + this.toolStripButtonLoop, + this.toolStripButtonShuffle, + this.toolStripSeparator1, + this.toolStripLabel1, + this.toolStripLabelPosition, + this.toolStripSeparator2, + this.toolStripLabel2, + this.toolStripLabelLength, + this.toolStripSeparator3}); + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(642, 25); + this.toolStrip1.TabIndex = 7; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButtonPlay + // + this.toolStripButtonPlay.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonPlay.Image = global::MarkHeath.AudioUtils.Images.Play; + this.toolStripButtonPlay.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonPlay.Name = "toolStripButtonPlay"; + this.toolStripButtonPlay.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonPlay.Text = "Play"; + this.toolStripButtonPlay.Click += new System.EventHandler(this.toolStripButtonPlay_Click); + // + // toolStripButtonPause + // + this.toolStripButtonPause.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonPause.Image = global::MarkHeath.AudioUtils.Images.Pause; + this.toolStripButtonPause.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonPause.Name = "toolStripButtonPause"; + this.toolStripButtonPause.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonPause.Text = "Pause"; + this.toolStripButtonPause.Click += new System.EventHandler(this.toolStripButtonPause_Click); + // + // toolStripButtonStop + // + this.toolStripButtonStop.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonStop.Image = global::MarkHeath.AudioUtils.Images.Stop; + this.toolStripButtonStop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonStop.Name = "toolStripButtonStop"; + this.toolStripButtonStop.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonStop.Text = "Stop"; + this.toolStripButtonStop.Click += new System.EventHandler(this.toolStripButtonStop_Click); + // + // toolStripButtonBack + // + this.toolStripButtonBack.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonBack.Image = global::MarkHeath.AudioUtils.Images.Back; + this.toolStripButtonBack.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonBack.Name = "toolStripButtonBack"; + this.toolStripButtonBack.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonBack.Text = "Skip Back"; + this.toolStripButtonBack.Click += new System.EventHandler(this.toolStripButtonBack_Click); + // + // toolStripButtonForward + // + this.toolStripButtonForward.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonForward.Image = global::MarkHeath.AudioUtils.Images.Forward; + this.toolStripButtonForward.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonForward.Name = "toolStripButtonForward"; + this.toolStripButtonForward.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonForward.Text = "Skip Forward"; + this.toolStripButtonForward.Click += new System.EventHandler(this.toolStripButtonForward_Click); + // + // toolStripButtonRewind + // + this.toolStripButtonRewind.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonRewind.Image = global::MarkHeath.AudioUtils.Images.Rewind; + this.toolStripButtonRewind.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonRewind.Name = "toolStripButtonRewind"; + this.toolStripButtonRewind.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonRewind.Text = "Rewind"; + this.toolStripButtonRewind.Click += new System.EventHandler(this.toolStripButtonRewind_Click); + // + // toolStripButtonLoop + // + this.toolStripButtonLoop.CheckOnClick = true; + this.toolStripButtonLoop.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonLoop.Image = global::MarkHeath.AudioUtils.Images.Loop; + this.toolStripButtonLoop.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonLoop.Name = "toolStripButtonLoop"; + this.toolStripButtonLoop.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonLoop.Text = "Loop"; + // + // toolStripButtonShuffle + // + this.toolStripButtonShuffle.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonShuffle.Image = global::MarkHeath.AudioUtils.Images.Shuffle; + this.toolStripButtonShuffle.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonShuffle.Name = "toolStripButtonShuffle"; + this.toolStripButtonShuffle.Size = new System.Drawing.Size(23, 22); + this.toolStripButtonShuffle.Text = "Shuffle"; + this.toolStripButtonShuffle.Click += new System.EventHandler(this.toolStripButtonShuffle_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStripLabel1 + // + this.toolStripLabel1.Name = "toolStripLabel1"; + this.toolStripLabel1.Size = new System.Drawing.Size(53, 22); + this.toolStripLabel1.Text = "Position:"; + // + // toolStripLabelPosition + // + this.toolStripLabelPosition.Name = "toolStripLabelPosition"; + this.toolStripLabelPosition.Size = new System.Drawing.Size(70, 22); + this.toolStripLabelPosition.Text = "00:00:00.000"; + this.toolStripLabelPosition.ToolTipText = "Position"; + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolStripLabel2 + // + this.toolStripLabel2.Name = "toolStripLabel2"; + this.toolStripLabel2.Size = new System.Drawing.Size(47, 22); + this.toolStripLabel2.Text = "Length:"; + // + // toolStripLabelLength + // + this.toolStripLabelLength.Name = "toolStripLabelLength"; + this.toolStripLabelLength.Size = new System.Drawing.Size(49, 22); + this.toolStripLabelLength.Text = "00:00:00"; + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // buttonA + // + this.buttonA.ContextMenuStrip = this.contextMenuStrip1; + this.buttonA.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonA.Location = new System.Drawing.Point(12, 62); + this.buttonA.Name = "buttonA"; + this.buttonA.Size = new System.Drawing.Size(150, 150); + this.buttonA.TabIndex = 8; + this.buttonA.Text = ""; + this.buttonA.UseVisualStyleBackColor = true; + this.buttonA.Click += new System.EventHandler(this.OnMixButtonClick); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.selectFileToolStripMenuItem, + this.clearToolStripMenuItem, + this.propertiesToolStripMenuItem}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(137, 70); + // + // selectFileToolStripMenuItem + // + this.selectFileToolStripMenuItem.Name = "selectFileToolStripMenuItem"; + this.selectFileToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.selectFileToolStripMenuItem.Text = "&Select File..."; + this.selectFileToolStripMenuItem.Click += new System.EventHandler(this.selectFileToolStripMenuItem_Click); + // + // clearToolStripMenuItem + // + this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; + this.clearToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.clearToolStripMenuItem.Text = "&Clear"; + this.clearToolStripMenuItem.Click += new System.EventHandler(this.clearToolStripMenuItem_Click); + // + // propertiesToolStripMenuItem + // + this.propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem"; + this.propertiesToolStripMenuItem.Size = new System.Drawing.Size(136, 22); + this.propertiesToolStripMenuItem.Text = "&Properties..."; + this.propertiesToolStripMenuItem.Click += new System.EventHandler(this.propertiesToolStripMenuItem_Click); + // + // buttonB + // + this.buttonB.ContextMenuStrip = this.contextMenuStrip1; + this.buttonB.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonB.Location = new System.Drawing.Point(168, 62); + this.buttonB.Name = "buttonB"; + this.buttonB.Size = new System.Drawing.Size(150, 150); + this.buttonB.TabIndex = 9; + this.buttonB.Text = ""; + this.buttonB.UseVisualStyleBackColor = true; + this.buttonB.Click += new System.EventHandler(this.OnMixButtonClick); + // + // buttonC + // + this.buttonC.ContextMenuStrip = this.contextMenuStrip1; + this.buttonC.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonC.Location = new System.Drawing.Point(324, 62); + this.buttonC.Name = "buttonC"; + this.buttonC.Size = new System.Drawing.Size(150, 150); + this.buttonC.TabIndex = 10; + this.buttonC.Text = ""; + this.buttonC.UseVisualStyleBackColor = true; + this.buttonC.Click += new System.EventHandler(this.OnMixButtonClick); + // + // buttonD + // + this.buttonD.ContextMenuStrip = this.contextMenuStrip1; + this.buttonD.Font = new System.Drawing.Font("Verdana", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.buttonD.Location = new System.Drawing.Point(480, 62); + this.buttonD.Name = "buttonD"; + this.buttonD.Size = new System.Drawing.Size(150, 150); + this.buttonD.TabIndex = 11; + this.buttonD.Text = ""; + this.buttonD.UseVisualStyleBackColor = true; + this.buttonD.Click += new System.EventHandler(this.OnMixButtonClick); + // + // timer1 + // + this.timer1.Interval = 200; + this.timer1.Tick += new System.EventHandler(this.timer1_Tick); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.optionsToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(642, 24); + this.menuStrip1.TabIndex = 11; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openSavedComparisonToolStripMenuItem, + this.saveComparisonToolStripMenuItem, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openSavedComparisonToolStripMenuItem + // + this.openSavedComparisonToolStripMenuItem.Name = "openSavedComparisonToolStripMenuItem"; + this.openSavedComparisonToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.openSavedComparisonToolStripMenuItem.Text = "Open Comparison..."; + this.openSavedComparisonToolStripMenuItem.Click += new System.EventHandler(this.openSavedComparisonToolStripMenuItem_Click); + // + // saveComparisonToolStripMenuItem + // + this.saveComparisonToolStripMenuItem.Name = "saveComparisonToolStripMenuItem"; + this.saveComparisonToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.saveComparisonToolStripMenuItem.Text = "Save Comparison..."; + this.saveComparisonToolStripMenuItem.Click += new System.EventHandler(this.saveComparisonToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.compareModeToolStripMenuItem, + this.settingsToolStripMenuItem}); + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); + this.optionsToolStripMenuItem.Text = "&Options"; + // + // compareModeToolStripMenuItem + // + this.compareModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.currentPositionToolStripMenuItem1, + this.skipBackToolStripMenuItem1, + this.restartToolStripMenuItem1}); + this.compareModeToolStripMenuItem.Name = "compareModeToolStripMenuItem"; + this.compareModeToolStripMenuItem.Size = new System.Drawing.Size(157, 22); + this.compareModeToolStripMenuItem.Text = "&Compare Mode"; + // + // currentPositionToolStripMenuItem1 + // + this.currentPositionToolStripMenuItem1.Checked = true; + this.currentPositionToolStripMenuItem1.CheckState = System.Windows.Forms.CheckState.Checked; + this.currentPositionToolStripMenuItem1.Name = "currentPositionToolStripMenuItem1"; + this.currentPositionToolStripMenuItem1.Size = new System.Drawing.Size(160, 22); + this.currentPositionToolStripMenuItem1.Text = "&Current Position"; + this.currentPositionToolStripMenuItem1.Click += new System.EventHandler(this.currentPositionToolStripMenuItem1_Click); + // + // skipBackToolStripMenuItem1 + // + this.skipBackToolStripMenuItem1.Name = "skipBackToolStripMenuItem1"; + this.skipBackToolStripMenuItem1.Size = new System.Drawing.Size(160, 22); + this.skipBackToolStripMenuItem1.Text = "&Skip Back"; + this.skipBackToolStripMenuItem1.Click += new System.EventHandler(this.skipBackToolStripMenuItem1_Click); + // + // restartToolStripMenuItem1 + // + this.restartToolStripMenuItem1.Name = "restartToolStripMenuItem1"; + this.restartToolStripMenuItem1.Size = new System.Drawing.Size(160, 22); + this.restartToolStripMenuItem1.Text = "&Restart"; + this.restartToolStripMenuItem1.Click += new System.EventHandler(this.restartToolStripMenuItem1_Click); + // + // settingsToolStripMenuItem + // + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(157, 22); + this.settingsToolStripMenuItem.Text = "&Settings..."; + this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.contentsToolStripMenuItem, + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // contentsToolStripMenuItem + // + this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; + this.contentsToolStripMenuItem.Size = new System.Drawing.Size(122, 22); + this.contentsToolStripMenuItem.Text = "&Contents"; + this.contentsToolStripMenuItem.Click += new System.EventHandler(this.contentsToolStripMenuItem_Click); + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(122, 22); + this.aboutToolStripMenuItem.Text = "&About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // MixDiffForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(642, 296); + this.Controls.Add(this.buttonD); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.buttonC); + this.Controls.Add(this.buttonB); + this.Controls.Add(this.buttonA); + this.Controls.Add(this.menuStrip1); + this.KeyPreview = true; + this.MainMenuStrip = this.menuStrip1; + this.Name = "MixDiffForm"; + this.Text = "MixDiff"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MixDiffForm_FormClosing); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MixDiffForm_KeyDown); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.contextMenuStrip1.ResumeLayout(false); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButtonPlay; + private System.Windows.Forms.ToolStripButton toolStripButtonPause; + private System.Windows.Forms.ToolStripButton toolStripButtonStop; + private System.Windows.Forms.ToolStripButton toolStripButtonBack; + private System.Windows.Forms.ToolStripButton toolStripButtonForward; + private System.Windows.Forms.ToolStripButton toolStripButtonRewind; + private System.Windows.Forms.ToolStripButton toolStripButtonLoop; + private System.Windows.Forms.Button buttonA; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripLabel toolStripLabelPosition; + private System.Windows.Forms.Button buttonB; + private System.Windows.Forms.Button buttonC; + private System.Windows.Forms.Button buttonD; + private System.Windows.Forms.ToolTip toolTip1; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem; + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.ToolStripLabel toolStripLabel1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openSavedComparisonToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveComparisonToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem compareModeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem currentPositionToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem skipBackToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem restartToolStripMenuItem1; + private System.Windows.Forms.ToolStripLabel toolStripLabel2; + private System.Windows.Forms.ToolStripLabel toolStripLabelLength; + private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem selectFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem propertiesToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButtonShuffle; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + + } +} + diff --git a/MixDiff/MixDiffForm.cs b/MixDiff/MixDiffForm.cs new file mode 100644 index 00000000..b4847bf7 --- /dev/null +++ b/MixDiff/MixDiffForm.cs @@ -0,0 +1,612 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Xml; +using NAudio.Wave; +using MarkHeath.AudioUtils.Properties; + +namespace MarkHeath.AudioUtils +{ + public partial class MixDiffForm : Form + { + private PlaybackStatus playbackStatus; + private IWavePlayer wavePlayer; + readonly Font BigFont = new Font("Verdana", 36, FontStyle.Bold); + readonly Font EmptyFont = new Font("Verdana", 16, FontStyle.Bold); + private WaveMixerStream32 mixer; + private int skipSeconds; + private Button selectedButton; + private CompareMode compareMode; + private List + + + + + + diff --git a/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml.cs b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml.cs new file mode 100644 index 00000000..9cda2c3b --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackDemoView.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace NAudioWpfDemo +{ + /// + /// Interaction logic for AudioPlaybackDemo.xaml + /// + public partial class AudioPlaybackDemoView : UserControl + { + public AudioPlaybackDemoView() + { + InitializeComponent(); + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackViewModel.cs b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackViewModel.cs new file mode 100644 index 00000000..1a8566f7 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/AudioPlaybackViewModel.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Windows.Input; +using Microsoft.Win32; +using System.Windows; +using NAudio.Wave; +using NAudioWpfDemo.AudioPlaybackDemo; +using NAudioWpfDemo.ViewModel; + +namespace NAudioWpfDemo +{ + class AudioPlaybackViewModel : ViewModelBase, IDisposable + { + private AudioPlayback audioPlayback; + private List visualizations; + private IVisualizationPlugin selectedVisualization; + private string selectedFile; + + public ICommand OpenFileCommand { get; private set; } + public ICommand PlayCommand { get; private set; } + public ICommand PauseCommand { get; private set; } + public ICommand StopCommand { get; private set; } + + public AudioPlaybackViewModel(IEnumerable visualizations) + { + this.visualizations = new List(visualizations); + this.selectedVisualization = this.visualizations.FirstOrDefault(); + + this.audioPlayback = new AudioPlayback(); + audioPlayback.MaximumCalculated += audioGraph_MaximumCalculated; + audioPlayback.FftCalculated += audioGraph_FftCalculated; + + PlayCommand = new DelegateCommand(Play); + OpenFileCommand = new DelegateCommand(OpenFile); + StopCommand = new DelegateCommand(Stop); + PauseCommand = new DelegateCommand(Pause); + } + + private void Pause() + { + audioPlayback.Pause(); + } + + public IList Visualizations { get { return this.visualizations; } } + + public IVisualizationPlugin SelectedVisualization + { + get + { + return this.selectedVisualization; + } + set + { + if (this.selectedVisualization != value) + { + this.selectedVisualization = value; + OnPropertyChanged("SelectedVisualization"); + OnPropertyChanged("Visualization"); + } + } + } + + public object Visualization + { + get + { + return this.selectedVisualization.Content; + } + } + + void audioGraph_FftCalculated(object sender, FftEventArgs e) + { + if (this.SelectedVisualization != null) + { + this.SelectedVisualization.OnFftCalculated(e.Result); + } + } + + void audioGraph_MaximumCalculated(object sender, MaxSampleEventArgs e) + { + if (this.SelectedVisualization != null) + { + this.SelectedVisualization.OnMaxCalculated(e.MinSample, e.MaxSample); + } + } + + private void OpenFile() + { + OpenFileDialog openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "All Supported Files (*.wav;*.mp3)|*.wav;*.mp3|All Files (*.*)|*.*"; + bool? result = openFileDialog.ShowDialog(); + if (result.HasValue && result.Value) + { + this.selectedFile = openFileDialog.FileName; + audioPlayback.Load(this.selectedFile); + } + } + + private void Play() + { + if (this.selectedFile == null) + { + OpenFile(); + } + if (this.selectedFile != null) + { + audioPlayback.Play(); + } + } + + private void Stop() + { + audioPlayback.Stop(); + } + + public void Dispose() + { + audioPlayback.Dispose(); + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/IVisualizationPlugin.cs b/NAudioWpfDemo/AudioPlaybackDemo/IVisualizationPlugin.cs new file mode 100644 index 00000000..0f0139b5 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/IVisualizationPlugin.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NAudio.Dsp; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + interface IVisualizationPlugin + { + string Name { get; } + object Content { get; } + + // n.b. not great design, need to refactor so visualizations can attach to the playback graph and measure just what they need + void OnMaxCalculated(float min, float max); + void OnFftCalculated(Complex[] result); + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/PolygonWaveFormVisualization.cs b/NAudioWpfDemo/AudioPlaybackDemo/PolygonWaveFormVisualization.cs new file mode 100644 index 00000000..1fcf962c --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/PolygonWaveFormVisualization.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + [Export(typeof(IVisualizationPlugin))] + class PolygonWaveFormVisualization : IVisualizationPlugin + { + private PolygonWaveFormControl polygonWaveFormControl = new PolygonWaveFormControl(); + + public string Name + { + get { return "Polygon WaveForm Visualization"; } + } + + public object Content + { + get { return polygonWaveFormControl; } + } + + + public void OnMaxCalculated(float min, float max) + { + polygonWaveFormControl.AddValue(max, min); + } + + public void OnFftCalculated(NAudio.Dsp.Complex[] result) + { + // nothing to do + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/PolylineWaveFormVisualization.cs b/NAudioWpfDemo/AudioPlaybackDemo/PolylineWaveFormVisualization.cs new file mode 100644 index 00000000..87946fc9 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/PolylineWaveFormVisualization.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + [Export(typeof(IVisualizationPlugin))] + class PolylineWaveFormVisualization : IVisualizationPlugin + { + private PolylineWaveFormControl polylineWaveFormControl = new PolylineWaveFormControl(); + + public string Name + { + get { return "Polyline WaveForm Visualization"; } + } + + public object Content + { + get { return polylineWaveFormControl; } + } + + public void OnMaxCalculated(float min, float max) + { + polylineWaveFormControl.AddValue(max, min); + } + + public void OnFftCalculated(NAudio.Dsp.Complex[] result) + { + // nothing to do + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/SampleAggregator.cs b/NAudioWpfDemo/AudioPlaybackDemo/SampleAggregator.cs new file mode 100644 index 00000000..e943fb69 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/SampleAggregator.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using NAudio.Dsp; +using NAudio.Wave; + +namespace NAudioWpfDemo +{ + public class SampleAggregator : ISampleProvider + { + // volume + public event EventHandler MaximumCalculated; + private float maxValue; + private float minValue; + public int NotificationCount { get; set; } + int count; + + // FFT + public event EventHandler FftCalculated; + public bool PerformFFT { get; set; } + private readonly Complex[] fftBuffer; + private readonly FftEventArgs fftArgs; + private int fftPos; + private readonly int fftLength; + private int m; + private readonly ISampleProvider source; + + private readonly int channels; + + public SampleAggregator(ISampleProvider source, int fftLength = 1024) + { + channels = source.WaveFormat.Channels; + if (!IsPowerOfTwo(fftLength)) + { + throw new ArgumentException("FFT Length must be a power of two"); + } + this.m = (int)Math.Log(fftLength, 2.0); + this.fftLength = fftLength; + this.fftBuffer = new Complex[fftLength]; + this.fftArgs = new FftEventArgs(fftBuffer); + this.source = source; + } + + bool IsPowerOfTwo(int x) + { + return (x & (x - 1)) == 0; + } + + + public void Reset() + { + count = 0; + maxValue = minValue = 0; + } + + private void Add(float value) + { + if (PerformFFT && FftCalculated != null) + { + fftBuffer[fftPos].X = (float)(value * FastFourierTransform.HammingWindow(fftPos, fftLength)); + fftBuffer[fftPos].Y = 0; + fftPos++; + if (fftPos >= fftBuffer.Length) + { + fftPos = 0; + // 1024 = 2^10 + FastFourierTransform.FFT(true, m, fftBuffer); + FftCalculated(this, fftArgs); + } + } + + maxValue = Math.Max(maxValue, value); + minValue = Math.Min(minValue, value); + count++; + if (count >= NotificationCount && NotificationCount > 0) + { + if (MaximumCalculated != null) + { + MaximumCalculated(this, new MaxSampleEventArgs(minValue, maxValue)); + } + Reset(); + } + } + + public WaveFormat WaveFormat { get { return source.WaveFormat; } } + + public int Read(float[] buffer, int offset, int count) + { + var samplesRead = source.Read(buffer, offset, count); + + for (int n = 0; n < samplesRead; n+=channels) + { + Add(buffer[n+offset]); + } + return samplesRead; + } + } + + public class MaxSampleEventArgs : EventArgs + { + [DebuggerStepThrough] + public MaxSampleEventArgs(float minValue, float maxValue) + { + this.MaxSample = maxValue; + this.MinSample = minValue; + } + public float MaxSample { get; private set; } + public float MinSample { get; private set; } + } + + public class FftEventArgs : EventArgs + { + [DebuggerStepThrough] + public FftEventArgs(Complex[] result) + { + this.Result = result; + } + public Complex[] Result { get; private set; } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/SpectrumAnalyzerVisualization.cs b/NAudioWpfDemo/AudioPlaybackDemo/SpectrumAnalyzerVisualization.cs new file mode 100644 index 00000000..6fdc7a88 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/SpectrumAnalyzerVisualization.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.AudioPlaybackDemo +{ + [Export(typeof(IVisualizationPlugin))] + class SpectrumAnalyzerVisualization : IVisualizationPlugin + { + private SpectrumAnalyser spectrumAnalyser = new SpectrumAnalyser(); + + public string Name + { + get { return "Spectrum Analyser"; } + } + + public object Content + { + get { return spectrumAnalyser; } + } + + + public void OnMaxCalculated(float min, float max) + { + // nothing to do + } + + public void OnFftCalculated(NAudio.Dsp.Complex[] result) + { + spectrumAnalyser.Update(result); + } + } +} diff --git a/NAudioWpfDemo/AudioPlaybackDemo/WaveformVisual.cs b/NAudioWpfDemo/AudioPlaybackDemo/WaveformVisual.cs new file mode 100644 index 00000000..b07ccd23 --- /dev/null +++ b/NAudioWpfDemo/AudioPlaybackDemo/WaveformVisual.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; +using System.Windows; + +namespace NAudioWpfDemo +{ + class WaveFormVisual : FrameworkElement, IWaveFormRenderer + { + // Create a collection of child visual objects. + private VisualCollection _children; + private List maxPoints; + private List minPoints; + double yTranslate = 40; + double yScale = 40; + + public WaveFormVisual() + { + maxPoints = new List(); + minPoints = new List(); + _children = new VisualCollection(this); + _children.Add(CreateWaveFormVisual()); + } + + private DrawingVisual CreateWaveFormVisual() + { + DrawingVisual drawingVisual = new DrawingVisual(); + + // Retrieve the DrawingContext in order to create new drawing content. + DrawingContext drawingContext = drawingVisual.RenderOpen(); + if (maxPoints.Count > 0) + { + RenderPolygon(drawingContext); + } + + //drawingContext.DrawGeometry + // Create a rectangle and draw it in the DrawingContext. + //Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80)); + //drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect); + + // Persist the drawing content. + drawingContext.Close(); + + return drawingVisual; + } + + private void RenderPolygon(DrawingContext drawingContext) + { + var fillBrush = Brushes.LawnGreen; + var borderPen = new Pen(Brushes.Black,1.0); + + PathFigure myPathFigure = new PathFigure(); + myPathFigure.StartPoint = maxPoints[0]; + + //PolyLineSegment seg = new PolyLineSegment( + + PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection(); + + for (int i = 1; i < maxPoints.Count; i++) + { + myPathSegmentCollection.Add(new LineSegment(maxPoints[i], true)); + } + for (int i = minPoints.Count - 1; i >= 0; i--) + { + myPathSegmentCollection.Add(new LineSegment(minPoints[i], true)); + } + + myPathFigure.Segments = myPathSegmentCollection; + PathGeometry myPathGeometry = new PathGeometry(); + + myPathGeometry.Figures.Add(myPathFigure); + + drawingContext.DrawGeometry(fillBrush, borderPen, myPathGeometry); + } + + // Provide a required override for the VisualChildrenCount property. + protected override int VisualChildrenCount + { + get { return _children.Count; } + } + + // Provide a required override for the GetVisualChild method. + protected override Visual GetVisualChild(int index) + { + if (index < 0 || index >= _children.Count) + { + throw new ArgumentOutOfRangeException(); + } + + return _children[index]; + } + + + #region IWaveFormRenderer Members + + public void AddValue(float maxValue, float minValue) + { + int xpos = maxPoints.Count; + maxPoints.Add(new Point(xpos, SampleToYPosition(minValue))); + minPoints.Add(new Point(xpos, SampleToYPosition(maxValue))); + _children.Clear(); + + _children.Add(CreateWaveFormVisual()); + this.InvalidateVisual(); + } + private double SampleToYPosition(float value) + { + return yTranslate + value * yScale; + } + #endregion + } +} diff --git a/NAudioWpfDemo/DrumMachineDemo/DrumKit.cs b/NAudioWpfDemo/DrumMachineDemo/DrumKit.cs new file mode 100644 index 00000000..d417d5dc --- /dev/null +++ b/NAudioWpfDemo/DrumMachineDemo/DrumKit.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NAudio.Wave; +using NAudio.Wave.SampleProviders; + +namespace NAudioWpfDemo.DrumMachineDemo +{ + class DrumKit + { + private List sampleSources; + private WaveFormat waveFormat; + + public DrumKit() + { + SampleSource kickSample = SampleSource.CreateFromWaveFile("Samples\\kick-trimmed.wav"); + SampleSource snareSample = SampleSource.CreateFromWaveFile("Samples\\snare-trimmed.wav"); + SampleSource closedHatsSample = SampleSource.CreateFromWaveFile("Samples\\closed-hat-trimmed.wav"); + SampleSource openHatsSample = SampleSource.CreateFromWaveFile("Samples\\open-hat-trimmed.wav"); + sampleSources = new List(); + + sampleSources.Add(kickSample); + sampleSources.Add(snareSample); + sampleSources.Add(closedHatsSample); + sampleSources.Add(openHatsSample); + this.waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(openHatsSample.SampleWaveFormat.SampleRate, openHatsSample.SampleWaveFormat.Channels); + } + + public virtual WaveFormat WaveFormat + { + get { return waveFormat; } + } + + public MusicSampleProvider GetSampleProvider(int note) + { + return new MusicSampleProvider(this.sampleSources[note]); + } + } +} diff --git a/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoPlugin.cs b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoPlugin.cs new file mode 100644 index 00000000..754ed621 --- /dev/null +++ b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoPlugin.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel.Composition; + +namespace NAudioWpfDemo.DrumMachineDemo +{ + [Export(typeof(IModule))] + class DrumMachineDemoPlugin : IModule + { + private DrumMachineDemoView view; + private DrumMachineDemoViewModel viewModel; + public string Name + { + get { return "Drum Machine"; } + } + + public System.Windows.Controls.UserControl UserInterface + { + get + { + if (view == null) + { + view = new DrumMachineDemoView(); + viewModel = new DrumMachineDemoViewModel(view.drumPatternEditor1.DrumPattern); + view.DataContext = viewModel; + } + return view; + } + } + + public void Deactivate() + { + if (view != null) + { + viewModel.Dispose(); + view = null; + viewModel = null; + } + } + } +} diff --git a/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml new file mode 100644 index 00000000..77169ad1 --- /dev/null +++ b/NAudioWpfDemo/DrumMachineDemo/DrumMachineDemoView.xaml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml.cs b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml.cs new file mode 100644 index 00000000..32405ada --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoView.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Linq; +using System.Windows.Controls; + +namespace NAudioWpfDemo.EqualizationDemo +{ + /// + /// Interaction logic for AudioPlaybackDemo.xaml + /// + public partial class EqualizationDemoView : UserControl + { + public EqualizationDemoView() + { + InitializeComponent(); + } + } +} diff --git a/NAudioWpfDemo/EqualizationDemo/EqualizationDemoViewModel.cs b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoViewModel.cs new file mode 100644 index 00000000..0f558a6b --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/EqualizationDemoViewModel.cs @@ -0,0 +1,220 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Windows.Input; +using Microsoft.Win32; +using NAudio.Wave; +using NAudioWpfDemo.ViewModel; + +namespace NAudioWpfDemo.EqualizationDemo +{ + class EqualizationDemoViewModel : ViewModelBase, IDisposable + { + private AudioFileReader reader; + private IWavePlayer player; + private Equalizer equalizer; + private string selectedFile; + private readonly EqualizerBand[] bands; + + public ICommand OpenFileCommand { get; private set; } + public ICommand PlayCommand { get; private set; } + public ICommand PauseCommand { get; private set; } + public ICommand StopCommand { get; private set; } + + public EqualizationDemoViewModel() + { + PlayCommand = new DelegateCommand(Play); + OpenFileCommand = new DelegateCommand(OpenFile); + StopCommand = new DelegateCommand(Stop); + PauseCommand = new DelegateCommand(Pause); + bands = new EqualizerBand[] + { + new EqualizerBand {Bandwidth = 0.8f, Frequency = 100, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 200, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 400, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 800, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 1200, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 2400, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 4800, Gain = 0}, + new EqualizerBand {Bandwidth = 0.8f, Frequency = 9600, Gain = 0}, + }; + this.PropertyChanged += OnPropertyChanged; + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) + { + if (equalizer!=null) equalizer.Update(); + } + + public float MinimumGain + { + get { return -30; } + } + + public float MaximumGain + { + get { return 30; } + } + + public float Band1 + { + get { return bands[0].Gain; } + set + { + if (bands[0].Gain != value) + { + bands[0].Gain = value; + OnPropertyChanged("Band1"); + } + } + } + + public float Band2 + { + get { return bands[1].Gain; } + set + { + if (bands[1].Gain != value) + { + bands[1].Gain = value; + OnPropertyChanged("Band2"); + } + } + } + + public float Band3 + { + get { return bands[2].Gain; } + set + { + if (bands[2].Gain != value) + { + bands[2].Gain = value; + OnPropertyChanged("Band3"); + } + } + } + + public float Band4 + { + get { return bands[3].Gain; } + set + { + if (bands[3].Gain != value) + { + bands[3].Gain = value; + OnPropertyChanged("Band4"); + } + } + } + + public float Band5 + { + get { return bands[4].Gain; } + set + { + if (bands[4].Gain != value) + { + bands[4].Gain = value; + OnPropertyChanged("Band5"); + } + } + } + + public float Band6 + { + get { return bands[5].Gain; } + set + { + if (bands[5].Gain != value) + { + bands[5].Gain = value; + OnPropertyChanged("Band6"); + } + } + } + + + public float Band7 + { + get { return bands[6].Gain; } + set + { + if (bands[6].Gain != value) + { + bands[6].Gain = value; + OnPropertyChanged("Band7"); + } + } + } + + public float Band8 + { + get { return bands[7].Gain; } + set + { + if (bands[7].Gain != value) + { + bands[7].Gain = value; + OnPropertyChanged("Band7"); + } + } + } + + private void Pause() + { + if (player != null) + { + player.Pause(); + } + } + + private void OpenFile() + { + var openFileDialog = new OpenFileDialog(); + openFileDialog.Filter = "All Supported Files (*.wav;*.mp3)|*.wav;*.mp3|All Files (*.*)|*.*"; + bool? result = openFileDialog.ShowDialog(); + if (result.HasValue && result.Value) + { + selectedFile = openFileDialog.FileName; + reader = new AudioFileReader(selectedFile); + equalizer = new Equalizer(reader, bands); + player = new WaveOutEvent(); + player.Init(equalizer); + } + } + + private void Play() + { + if (selectedFile == null) + { + OpenFile(); + } + if (selectedFile != null) + { + player.Play(); + } + } + + private void Stop() + { + if (player != null) + { + player.Stop(); + } + } + + public void Dispose() + { + if (player != null) + { + player.Dispose(); + } + if (reader != null) + { + reader.Dispose(); + } + + } + } +} diff --git a/NAudioWpfDemo/EqualizationDemo/Equalizer.cs b/NAudioWpfDemo/EqualizationDemo/Equalizer.cs new file mode 100644 index 00000000..8b9c185e --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/Equalizer.cs @@ -0,0 +1,76 @@ +using NAudio.Dsp; +using NAudio.Wave; + +namespace NAudioWpfDemo.EqualizationDemo +{ + /// + /// Basic example of a multi-band eq + /// uses the same settings for both channels in stereo audio + /// Call Update after you've updated the bands + /// Potentially to be added to NAudio in a future version + /// + class Equalizer : ISampleProvider + { + private readonly ISampleProvider sourceProvider; + private readonly EqualizerBand[] bands; + private readonly BiQuadFilter[,] filters; + private readonly int channels; + private readonly int bandCount; + private bool updated; + + public Equalizer(ISampleProvider sourceProvider, EqualizerBand[] bands) + { + this.sourceProvider = sourceProvider; + this.bands = bands; + channels = sourceProvider.WaveFormat.Channels; + bandCount = bands.Length; + filters = new BiQuadFilter[channels,bands.Length]; + CreateFilters(); + } + + private void CreateFilters() + { + for (int bandIndex = 0; bandIndex < bandCount; bandIndex++) + { + var band = bands[bandIndex]; + for (int n = 0; n < channels; n++) + { + if (filters[n, bandIndex] == null) + filters[n, bandIndex] = BiQuadFilter.PeakingEQ(sourceProvider.WaveFormat.SampleRate, band.Frequency, band.Bandwidth, band.Gain); + else + filters[n, bandIndex].SetPeakingEq(sourceProvider.WaveFormat.SampleRate, band.Frequency, band.Bandwidth, band.Gain); + } + } + } + + public void Update() + { + updated = true; + CreateFilters(); + } + + public WaveFormat WaveFormat { get { return sourceProvider.WaveFormat; } } + + public int Read(float[] buffer, int offset, int count) + { + int samplesRead = sourceProvider.Read(buffer, offset, count); + + if (updated) + { + CreateFilters(); + updated = false; + } + + for (int n = 0; n < samplesRead; n++) + { + int ch = n % channels; + + for (int band = 0; band < bandCount; band++) + { + buffer[offset + n] = filters[ch, band].Transform(buffer[offset + n]); + } + } + return samplesRead; + } + } +} \ No newline at end of file diff --git a/NAudioWpfDemo/EqualizationDemo/EqualizerBand.cs b/NAudioWpfDemo/EqualizationDemo/EqualizerBand.cs new file mode 100644 index 00000000..3c3584f6 --- /dev/null +++ b/NAudioWpfDemo/EqualizationDemo/EqualizerBand.cs @@ -0,0 +1,9 @@ +namespace NAudioWpfDemo.EqualizationDemo +{ + class EqualizerBand + { + public float Frequency { get; set; } + public float Gain { get; set; } + public float Bandwidth { get; set; } + } +} \ No newline at end of file diff --git a/NAudioWpfDemo/IModule.cs b/NAudioWpfDemo/IModule.cs new file mode 100644 index 00000000..4a0adc47 --- /dev/null +++ b/NAudioWpfDemo/IModule.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls; + +namespace NAudioWpfDemo +{ + public interface IModule + { + string Name { get; } + UserControl UserInterface { get; } + void Deactivate(); + } +} diff --git a/NAudioWpfDemo/IWaveFormRenderer.cs b/NAudioWpfDemo/IWaveFormRenderer.cs new file mode 100644 index 00000000..9c5426c7 --- /dev/null +++ b/NAudioWpfDemo/IWaveFormRenderer.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NAudioWpfDemo +{ + public interface IWaveFormRenderer + { + void AddValue(float maxValue, float minValue); + } +} diff --git a/NAudioWpfDemo/MainWindow.xaml b/NAudioWpfDemo/MainWindow.xaml new file mode 100644 index 00000000..b59e70b4 --- /dev/null +++ b/NAudioWpfDemo/MainWindow.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/NAudioWpfDemo/MainWindow.xaml.cs b/NAudioWpfDemo/MainWindow.xaml.cs new file mode 100644 index 00000000..4e58ed88 --- /dev/null +++ b/NAudioWpfDemo/MainWindow.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Windows; + +namespace NAudioWpfDemo +{ + /// + /// Interaction logic for Window1.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + this.Title = this.Title + ((System.Runtime.InteropServices.Marshal.SizeOf(IntPtr.Zero) == 8) ? " (x64)" : " (x86)"); + } + } +} diff --git a/NAudioWpfDemo/MainWindowViewModel.cs b/NAudioWpfDemo/MainWindowViewModel.cs new file mode 100644 index 00000000..195e8912 --- /dev/null +++ b/NAudioWpfDemo/MainWindowViewModel.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Windows.Controls; +using NAudioWpfDemo.ViewModel; + +namespace NAudioWpfDemo +{ + class MainWindowViewModel : ViewModelBase + { + private IModule selectedModule; + + public MainWindowViewModel(IEnumerable modules) + { + this.Modules = modules.OrderBy(m => m.Name).ToList(); + if (this.Modules.Count > 0) + { + this.SelectedModule = this.Modules[0]; + } + } + + public List Modules { get; private set; } + + public IModule SelectedModule + { + get + { + return selectedModule; + } + set + { + if (value != selectedModule) + { + if (selectedModule != null) + { + selectedModule.Deactivate(); + } + selectedModule = value; + OnPropertyChanged("SelectedModule"); + OnPropertyChanged("UserInterface"); + } + } + } + + public UserControl UserInterface + { + get + { + if (SelectedModule == null) return null; + return SelectedModule.UserInterface; + } + } + } +} diff --git a/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodePlugin.cs b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodePlugin.cs new file mode 100644 index 00000000..328f55d6 --- /dev/null +++ b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodePlugin.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using System.Text; +using System.Windows.Controls; + +namespace NAudioWpfDemo.MediaFoundationEncode +{ + [Export(typeof(IModule))] + class MediaFoundationEncodePlugin : ModuleBase + { + protected override UserControl CreateViewAndViewModel() + { + return new MediaFoundationEncodeView() {DataContext = new MediaFoundationEncodeViewModel()}; + } + + public override string Name + { + get { return "Media Foundation Encode"; } + } + } +} diff --git a/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml new file mode 100644 index 00000000..ec441452 --- /dev/null +++ b/NAudioWpfDemo/MediaFoundationEncode/MediaFoundationEncodeView.xaml @@ -0,0 +1,39 @@ + + +