2538 lines
94 KiB
C#
Raw Normal View History

2017-01-26 23:40:46 +03:00
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.InteropServices;
2017-01-26 23:40:46 +03:00
using CsbBuilder.Builder;
using CsbBuilder.BuilderNodes;
2017-01-26 23:40:46 +03:00
using CsbBuilder.Audio;
using CsbBuilder.Importer;
using CsbBuilder.Project;
using CsbBuilder.Serialization;
using CsbBuilder.Properties;
using SonicAudioLib.IO;
using SonicAudioLib.Archives;
2017-01-26 23:40:46 +03:00
using NAudio.Wave;
namespace CsbBuilder
{
public partial class MainForm : Form
{
2017-04-17 19:06:29 +03:00
public static Settings Settings;
2017-01-26 23:40:46 +03:00
private bool enabled = false;
private bool saved = true;
private CsbProject project = null;
private TreeNode copiedNode = null;
private TreeView treeViewOfCopiedNode = null;
private List<IWavePlayer> sounds = new List<IWavePlayer>();
private string filters = null;
private string Filters
{
get
{
if (string.IsNullOrEmpty(filters))
{
var culture = Thread.CurrentThread.CurrentUICulture;
var formats = VGMStreamNative.GetFormats().OrderBy(format => format);
var formatFilter = formats.Select(format => $"{format.ToUpper(culture)} Files|*.{format}");
filters = $"All Formats|{string.Join(";", formats.Select(format => $"*.{format}"))}|{string.Join("|", formatFilter)}";
}
return filters;
}
}
2017-01-26 23:40:46 +03:00
public MainForm()
{
InitializeComponent();
imageList.Images.Add("Node", Resources.Node);
imageList.Images.Add("Folder", Resources.Folder);
imageList.Images.Add("FolderOpen", Resources.FolderOpen);
imageList.Images.Add("Sound", Resources.Sound);
2017-04-17 19:06:29 +03:00
Settings = Settings.Load();
2017-01-26 23:40:46 +03:00
}
public void ClearTreeViews()
{
cueTree.Nodes.Clear();
synthTree.Nodes.Clear();
soundElementTree.Nodes.Clear();
aisacTree.Nodes.Clear();
voiceLimitGroupTree.Nodes.Clear();
}
public void ExpandAllTreeViews()
{
cueTree.ExpandAll();
if (cueTree.Nodes.Count > 0)
{
cueTree.Nodes[0].EnsureVisible();
}
synthTree.ExpandAll();
if (synthTree.Nodes.Count > 0)
{
synthTree.Nodes[0].EnsureVisible();
}
soundElementTree.ExpandAll();
if (soundElementTree.Nodes.Count > 0)
{
soundElementTree.Nodes[0].EnsureVisible();
}
aisacTree.ExpandAll();
if (aisacTree.Nodes.Count > 0)
{
aisacTree.Nodes[0].EnsureVisible();
}
voiceLimitGroupTree.ExpandAll();
if (voiceLimitGroupTree.Nodes.Count > 0)
{
voiceLimitGroupTree.Nodes[0].EnsureVisible();
}
}
public void ClearProject()
{
project = null;
ClearTreeViews();
Text = Program.ApplicationTitle;
2017-01-26 23:40:46 +03:00
saved = true;
}
public void DisplayOnTreeView()
{
foreach (BuilderCueNode cueNode in project.CueNodes)
{
TreeNode treeNode = new TreeNode();
treeNode.ContextMenuStrip = cueReferenceMenu;
treeNode.Name = cueNode.Name;
treeNode.Text = treeNode.Name;
treeNode.Tag = cueNode;
cueTree.Nodes.Add(treeNode);
}
foreach (BuilderSynthNode synthNode in project.SynthNodes)
{
TreeNode treeNode = synthTree.CreateNodesByFullPath(synthNode.Name);
treeNode.ContextMenuStrip = trackMenu;
treeNode.Tag = synthNode;
if (synthNode.Type == BuilderSynthType.Single)
{
treeNode.ContextMenuStrip = trackItemMenu;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
}
while ((treeNode = treeNode.Parent) != null)
{
if (treeNode.Tag == null)
{
treeNode.ContextMenuStrip = synthFolderMenu;
}
}
}
foreach (BuilderSoundElementNode soundElementNode in project.SoundElementNodes)
{
TreeNode treeNode = soundElementTree.CreateNodesByFullPath(soundElementNode.Name);
treeNode.ContextMenuStrip = soundElementMenu;
treeNode.Tag = soundElementNode;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
while ((treeNode = treeNode.Parent) != null)
{
if (treeNode.Tag == null)
{
treeNode.ContextMenuStrip = folderMenu;
}
}
}
foreach (BuilderAisacNode aisacNode in project.AisacNodes)
{
TreeNode treeNode = aisacTree.CreateNodesByFullPath(aisacNode.Name);
treeNode.ContextMenuStrip = aisacNodeMenu;
treeNode.Tag = aisacNode;
while ((treeNode = treeNode.Parent) != null)
{
if (treeNode.Tag == null)
{
treeNode.ContextMenuStrip = aisacFolderMenu;
}
}
}
foreach (BuilderVoiceLimitGroupNode voiceLimitGroupNode in project.VoiceLimitGroupNodes)
{
TreeNode treeNode = new TreeNode();
treeNode.ContextMenuStrip = nodeMenu;
treeNode.Name = voiceLimitGroupNode.Name;
treeNode.Text = treeNode.Name;
treeNode.Tag = voiceLimitGroupNode;
voiceLimitGroupTree.Nodes.Add(treeNode);
}
}
public void SetProject(CsbProject project)
{
StopSound(null, null);
if (!enabled)
{
splitContainer1.Enabled = true;
splitContainer2.Enabled = true;
propertyGrid.Enabled = true;
saveProjectAsToolStripMenuItem.Enabled = true;
saveProjectToolStripMenuItem.Enabled = true;
buildCurrentProjectAsToolStripMenuItem.Enabled = true;
buildCurrentProjectToolStripMenuItem.Enabled = true;
mergeProjectToolStripMenuItem.Enabled = true;
ımportAndMergeToolStripMenuItem.Enabled = true;
enabled = true;
}
ClearProject();
this.project = project;
project.Create();
DisplayOnTreeView();
UpdateAllNodes();
ExpandAllTreeViews();
Text += $" - {project.Name}";
}
private void CreateNewProject(object sender, EventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
return;
}
using (CreateNewProjectForm newProject = new CreateNewProjectForm())
{
if (newProject.ShowDialog(this) == DialogResult.OK)
{
SetProject(newProject.Project);
project.Save();
}
}
}
private void ImportCsbFile(object sender, EventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
return;
}
using (OpenFileDialog openCsbFile = new OpenFileDialog
{
Title = "Import CSB File",
DefaultExt = "csb",
Filter = "CSB Files|*.csb",
})
{
if (openCsbFile.ShowDialog() == DialogResult.OK)
{
using (CreateNewProjectForm createProject = new CreateNewProjectForm(openCsbFile.FileName))
{
if (createProject.ShowDialog(this) == DialogResult.OK)
{
createProject.Project.Create();
CsbImporter.Import(openCsbFile.FileName, createProject.Project);
SetProject(createProject.Project);
project.Save();
}
}
}
}
}
private void OnNodeClick(object sender, TreeNodeMouseClickEventArgs e)
{
e.Node.TreeView.SelectedNode = e.Node;
}
private TreeNode CreateCueNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
2017-04-17 19:06:29 +03:00
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Cue";
while (collection.ContainsKey($"{parentName}_{index}"))
2017-01-26 23:40:46 +03:00
{
index++;
}
2017-04-17 19:06:29 +03:00
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
2017-01-26 23:40:46 +03:00
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = cueReferenceMenu;
BuilderCueNode cueNode = new BuilderCueNode();
cueNode.Name = treeNode.FullPath;
if (project.CueNodes.Count > 0)
{
cueNode.Identifier = project.CueNodes.Max(cue => cue.Identifier) + 1;
}
treeNode.Tag = cueNode;
project.CueNodes.Add(cueNode);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private void RemoveNode(BuilderBaseNode node)
{
if (node is BuilderCueNode cueNode)
2017-01-26 23:40:46 +03:00
{
project.CueNodes.Remove(cueNode);
2017-01-26 23:40:46 +03:00
}
else if (node is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
project.SynthNodes.Remove(synthNode);
project.CueNodes.Where(cue => cue.SynthReference == synthNode.Name).ToList().ForEach(cue => cue.SynthReference = string.Empty);
project.SynthNodes.Where(synth => synth.Children.Contains(synthNode.Name)).ToList().ForEach(synth => synth.Children.Remove(synthNode.Name));
}
else if (node is BuilderSoundElementNode soundElementNode)
2017-01-26 23:40:46 +03:00
{
project.SoundElementNodes.Remove(soundElementNode);
project.SynthNodes.Where(soundElement => soundElement.SoundElementReference == soundElementNode.Name).ToList().ForEach(synth => synth.SoundElementReference = string.Empty);
}
else if (node is BuilderAisacNode aisacNode)
2017-01-26 23:40:46 +03:00
{
project.AisacNodes.Remove(aisacNode);
project.SynthNodes.Where(synth => synth.AisacReference == aisacNode.Name).ToList().ForEach(synth => synth.AisacReference = string.Empty);
}
else if (node is BuilderVoiceLimitGroupNode voiceLimitGroupNode)
2017-01-26 23:40:46 +03:00
{
project.VoiceLimitGroupNodes.Remove(voiceLimitGroupNode);
project.SynthNodes.Where(synth => synth.VoiceLimitGroupReference == voiceLimitGroupNode.Name).ToList().ForEach(voiceLimitGroup => voiceLimitGroup.VoiceLimitGroupReference = string.Empty);
}
}
private TreeNode CreateSynthNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
2017-04-17 19:06:29 +03:00
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Synth";
while (collection.ContainsKey($"{parentName}_{index}"))
2017-01-26 23:40:46 +03:00
{
index++;
}
2017-04-17 19:06:29 +03:00
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
2017-01-26 23:40:46 +03:00
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = trackMenu;
BuilderSynthNode synthNode = new BuilderSynthNode();
synthNode.Type = BuilderSynthType.WithChildren;
synthNode.Name = treeNode.FullPath;
treeNode.Tag = synthNode;
project.SynthNodes.Add(synthNode);
if (parent != null && parent.Tag is BuilderSynthNode parentSynthNode)
2017-01-26 23:40:46 +03:00
{
if (parentSynthNode.Type == BuilderSynthType.WithChildren)
{
parentSynthNode.Children.Add(synthNode.Name);
}
}
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateSoundNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
2017-04-17 19:06:29 +03:00
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Sound";
while (collection.ContainsKey($"{parentName}_{index}"))
2017-01-26 23:40:46 +03:00
{
index++;
}
2017-04-17 19:06:29 +03:00
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
2017-01-26 23:40:46 +03:00
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = trackItemMenu;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
BuilderSynthNode synthNode = new BuilderSynthNode();
synthNode.Name = treeNode.FullPath;
treeNode.Tag = synthNode;
project.SynthNodes.Add(synthNode);
if (parent != null && parent.Tag is BuilderSynthNode parentSynthNode)
2017-01-26 23:40:46 +03:00
{
if (parentSynthNode.Type == BuilderSynthType.WithChildren)
{
parentSynthNode.Children.Add(synthNode.Name);
}
}
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateSoundElementNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
2017-04-17 19:06:29 +03:00
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "SoundElement";
while (collection.ContainsKey($"{parentName}_{index}"))
2017-01-26 23:40:46 +03:00
{
index++;
}
2017-04-17 19:06:29 +03:00
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
2017-01-26 23:40:46 +03:00
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = soundElementMenu;
BuilderSoundElementNode soundElementNode = new BuilderSoundElementNode();
soundElementNode.Name = treeNode.FullPath;
treeNode.Tag = soundElementNode;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
project.SoundElementNodes.Add(soundElementNode);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateAisacNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1, BuilderAisacNode aisacNodeToImport = null)
{
saved = false;
int index = 0;
2017-04-17 19:06:29 +03:00
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "AISAC";
while (collection.ContainsKey($"{parentName}_{index}"))
2017-01-26 23:40:46 +03:00
{
index++;
}
2017-04-17 19:06:29 +03:00
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
2017-01-26 23:40:46 +03:00
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = aisacNodeMenu;
BuilderAisacNode aisacNode = aisacNodeToImport != null ? aisacNodeToImport : new BuilderAisacNode();
aisacNode.Name = treeNode.FullPath;
treeNode.Tag = aisacNode;
project.AisacNodes.Add(aisacNode);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateVoiceLimitGroupNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
2017-04-17 19:06:29 +03:00
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "VoiceLimitGroup";
while (collection.ContainsKey($"{parentName}_{index}"))
2017-01-26 23:40:46 +03:00
{
index++;
}
2017-04-17 19:06:29 +03:00
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
2017-01-26 23:40:46 +03:00
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = nodeMenu;
BuilderVoiceLimitGroupNode voiceLimitGroup = new BuilderVoiceLimitGroupNode();
voiceLimitGroup.Name = treeNode.FullPath;
treeNode.Tag = voiceLimitGroup;
project.VoiceLimitGroupNodes.Add(voiceLimitGroup);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateFolder(TreeNodeCollection collection, TreeNode parent)
{
saved = false;
int index = 0;
2017-04-17 19:06:29 +03:00
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Folder";
2017-01-26 23:40:46 +03:00
while (collection.ContainsKey($"Folder_{index}"))
{
index++;
}
TreeNode treeNode = collection.Add($"Folder_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = folderMenu;
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 2;
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateSynthFolder(TreeNodeCollection collection)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"Folder_{index}"))
{
index++;
}
TreeNode treeNode = collection.Add($"Folder_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = synthFolderMenu;
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 2;
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private void CreateChildNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == cueTree)
{
CreateCueNode(selectedTree.Nodes, null);
}
else if (selectedTree == synthTree)
{
if (selectedNode.Tag is BuilderSynthNode synthNode && synthNode.Type == BuilderSynthType.WithChildren)
2017-01-26 23:40:46 +03:00
{
CreateSoundNode(selectedNode.Nodes, selectedNode);
}
else
{
CreateSynthNode(selectedNode.Nodes, selectedNode);
}
}
else if (selectedTree == soundElementTree)
{
CreateSoundElementNode(selectedNode.Nodes, selectedNode);
}
else if (selectedTree == aisacTree)
{
CreateAisacNode(selectedNode.Nodes, selectedNode);
}
else if (selectedTree == voiceLimitGroupTree)
{
CreateVoiceLimitGroupNode(selectedTree.Nodes, null);
}
}
}
private void CreateNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
if (selectedTree == cueTree)
{
CreateCueNode(selectedTree.Nodes, null);
}
else if (selectedTree == synthTree)
{
CreateSynthNode(selectedTree.Nodes, null);
}
else if (selectedTree == soundElementTree)
{
CreateSoundElementNode(selectedTree.Nodes, null);
}
else if (selectedTree == aisacTree)
{
CreateAisacNode(selectedTree.Nodes, null);
}
else if (selectedTree == voiceLimitGroupTree)
{
CreateVoiceLimitGroupNode(selectedTree.Nodes, null);
}
}
}
private void CreateFolder(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
if (selectedTree == synthTree)
{
CreateSynthFolder(selectedTree.Nodes);
}
else
{
CreateFolder(selectedTree.Nodes, null);
}
}
}
private void RemoveNodes(TreeNodeCollection collection)
{
foreach (TreeNode node in collection)
{
if (node.Tag is BuilderBaseNode baseNode)
2017-01-26 23:40:46 +03:00
{
RemoveNode(baseNode);
2017-01-26 23:40:46 +03:00
}
RemoveNodes(node.Nodes);
}
}
private void RemoveNode(TreeNode treeNode)
{
saved = false;
if (treeNode.Tag is BuilderBaseNode baseNode)
2017-01-26 23:40:46 +03:00
{
RemoveNode(baseNode);
2017-01-26 23:40:46 +03:00
}
RemoveNodes(treeNode.Nodes);
treeNode.Remove();
}
private void RemoveNode(object sender, EventArgs e)
{
saved = false;
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
RemoveNode(selectedNode);
}
}
private void BuildProject(object sender, EventArgs e)
{
project.BinaryDirectory.Create();
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
Builder.CsbBuilder.Build(project, Path.Combine(project.BinaryDirectory.FullName, project.Name + ".csb"));
Process.Start(project.BinaryDirectory.FullName);
}
private void CopyFullPath(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
Clipboard.SetText(selectedNode.FullPath);
}
}
private void CreateChildFolder(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == synthTree)
{
CreateSynthFolder(selectedNode.Nodes);
}
else
{
CreateFolder(selectedNode.Nodes, selectedNode);
}
}
}
private void RenameNode(object sender, TreeNodeMouseClickEventArgs e)
{
e.Node.BeginEdit();
}
private void UpdateNodeNoRename(TreeNode treeNode)
{
if (treeNode.Tag is BuilderBaseNode baseNode)
2017-01-26 23:40:46 +03:00
{
baseNode.Name = treeNode.FullPath;
}
foreach (TreeNode childNode in treeNode.Nodes)
{
UpdateNodeNoRename(childNode);
}
}
private void UpdateNodes(TreeNodeCollection collection)
{
foreach (TreeNode treeNode in collection)
{
if (treeNode.Tag is BuilderBaseNode baseNode)
2017-01-26 23:40:46 +03:00
{
string previousName = baseNode.Name;
baseNode.Name = treeNode.FullPath;
// Do it only if it's different, don't waste time
if (previousName != baseNode.Name)
{
string fullPath = baseNode.Name;
if (baseNode is BuilderSynthNode)
{
project.CueNodes.Where(cue => cue.SynthReference == previousName).ToList().ForEach(cue => cue.SynthReference = fullPath);
project.SynthNodes.Where(synth => synth.Children.Contains(previousName)).ToList().ForEach(synth => synth.Children[synth.Children.IndexOf(previousName)] = fullPath);
}
else if (baseNode is BuilderSoundElementNode)
{
project.SynthNodes.Where(synth => synth.SoundElementReference == previousName).ToList().ForEach(synth => synth.SoundElementReference = fullPath);
}
else if (baseNode is BuilderAisacNode)
{
project.SynthNodes.Where(synth => synth.AisacReference == previousName).ToList().ForEach(synth => synth.AisacReference = fullPath);
}
else if (baseNode is BuilderVoiceLimitGroupNode)
{
project.SynthNodes.Where(synth => synth.VoiceLimitGroupReference == previousName).ToList().ForEach(synth => synth.VoiceLimitGroupReference = fullPath);
}
}
}
else
{
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 2;
}
UpdateNodes(treeNode.Nodes);
}
}
private void UpdateAllNodes()
{
UpdateNodes(cueTree.Nodes);
UpdateNodes(synthTree.Nodes);
UpdateNodes(soundElementTree.Nodes);
UpdateNodes(aisacTree.Nodes);
UpdateNodes(voiceLimitGroupTree.Nodes);
}
2017-04-17 19:06:29 +03:00
private void RenameNode(TreeNode node, string name)
2017-01-26 23:40:46 +03:00
{
2017-04-17 19:06:29 +03:00
saved = false;
string previousName = node.FullPath;
// check siblings before rename
TreeNodeCollection collection = node.Parent != null ? node.Parent.Nodes : node.TreeView.Nodes;
if (collection.ContainsKey(name))
2017-01-26 23:40:46 +03:00
{
2017-04-17 19:06:29 +03:00
int index = -1;
string _name = name;
while (collection.ContainsKey(name))
{
name = $"{_name}_{++index}";
}
2017-01-26 23:40:46 +03:00
}
2017-04-17 19:06:29 +03:00
node.Name = name;
node.Text = name;
2017-01-26 23:40:46 +03:00
2017-04-17 19:06:29 +03:00
string fullPath = node.FullPath;
2017-01-26 23:40:46 +03:00
UpdateAllNodes();
2017-04-17 19:06:29 +03:00
if (node.Tag is BuilderSynthNode)
2017-01-26 23:40:46 +03:00
{
project.CueNodes.Where(cue => cue.SynthReference == previousName).ToList().ForEach(cue => cue.SynthReference = fullPath);
project.SynthNodes.Where(synth => synth.Children.Contains(previousName)).ToList().ForEach(synth => synth.Children[synth.Children.IndexOf(previousName)] = fullPath);
}
2017-04-17 19:06:29 +03:00
else if (node.Tag is BuilderSoundElementNode)
2017-01-26 23:40:46 +03:00
{
project.SynthNodes.Where(synth => synth.SoundElementReference == previousName).ToList().ForEach(synth => synth.SoundElementReference = fullPath);
}
2017-04-17 19:06:29 +03:00
else if (node.Tag is BuilderAisacNode)
2017-01-26 23:40:46 +03:00
{
project.SynthNodes.Where(synth => synth.AisacReference == previousName).ToList().ForEach(synth => synth.AisacReference = fullPath);
}
2017-04-17 19:06:29 +03:00
else if (node.Tag is BuilderVoiceLimitGroupNode)
2017-01-26 23:40:46 +03:00
{
project.SynthNodes.Where(synth => synth.VoiceLimitGroupReference == previousName).ToList().ForEach(synth => synth.VoiceLimitGroupReference = fullPath);
}
propertyGrid.Refresh();
}
2017-04-17 19:06:29 +03:00
private void OnRenameEnd(object sender, NodeLabelEditEventArgs e)
{
if (string.IsNullOrEmpty(e.Label) || e.Label == e.Node.Name)
{
e.CancelEdit = true;
return;
}
RenameNode(e.Node, e.Label);
}
2017-01-26 23:40:46 +03:00
private void OnPropertyChange(object s, PropertyValueChangedEventArgs e)
{
saved = false;
propertyGrid.Refresh();
}
private DialogResult AskForSave()
{
DialogResult dialogResult = DialogResult.No;
if (!saved)
{
dialogResult = MessageBox.Show("Do you want to save your changes?", "CSB Builder", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes)
{
SaveProject(null, null);
}
}
return dialogResult;
}
private void LoadProject(object sender, EventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
return;
}
using (OpenFileDialog openProject = new OpenFileDialog
{
Title = "Open CSB Project File",
Filter = "CSB Project files|*.csbproject",
DefaultExt = "csbproject",
})
{
if (openProject.ShowDialog() == DialogResult.OK)
{
CsbProject csbProject = CsbProject.Load(openProject.FileName);
if (!csbProject.AudioDirectory.Exists)
{
MessageBox.Show("Audio directory does not seem to be present for this project. All the audio references will be removed.");
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Intro = string.Empty);
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Loop = string.Empty);
}
SetProject(csbProject);
}
}
}
private void SaveProject(object sender, EventArgs e)
{
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
project.Save();
saved = true;
}
private void SaveProjectAs(object sender, EventArgs e)
{
using (SaveFileDialog saveProject = new SaveFileDialog
{
Title = "Save CSB Project File As",
Filter = "CSB Project files|*.csbproject",
DefaultExt = "csbproject",
})
{
if (saveProject.ShowDialog() == DialogResult.OK)
{
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
project.SaveAs(saveProject.FileName);
saved = true;
// Reload the project
SetProject(project);
}
}
}
private void OnClose(object sender, FormClosingEventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
e.Cancel = true;
}
}
private void Exit(object sender, EventArgs e)
{
Close();
}
private void BuildProjectAs(object sender, EventArgs e)
{
using (SaveFileDialog buildCsb = new SaveFileDialog()
{
Title = "Build Current Project As",
DefaultExt = "csb",
Filter = "CSB Files|*.csb",
FileName = project.Name,
})
{
if (buildCsb.ShowDialog() == DialogResult.OK)
{
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
Builder.CsbBuilder.Build(project, buildCsb.FileName);
}
}
}
private void AfterNodeSelect(object sender, TreeViewEventArgs e)
{
propertyGrid.SelectedObject = e.Node.Tag;
}
private void MergeProject(object sender, EventArgs e)
{
using (OpenFileDialog openProject = new OpenFileDialog
{
Title = "Merge Project With",
Filter = "CSB Project files|*.csbproject",
DefaultExt = "csbproject",
})
{
if (openProject.ShowDialog() == DialogResult.OK)
{
CsbProject csbProject = CsbProject.Load(openProject.FileName);
if (!csbProject.AudioDirectory.Exists)
{
MessageBox.Show("Audio directory does not seem to be present for this project. All the audio references will be removed.");
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Intro = string.Empty);
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Loop = string.Empty);
}
else
{
// Copy all to this project's audio folder
foreach (FileInfo audioFile in csbProject.AudioDirectory.EnumerateFiles())
{
audioFile.CopyTo(Path.Combine(project.AudioDirectory.FullName, audioFile.Name), true);
}
}
project.CueNodes.AddRange(csbProject.CueNodes);
project.SynthNodes.AddRange(csbProject.SynthNodes);
project.SoundElementNodes.AddRange(csbProject.SoundElementNodes);
project.AisacNodes.AddRange(csbProject.AisacNodes);
project.VoiceLimitGroupNodes.AddRange(csbProject.VoiceLimitGroupNodes);
// Reload
SetProject(project);
}
}
}
private void ImportAndMergeProject(object sender, EventArgs e)
{
using (OpenFileDialog openCsbFile = new OpenFileDialog
{
Title = "Import And Merge CSB File With",
DefaultExt = "csb",
Filter = "CSB Files|*.csb",
})
{
if (openCsbFile.ShowDialog() == DialogResult.OK)
{
CsbProject csbProject = new CsbProject();
csbProject.Directory = project.Directory;
CsbImporter.Import(openCsbFile.FileName, csbProject);
project.CueNodes.AddRange(csbProject.CueNodes);
project.SynthNodes.AddRange(csbProject.SynthNodes);
project.SoundElementNodes.AddRange(csbProject.SoundElementNodes);
project.AisacNodes.AddRange(csbProject.AisacNodes);
project.VoiceLimitGroupNodes.AddRange(csbProject.VoiceLimitGroupNodes);
// Reload
SetProject(project);
}
}
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
TreeView treeView = (TreeView)sender;
if (e.KeyCode == Keys.Delete && treeView.SelectedNode != null)
{
RemoveNode(treeView.SelectedNode);
}
else if (e.Control && e.KeyCode == Keys.C && treeView.SelectedNode != null)
{
CopyNode(treeView.SelectedNode);
}
else if (e.Control && e.KeyCode == Keys.V && treeView == treeViewOfCopiedNode)
{
if (treeView.SelectedNode == null)
{
PasteNode();
}
else if (treeView.SelectedNode != null && (treeView.SelectedNode.Tag == null || (treeView.SelectedNode.Tag is BuilderSynthNode synthNode && synthNode.Type == BuilderSynthType.WithChildren)))
2017-01-26 23:40:46 +03:00
{
PasteAsChildNode(treeView.SelectedNode);
}
else if (treeView.SelectedNode != null && treeView.SelectedNode.Tag != null)
{
PasteNode(treeView.SelectedNode.Index + 1);
}
}
else if (e.KeyCode == Keys.Enter && treeView.SelectedNode != null)
{
treeView.SelectedNode.BeginEdit();
}
}
private bool CheckIfAny(TreeView treeView)
{
foreach (TreeNode treeNode in treeView.Nodes)
{
if (CheckIfAny(treeNode))
{
return true;
}
}
return false;
}
private bool CheckIfAny(TreeNode treeNode)
{
if (treeNode.Tag != null)
{
return true;
}
foreach (TreeNode childNode in treeNode.Nodes)
{
if (CheckIfAny(childNode))
{
return true;
}
}
return false;
}
private void SetAisacReference(object sender, EventArgs e)
{
if (!CheckIfAny(aisacTree))
{
MessageBox.Show("This project does not contain any Aisac nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(aisacTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (setReferenceForm.SelectedNode == null)
{
synthNode.AisacReference = string.Empty;
}
else
{
synthNode.AisacReference = setReferenceForm.SelectedNode.FullPath;
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SetVoiceLimitGroupReference(object sender, EventArgs e)
{
if (voiceLimitGroupTree.Nodes.Count == 0)
{
MessageBox.Show("This project does not contain any Voice Limit Group nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(voiceLimitGroupTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (setReferenceForm.SelectedNode == null)
{
synthNode.VoiceLimitGroupReference = string.Empty;
}
else
{
synthNode.VoiceLimitGroupReference = setReferenceForm.SelectedNode.FullPath;
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SetSynthReference(object sender, EventArgs e)
{
if (!CheckIfAny(synthTree))
{
MessageBox.Show("This project does not contain any Synth nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(synthTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderCueNode)
{
BuilderCueNode cueNode = (BuilderCueNode)selectedNode.Tag;
if (setReferenceForm.SelectedNode == null)
{
cueNode.SynthReference = string.Empty;
}
else
{
cueNode.SynthReference = setReferenceForm.SelectedNode.FullPath;
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SelectSynthReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderCueNode cueNode)
2017-01-26 23:40:46 +03:00
{
if (!string.IsNullOrEmpty(cueNode.SynthReference))
{
TreeNode treeNode = synthTree.FindNodeByFullPath(cueNode.SynthReference);
synthTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
synthTree.Focus();
}
}
}
}
private void SelectAisacReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (!string.IsNullOrEmpty(synthNode.AisacReference))
{
TreeNode treeNode = aisacTree.FindNodeByFullPath(synthNode.AisacReference);
tabControl1.SelectTab(tabPage1);
aisacTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
aisacTree.Focus();
}
}
}
}
private void SelectVoiceLimitGroupReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (!string.IsNullOrEmpty(synthNode.VoiceLimitGroupReference))
{
TreeNode treeNode = voiceLimitGroupTree.FindNodeByFullPath(synthNode.VoiceLimitGroupReference);
tabControl1.SelectTab(tabPage2);
voiceLimitGroupTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
voiceLimitGroupTree.Focus();
}
}
}
}
private void SelectSoundElementReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (!string.IsNullOrEmpty(synthNode.SoundElementReference))
{
TreeNode treeNode = soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference);
soundElementTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
soundElementTree.Focus();
}
}
}
}
private void SetSoundElementReference(object sender, EventArgs e)
{
if (!CheckIfAny(soundElementTree))
{
MessageBox.Show("This project does not contain any Sound nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(soundElementTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (setReferenceForm.SelectedNode == null)
{
synthNode.SoundElementReference = string.Empty;
}
else
{
synthNode.SoundElementReference = setReferenceForm.SelectedNode.FullPath;
2017-04-17 19:06:29 +03:00
if (Settings.RenameToSoundElement)
{
RenameNode(selectedNode, setReferenceForm.SelectedNode.Name);
}
2017-01-26 23:40:46 +03:00
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SetAudio(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSoundElementNode soundElementNode)
2017-01-26 23:40:46 +03:00
{
string intro = soundElementNode.Intro;
if (!string.IsNullOrEmpty(intro))
{
intro = Path.Combine(project.AudioDirectory.FullName, intro);
}
string loop = soundElementNode.Loop;
if (!string.IsNullOrEmpty(loop))
{
loop = Path.Combine(project.AudioDirectory.FullName, loop);
}
using (SetAudioForm setAudioForm = new SetAudioForm(intro, loop))
{
if (setAudioForm.ShowDialog(this) == DialogResult.OK)
{
uint sampleRate = soundElementNode.SampleRate;
byte channelCount = soundElementNode.ChannelCount;
uint introSampleCount = 0;
soundElementNode.Intro = project.AddAudio(setAudioForm.Intro);
if (!string.IsNullOrEmpty(setAudioForm.Intro))
{
ReadAdx(setAudioForm.Intro, out sampleRate, out channelCount, out introSampleCount);
}
uint loopSampleCount = 0;
soundElementNode.Loop = project.AddAudio(setAudioForm.Loop);
if (!string.IsNullOrEmpty(setAudioForm.Loop))
{
ReadAdx(setAudioForm.Loop, out sampleRate, out channelCount, out loopSampleCount);
}
soundElementNode.SampleRate = sampleRate;
soundElementNode.ChannelCount = channelCount;
soundElementNode.SampleCount = introSampleCount + loopSampleCount;
propertyGrid.Refresh();
}
}
}
}
}
public void ReadAdx(string path, out uint sampleRate, out byte channelCount, out uint sampleCount)
{
using (var reader = new VGMStreamReader(path))
{
sampleRate = (uint)reader.WaveFormat.SampleRate;
channelCount = (byte)reader.WaveFormat.Channels;
sampleCount = (uint)(reader.Length / 2);
}
2017-01-26 23:40:46 +03:00
}
private void CreateChildSoundNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag == null)
{
CreateSoundNode(selectedNode.Nodes, selectedNode);
}
}
}
private void CreateSound(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
CreateSoundNode(selectedTree.Nodes, null);
}
}
private int GetByteCountFromMiliseconds(int miliseconds, int sampleRate, int channelCount, int bitsPerSample)
{
return (int)(miliseconds * sampleRate / 1000.0) * channelCount * bitsPerSample / 8;
}
private int GetMilisecondsFromByteCount(int byteCount, int sampleRate, int channelCount, int bitsPerSample)
{
return (int)((8000.0 * byteCount) / (sampleRate * channelCount * bitsPerSample));
}
private WaveStream GetWaveStream(string path)
{
if (path.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
{
return new WaveFileReader(project.GetFullAudioPath(path));
}
return new VGMStreamReader(project.GetFullAudioPath(path));
}
private void AddSoundElementSound(BuilderSoundElementNode soundElementNode, double volume, double pitch, int delayTime)
2017-01-26 23:40:46 +03:00
{
2017-04-17 19:06:29 +03:00
WaveStream waveStream = null;
2017-01-26 23:40:46 +03:00
2017-04-17 19:06:29 +03:00
if (!string.IsNullOrEmpty(soundElementNode.Intro) && string.IsNullOrEmpty(soundElementNode.Loop))
2017-01-26 23:40:46 +03:00
{
var reader = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Intro));
reader.DisableLoop();
waveStream = new ExtendedWaveStream(reader)
{
DelayTime = delayTime,
Volume = volume,
Pitch = pitch,
};
2017-04-17 19:06:29 +03:00
}
2017-01-26 23:40:46 +03:00
2017-04-17 19:06:29 +03:00
else if (string.IsNullOrEmpty(soundElementNode.Intro) && !string.IsNullOrEmpty(soundElementNode.Loop))
{
var reader = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Loop));
reader.ForceLoop();
waveStream = new ExtendedWaveStream(reader)
{
DelayTime = delayTime,
Volume = volume,
Pitch = pitch,
ForceLoop = true,
};
2017-01-26 23:40:46 +03:00
}
2017-04-17 19:06:29 +03:00
else if (!string.IsNullOrEmpty(soundElementNode.Intro) && !string.IsNullOrEmpty(soundElementNode.Loop))
2017-01-26 23:40:46 +03:00
{
var intro = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Intro));
intro.DisableLoop();
var loop = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Loop));
loop.ForceLoop();
waveStream = new ExtendedWaveStream(intro, loop)
{
DelayTime = delayTime,
Volume = volume,
Pitch = pitch,
ForceLoop = true,
};
2017-01-26 23:40:46 +03:00
}
2017-04-17 19:06:29 +03:00
if (waveStream != null)
2017-01-26 23:40:46 +03:00
{
IWavePlayer wavePlayer = null;
switch (Settings.WavePlayer)
{
case Settings.NAudioWavePlayer.WaveOut:
wavePlayer = new WaveOut();
break;
case Settings.NAudioWavePlayer.WasapiOut:
wavePlayer = new WasapiOut();
break;
case Settings.NAudioWavePlayer.DirectSoundOut:
wavePlayer = new DirectSoundOut();
break;
case Settings.NAudioWavePlayer.AsioOut:
wavePlayer = new AsioOut();
break;
}
wavePlayer.Init(waveStream);
sounds.Add(wavePlayer);
2017-01-26 23:40:46 +03:00
}
}
private void AddSoundElementSound(TreeNode soundElementTreeNode, double volume, double pitch, int delayTime)
2017-01-26 23:40:46 +03:00
{
AddSoundElementSound((BuilderSoundElementNode)soundElementTreeNode.Tag, volume, pitch, delayTime);
2017-01-26 23:40:46 +03:00
}
private double GetSecondsFromSampleCount(int sampleCount, int sampleRate)
{
return sampleCount / (double)sampleRate;
}
private void GetTheBiggestSampleCount(TreeNode synthTreeNode, ref int sampleCount)
{
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (synthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(synthNode.SoundElementReference))
{
BuilderSoundElementNode soundElementNode = (BuilderSoundElementNode)soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference).Tag;
// We want the loop to be at least 10 seconds
int soundElementSampleCount = (int)soundElementNode.SampleCount;
while (GetSecondsFromSampleCount(soundElementSampleCount, (int)soundElementNode.SampleRate) < 10.0)
{
soundElementSampleCount *= 2;
}
if (soundElementSampleCount > sampleCount)
{
sampleCount = soundElementSampleCount;
}
}
}
foreach (TreeNode childNode in synthTreeNode.Nodes)
{
GetTheBiggestSampleCount(childNode, ref sampleCount);
}
}
private double GetAbsolutePitch(TreeNode synthTreeNode)
{
double pitch = 0;
while (synthTreeNode != null)
{
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
pitch += synthNode.Pitch;
}
synthTreeNode = synthTreeNode.Parent;
}
return pitch / 1500.0;
2017-01-26 23:40:46 +03:00
}
private double GetAbsoluteVolume(TreeNode synthTreeNode)
{
double volume = 1000;
while (synthTreeNode != null)
{
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
volume = (volume * synthNode.Volume) / 1000.0;
2017-01-26 23:40:46 +03:00
}
synthTreeNode = synthTreeNode.Parent;
}
return volume / 1000.0;
}
private int GetAbsoluteDelayTime(TreeNode synthTreeNode)
{
int delayTime = 0;
while (synthTreeNode != null)
{
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
delayTime += (int)synthNode.DelayTime;
}
synthTreeNode = synthTreeNode.Parent;
}
return delayTime;
}
private void AddSynthSound(TreeNode synthTreeNode)
2017-01-26 23:40:46 +03:00
{
BuilderSynthNode synthNode = (BuilderSynthNode)synthTreeNode.Tag;
if (synthNode.Type == BuilderSynthType.WithChildren)
{
if (synthNode.PlaybackType == BuilderSynthPlaybackType.RandomNoRepeat || synthNode.PlaybackType == BuilderSynthPlaybackType.Random)
{
TreeNode childNode = synthTreeNode.Nodes[synthNode.RandomChildNode];
BuilderSynthNode childSynthNode = (BuilderSynthNode)childNode.Tag;
if (childSynthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(childSynthNode.SoundElementReference) && childSynthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), GetAbsoluteDelayTime(childNode));
2017-01-26 23:40:46 +03:00
}
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
{
AddSynthSound(childNode);
2017-01-26 23:40:46 +03:00
}
}
else if (synthNode.PlaybackType == BuilderSynthPlaybackType.Sequential)
{
TreeNode childNode = synthTreeNode.Nodes[synthNode.NextChildNode];
BuilderSynthNode childSynthNode = (BuilderSynthNode)childNode.Tag;
if (childSynthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(childSynthNode.SoundElementReference) && childSynthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), GetAbsoluteDelayTime(childNode));
2017-01-26 23:40:46 +03:00
}
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
{
AddSynthSound(childNode);
2017-01-26 23:40:46 +03:00
}
}
else
{
foreach (TreeNode childNode in synthTreeNode.Nodes)
{
BuilderSynthNode childSynthNode = (BuilderSynthNode)childNode.Tag;
if (childSynthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(childSynthNode.SoundElementReference) && childSynthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), GetAbsoluteDelayTime(childNode));
2017-01-26 23:40:46 +03:00
}
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
{
AddSynthSound(childNode);
2017-01-26 23:40:46 +03:00
}
}
}
}
else if (synthNode.Type == BuilderSynthType.Single)
{
if (!string.IsNullOrEmpty(synthNode.SoundElementReference) && synthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference), synthNode.Volume / 1000.0, synthNode.Pitch / 1500.0, (int)synthNode.DelayTime);
2017-01-26 23:40:46 +03:00
}
}
}
private int GetTheBiggestSampleCount(TreeNode synthNode)
{
int sampleCount = -1;
GetTheBiggestSampleCount(synthNode, ref sampleCount);
return sampleCount;
}
private void PlaySound(object sender, EventArgs e)
{
StopSound(sender, e);
if (cueTree.Focused && cueTree.SelectedNode != null && cueTree.SelectedNode.Tag is BuilderCueNode cueNode)
2017-01-26 23:40:46 +03:00
{
if (!string.IsNullOrEmpty(cueNode.SynthReference))
{
TreeNode synthNode = synthTree.FindNodeByFullPath(cueNode.SynthReference);
AddSynthSound(synthNode);
2017-01-26 23:40:46 +03:00
}
}
else if (soundElementTree.Focused && soundElementTree.SelectedNode != null && soundElementTree.SelectedNode.Tag is BuilderSoundElementNode)
{
AddSoundElementSound(soundElementTree.SelectedNode, 1, 0, 0);
2017-01-26 23:40:46 +03:00
}
else if (synthTree.Focused && synthTree.SelectedNode != null && synthTree.SelectedNode.Tag is BuilderSynthNode)
{
AddSynthSound(synthTree.SelectedNode);
2017-01-26 23:40:46 +03:00
}
sounds.ForEach(sound => sound.Play());
}
private void StopSound(object sender, EventArgs e)
{
sounds.ForEach(sound =>
{
sound.Stop();
sound.Dispose();
});
sounds.Clear();
}
private TreeNode CloneNode(TreeNode treeNode)
{
TreeNode clonedNode = (TreeNode)treeNode.Clone();
CloneTag(clonedNode);
return clonedNode;
}
private void CloneTag(TreeNode treeNode)
{
if (treeNode.Tag != null && treeNode.Tag is ICloneable clonable)
2017-01-26 23:40:46 +03:00
{
treeNode.Tag = clonable.Clone();
2017-01-26 23:40:46 +03:00
}
foreach (TreeNode childNode in treeNode.Nodes)
{
CloneTag(childNode);
}
}
private void CopyNode(TreeNode treeNode)
{
treeViewOfCopiedNode = treeNode.TreeView;
copiedNode = CloneNode(treeNode);
}
private void CopyNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
CopyNode(selectedTree.SelectedNode);
2017-01-26 23:40:46 +03:00
}
}
private void AddToProject(TreeNode treeNode)
{
if (treeNode.Tag is BuilderCueNode cueNode)
2017-01-26 23:40:46 +03:00
{
// Do checks
if (!string.IsNullOrEmpty(cueNode.SynthReference) && synthTree.FindNodeByFullPath(cueNode.SynthReference) == null)
{
cueNode.SynthReference = string.Empty;
}
project.CueNodes.Add(cueNode);
}
else if (treeNode.Tag is BuilderSynthNode synthNode)
2017-01-26 23:40:46 +03:00
{
if (!string.IsNullOrEmpty(synthNode.SoundElementReference) && soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference) == null)
{
synthNode.SoundElementReference = string.Empty;
}
if (!string.IsNullOrEmpty(synthNode.AisacReference) && aisacTree.FindNodeByFullPath(synthNode.AisacReference) == null)
{
synthNode.AisacReference = string.Empty;
}
if (!string.IsNullOrEmpty(synthNode.VoiceLimitGroupReference) && !voiceLimitGroupTree.Nodes.ContainsKey(synthNode.VoiceLimitGroupReference))
{
synthNode.VoiceLimitGroupReference = string.Empty;
}
project.SynthNodes.Add(synthNode);
}
if (treeNode.Tag is BuilderSoundElementNode soundElementNode)
2017-01-26 23:40:46 +03:00
{
if (!string.IsNullOrEmpty(soundElementNode.Intro) && !File.Exists(project.GetFullAudioPath(soundElementNode.Intro)))
{
soundElementNode.Intro = string.Empty;
}
if (!string.IsNullOrEmpty(soundElementNode.Loop) && !File.Exists(project.GetFullAudioPath(soundElementNode.Loop)))
{
soundElementNode.Loop = string.Empty;
}
project.SoundElementNodes.Add(soundElementNode);
}
if (treeNode.Tag is BuilderAisacNode aisacNode)
2017-01-26 23:40:46 +03:00
{
project.AisacNodes.Add(aisacNode);
2017-01-26 23:40:46 +03:00
}
if (treeNode.Tag is BuilderVoiceLimitGroupNode voiceLimitGroupNode)
2017-01-26 23:40:46 +03:00
{
project.VoiceLimitGroupNodes.Add(voiceLimitGroupNode);
2017-01-26 23:40:46 +03:00
}
}
private void PasteAsChildNode(TreeNode parent, int nodeIndex = -1)
{
saved = false;
TreeNode nodeToPaste = CloneNode(copiedNode);
// Look for any duplicates
int index = -1;
string name = nodeToPaste.Name;
while (parent.Nodes.ContainsKey(nodeToPaste.Name))
{
nodeToPaste.Name = $"{name}_Copy{++index}";
}
nodeToPaste.Text = nodeToPaste.Name;
// paste it now
if (nodeIndex == -1)
{
parent.Nodes.Add(nodeToPaste);
}
else
{
parent.Nodes.Insert(nodeIndex, nodeToPaste);
}
// Update the CSB node and its children (will prevent some issues)
UpdateNodeNoRename(nodeToPaste);
// fix node if the tree is synthTree, and the nodes are synth nodes
if (parent.TreeView == synthTree && parent.Tag is BuilderSynthNode synthNode && nodeToPaste.Tag is BuilderSynthNode copiedSynthNode)
2017-01-26 23:40:46 +03:00
{
if (synthNode.Type == BuilderSynthType.WithChildren)
{
// add the new node to track's children
synthNode.Children.Add(copiedSynthNode.Name);
}
}
AddToProject(nodeToPaste);
nodeToPaste.TreeView.SelectedNode = nodeToPaste;
nodeToPaste.EnsureVisible();
}
private void PasteNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == treeViewOfCopiedNode)
{
// Parent is a CSB node but the copied object is a folder? abort.
if (selectedNode.Tag != null && copiedNode.Tag == null)
{
return;
}
PasteAsChildNode(selectedNode);
}
}
}
private void PasteNode(int nodeIndex = -1)
{
saved = false;
TreeNode nodeToPaste = CloneNode(copiedNode);
// check if it's cue and fix duplicate identifier if needed
if (nodeToPaste.Tag is BuilderCueNode cueNode)
2017-01-26 23:40:46 +03:00
{
while (project.CueNodes.Exists(cue => cue.Identifier == cueNode.Identifier))
{
cueNode.Identifier++;
}
}
// paste
if (treeViewOfCopiedNode.SelectedNode != null && treeViewOfCopiedNode.SelectedNode.Parent != null)
{
// Look for any duplicates
int index = -1;
string name = nodeToPaste.Name;
while (treeViewOfCopiedNode.SelectedNode.Parent.Nodes.ContainsKey(nodeToPaste.Name))
{
nodeToPaste.Name = $"{name}_Copy{++index}";
}
nodeToPaste.Text = nodeToPaste.Name;
if (nodeIndex == -1)
{
treeViewOfCopiedNode.SelectedNode.Parent.Nodes.Add(nodeToPaste);
}
else
{
treeViewOfCopiedNode.SelectedNode.Parent.Nodes.Insert(nodeIndex, nodeToPaste);
}
}
else
{
// Look for any duplicates
int index = -1;
string name = nodeToPaste.Name;
while (treeViewOfCopiedNode.Nodes.ContainsKey(nodeToPaste.Name))
{
nodeToPaste.Name = $"{name}_Copy{++index}";
}
nodeToPaste.Text = nodeToPaste.Name;
if (nodeIndex == -1)
{
treeViewOfCopiedNode.Nodes.Add(nodeToPaste);
}
else
{
treeViewOfCopiedNode.Nodes.Insert(nodeIndex, nodeToPaste);
}
}
// update the CSB node and its children
UpdateNodeNoRename(nodeToPaste);
AddToProject(nodeToPaste);
nodeToPaste.TreeView.SelectedNode = nodeToPaste;
nodeToPaste.EnsureVisible();
}
private void PasteNodeOnTree(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
if (selectedTree == treeViewOfCopiedNode)
{
PasteNode();
}
}
}
private void PasteAndInsertNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == treeViewOfCopiedNode)
{
PasteNode(selectedNode.Index + 1);
}
}
}
private void ShowAbout(object sender, EventArgs e)
{
MessageBox.Show($"{Program.ApplicationTitle} by Skyth (blueskythlikesclouds)", "CSB Builder");
2017-01-26 23:40:46 +03:00
}
private void CreateChildTrackNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == synthTree)
{
CreateSynthNode(selectedNode.Nodes, selectedNode);
}
}
}
private void CreateAndInsertNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == cueTree)
{
CreateCueNode(selectedTree.Nodes, null, selectedNode.Index + 1);
}
else if (selectedTree == synthTree)
{
if (selectedNode.Tag is BuilderSynthNode synthNode && synthNode.Type == BuilderSynthType.WithChildren)
2017-01-26 23:40:46 +03:00
{
CreateSoundNode(selectedNode.Nodes, selectedNode, selectedNode.Index + 1);
}
else
{
CreateSynthNode(selectedNode.Nodes, selectedNode, selectedNode.Index + 1);
}
}
else if (selectedTree == soundElementTree)
{
CreateSoundElementNode(selectedNode.Parent != null ? selectedNode.Parent.Nodes : selectedTree.Nodes, selectedNode, selectedNode.Index + 1);
}
else if (selectedTree == aisacTree)
{
CreateAisacNode(selectedNode.Nodes, selectedNode, selectedNode.Index + 1);
}
else if (selectedTree == voiceLimitGroupTree)
{
CreateVoiceLimitGroupNode(selectedTree.Nodes, null, selectedNode.Index + 1);
}
}
}
private void CreateAndInsertSoundNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
if (selectedNode.Parent == null)
{
CreateSoundNode(synthTree.Nodes, null, selectedNode.Index + 1);
}
else
{
CreateSoundNode(selectedNode.Parent.Nodes, selectedNode.Parent, selectedNode.Index + 1);
}
}
}
}
private void LoadTemplate(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == aisacTree)
{
using (OpenFileDialog openAisacTemplate = new OpenFileDialog()
{
Title = "Load AISAC Template",
Filter = "XML Files|*.xml",
DefaultExt = "xml",
FileName = selectedNode != null ? selectedNode.Name : string.Empty,
})
{
if (openAisacTemplate.ShowDialog() == DialogResult.OK)
{
XmlSerializer aisacSerializer = new XmlSerializer(typeof(BuilderAisacNode));
try
{
using (Stream source = File.OpenRead(openAisacTemplate.FileName))
{
BuilderAisacNode aisacNode = (BuilderAisacNode)aisacSerializer.Deserialize(source);
TreeNode aisacTreeNode = null;
// folder
if (selectedNode != null && selectedNode.Tag == null)
{
aisacTreeNode = CreateAisacNode(selectedNode.Nodes, selectedNode, -1, aisacNode);
}
// aisac
else if (selectedNode != null && selectedNode.Tag is BuilderAisacNode)
{
project.AisacNodes[project.AisacNodes.IndexOf((BuilderAisacNode)selectedNode.Tag)] = aisacNode;
aisacNode.Name = selectedNode.FullPath;
selectedNode.Tag = aisacNode;
selectedTree.SelectedNode = selectedNode;
}
// nothing, create a new aisac
else if (selectedNode == null)
{
aisacTreeNode = CreateAisacNode(aisacTree.Nodes, null, -1, aisacNode);
}
// fix the current aisac if it was imported
if (aisacTreeNode != null)
{
if (!string.IsNullOrEmpty(aisacNode.Name))
{
// duplicate? fix it really quick
string name = Path.GetFileName(aisacNode.Name);
string uniqueName = name;
TreeNodeCollection collection = aisacTreeNode.Parent != null ? aisacTreeNode.Parent.Nodes : aisacTree.Nodes;
int index = -1;
while (collection.ContainsKey(uniqueName))
{
uniqueName = $"{name}_{++index}";
}
aisacTreeNode.Name = uniqueName;
aisacTreeNode.Text = aisacTreeNode.Name;
}
aisacNode.Name = aisacTreeNode.FullPath;
aisacTreeNode.Tag = aisacNode;
selectedTree.SelectedNode = aisacTreeNode;
aisacTreeNode.EnsureVisible();
}
}
}
catch
{
MessageBox.Show("The template file is invalid.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}
}
private void SaveTemplate(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView selectedTree)
2017-01-26 23:40:46 +03:00
{
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == aisacTree)
{
using (SaveFileDialog saveAisacTemplate = new SaveFileDialog()
{
Title = "Save AISAC Template",
Filter = "XML Files|*.xml",
DefaultExt = "xml",
FileName = selectedNode.Name,
})
{
if (saveAisacTemplate.ShowDialog() == DialogResult.OK)
{
if (selectedNode.Tag is BuilderAisacNode)
{
XmlSerializer aisacSerializer = new XmlSerializer(typeof(BuilderAisacNode));
using (Stream destination = File.Create(saveAisacTemplate.FileName))
{
aisacSerializer.Serialize(destination, selectedNode.Tag);
}
}
}
}
}
}
}
2017-04-17 19:06:29 +03:00
private void OpenSettings(object sender, EventArgs e)
{
using (SettingsForm settings = new SettingsForm())
{
settings.ShowDialog(this);
}
}
private void convertADXsToWAVToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog
{
Title = "Convert Audio Files",
FileName = "Select audio files you want to convert and press Open",
Filter = Filters,
2017-04-17 19:06:29 +03:00
Multiselect = true,
})
{
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog
{
Title = "Output Directory",
FileName = "Enter into a directory and press Save",
})
{
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
var failedFiles = new List<string>();
Action<string> action = fileName =>
2017-04-17 19:06:29 +03:00
{
VGMStreamReader reader = null;
try
{
reader = new VGMStreamReader(fileName);
}
catch (NullReferenceException)
{
failedFiles.Add(Path.GetFileName(fileName));
return;
}
using (reader)
2017-04-17 19:06:29 +03:00
using (WaveFileWriter writer = new WaveFileWriter(
Path.Combine(
Path.GetDirectoryName(saveFileDialog.FileName),
Path.GetFileNameWithoutExtension(fileName) + ".wav"),
reader.WaveFormat))
{
if (reader.LoopFlag)
{
// Intro
DataStream.CopyPartTo(reader, writer, reader.LoopStartPosition, Settings.BufferSize);
// Loops
DataStream.CopyPartTo(reader, writer, (reader.LoopEndPosition - reader.LoopStartPosition) * Settings.LoopCount, Settings.BufferSize);
// Last loop, fade away
byte[] buffer = new byte[Settings.BufferSize];
// Fade will be 10 seconds
double sampleCount = (int)(reader.WaveFormat.AverageBytesPerSecond * Settings.FadeTime);
int i;
int j = (int)(sampleCount + reader.WaveFormat.AverageBytesPerSecond * Settings.FadeDelay);
2017-04-17 19:06:29 +03:00
while (j > 0)
{
reader.Read(buffer, 0, buffer.Length);
for (i = 0; i < buffer.Length && j > 0; i += 2, j--)
{
double volume = j / sampleCount;
// Clamp to 0.0-1.0 range so delay actually works
volume = volume > 1.0 ? 1.0 : volume;
PostSampleEditor.ApplyVolume(buffer, i, volume);
}
writer.Write(buffer, 0, i);
}
}
else
2017-04-17 19:06:29 +03:00
{
DataStream.CopyTo(reader, writer, Settings.BufferSize);
2017-04-17 19:06:29 +03:00
}
}
};
if (Settings.EnableThreading)
{
Parallel.ForEach(openFileDialog.FileNames, new ParallelOptions { MaxDegreeOfParallelism = Settings.MaxThreads }, action);
}
else
{
foreach (var item in openFileDialog.FileNames)
{
action(item);
}
}
if (failedFiles.Count != 0)
{
MessageBox.Show($"Following files could not be converted:\n{string.Join("\n", failedFiles)}", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
2017-04-17 19:06:29 +03:00
}
}
}
}
}
}
private void extractAAXToFolderToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog
{
Title = "Extract AAX Files",
FileName = "Select AAX files you want to extract and press Open",
Filter = "AAX Files|*.aax",
DefaultExt = "aax",
Multiselect = true,
})
{
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog
{
Title = "Output Directory",
FileName = "Enter into a directory and press Save",
})
{
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
DataExtractor extractor = new DataExtractor();
extractor.EnableThreading = Settings.EnableThreading;
extractor.MaxThreads = Settings.MaxThreads;
extractor.BufferSize = Settings.BufferSize;
2017-04-17 19:06:29 +03:00
foreach (string fileName in openFileDialog.FileNames)
{
CriAaxArchive aaxArchive = new CriAaxArchive();
aaxArchive.Load(fileName, Settings.BufferSize);
foreach (CriAaxEntry entry in aaxArchive)
{
using (Stream source = File.OpenRead(fileName))
{
extractor.Add(fileName, Path.Combine(
Path.GetDirectoryName(saveFileDialog.FileName),
$"{Path.GetFileNameWithoutExtension(fileName)}_{entry.Flag}{aaxArchive.GetModeExtension()}"),
entry.Position,
entry.Length);
2017-04-17 19:06:29 +03:00
}
}
}
extractor.Run();
2017-04-17 19:06:29 +03:00
}
}
}
}
}
private void packFolderToAAXToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog
{
Title = "Pack ADX Files",
2017-04-17 19:06:29 +03:00
FileName = "Select ADX files you want to pack and press Open",
Filter = "All Files|*.adx;*.wav|ADX Files|*.adx|WAV Files|*.wav",
2017-04-17 19:06:29 +03:00
Multiselect = true,
})
{
string[] files = null;
DialogResult dialogResult;
while ((dialogResult = openFileDialog.ShowDialog(this)) == DialogResult.OK)
{
if (openFileDialog.FileNames.Length > 2)
{
MessageBox.Show("You can select maximum 2 ADX files.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else if (openFileDialog.FileNames.Length == 2 &&
!Path.GetExtension(openFileDialog.FileNames[0]).Equals(
Path.GetExtension(openFileDialog.FileNames[1]), StringComparison.OrdinalIgnoreCase))
{
MessageBox.Show("You can select only the same type of files.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
2017-04-17 19:06:29 +03:00
else
{
files = openFileDialog.FileNames;
break;
}
}
if (dialogResult == DialogResult.OK)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog
{
Title = "Output File",
FileName = $"{Path.GetFileNameWithoutExtension(files[0])}.aax",
2017-04-17 19:06:29 +03:00
Filter = "AAX Files|*.aax",
DefaultExt = "aax",
})
{
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
CriAaxArchive archive = new CriAaxArchive();
archive.SetModeFromExtension(files[0]);
2017-04-17 19:06:29 +03:00
for (int i = 0; i < files.Length; i++)
{
archive.Add(new CriAaxEntry { FilePath = new FileInfo(files[i]), Flag = (CriAaxEntryFlag)i });
}
archive.Save(saveFileDialog.FileName);
}
}
}
}
}
private void convertAndSplitLoopingToWAVToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog
{
Title = "Convert And Split Audio Files",
FileName = "Select audio files you want to convert and press Open",
Filter = Filters,
Multiselect = true,
})
{
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog
{
Title = "Output Directory",
FileName = "Enter into a directory and press Save",
})
{
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
var failedFiles = new List<string>();
Action<string> action = fileName =>
{
VGMStreamReader reader = null;
try
{
reader = new VGMStreamReader(fileName);
}
catch (NullReferenceException)
{
failedFiles.Add(Path.GetFileName(fileName));
return;
}
using (reader)
{
string outputFileName =
Path.Combine(
Path.GetDirectoryName(saveFileDialog.FileName),
Path.GetFileNameWithoutExtension(fileName));
WaveFileWriter introWriter;
WaveFileWriter loopWriter;
if (reader.LoopFlag)
{
using (introWriter = new WaveFileWriter(outputFileName + "_Intro.wav", reader.WaveFormat))
using (loopWriter = new WaveFileWriter(outputFileName + "_Loop.wav", reader.WaveFormat))
{
DataStream.CopyPartTo(reader, introWriter, 0, reader.LoopStartPosition, Settings.BufferSize);
DataStream.CopyPartTo(reader, loopWriter, reader.LoopStartPosition, reader.LoopEndPosition - reader.LoopStartPosition, Settings.BufferSize);
}
}
// No loop enabled, directly extract the intro
else
{
using (introWriter = new WaveFileWriter(outputFileName + "_Intro.wav", reader.WaveFormat))
{
DataStream.CopyTo(reader, introWriter, Settings.BufferSize);
}
}
}
};
if (Settings.EnableThreading)
{
Parallel.ForEach(openFileDialog.FileNames, new ParallelOptions { MaxDegreeOfParallelism = Settings.MaxThreads }, action);
}
else
{
foreach (var item in openFileDialog.FileNames)
{
action(item);
}
}
if (failedFiles.Count != 0)
{
MessageBox.Show($"Following files could not be converted:\n{string.Join("\n", failedFiles)}", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}
}
2017-01-26 23:40:46 +03:00
}
}