├── .gitignore ├── Image ├── Ico.png ├── Krystal.png ├── Menu │ ├── close.png │ ├── export.png │ ├── help.png │ ├── iconSet.png │ ├── import.png │ ├── new.png │ ├── nsm.png │ ├── open.png │ ├── quitter.png │ ├── rename.png │ ├── save.png │ └── saveAs.png ├── Track │ ├── Idle.png │ ├── Mute.png │ └── NoteDown.png ├── Tree │ ├── FILES.png │ ├── bank.ico │ ├── bank.png │ ├── blank.png │ ├── group.ico │ ├── group.png │ ├── lookup.ico │ ├── lookup.png │ ├── player.png │ ├── psg.png │ ├── ranged.png │ ├── record.png │ ├── recordArc.ico │ ├── recordArc.png │ ├── recordRegion.png │ ├── regional.png │ ├── seqArc.ico │ ├── seqArc.png │ ├── sseq.ico │ ├── sseq.png │ ├── streamPlayer.png │ ├── strm.ico │ ├── strm.png │ ├── version.png │ ├── wave.ico │ ├── wave.png │ ├── waveArchive.ico │ ├── waveArchive.png │ └── whiteNoise.png ├── icon.ico └── icon.png ├── InstallerFolderPermissions ├── Installer1.Designer.cs ├── Installer1.cs ├── InstallerFolderPermissions.csproj └── Properties │ └── AssemblyInfo.cs ├── Nitro Studio 2.sln ├── Nitro Studio 2 ├── AboutWindow.Designer.cs ├── AboutWindow.cs ├── AboutWindow.resx ├── App.config ├── AxInterop.WMPLib.dll ├── BankEditor.cs ├── BankGenerator.Designer.cs ├── BankGenerator.cs ├── BankGenerator.resx ├── CreateStreamTool.Designer.cs ├── CreateStreamTool.cs ├── CreateStreamTool.resx ├── EditorBase.cs ├── EditorBase.resx ├── FodyWeavers.xml ├── Hardware │ ├── DutyCycle1.wav │ ├── DutyCycle2.wav │ ├── DutyCycle3.wav │ ├── DutyCycle4.wav │ ├── DutyCycle5.wav │ ├── DutyCycle6.wav │ ├── DutyCycle7.wav │ ├── Null.wav │ └── WhiteNoise.wav ├── Instrument Selector.Designer.cs ├── Instrument Selector.cs ├── Instrument Selector.resx ├── Interop.WMPLib.dll ├── MainWindow.cs ├── Nitro Studio 2.csproj ├── NitroStudio2Instrument.cs ├── NitroStudioInstrument.cs ├── PianoKey.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ ├── Ico.png │ ├── Idle.png │ ├── Mute.png │ ├── NoteDown.png │ ├── War.ico │ ├── bank.ico │ ├── bank.png │ ├── close.png │ ├── export.png │ ├── help.png │ ├── icon.ico │ ├── icon.png │ ├── import.png │ ├── new.png │ ├── nsm.png │ ├── open.png │ ├── quitter.png │ ├── rename.png │ ├── save.png │ ├── saveAs.png │ ├── sseq.ico │ ├── wave.ico │ └── waveArchive.ico ├── SaveCloseDialog.Designer.cs ├── SaveCloseDialog.cs ├── SaveCloseDialog.resx ├── SaveQuitDialog.Designer.cs ├── SaveQuitDialog.cs ├── SaveQuitDialog.resx ├── SequenceArchiveEditor.cs ├── SequenceEditor.cs ├── SequenceRecorder.Designer.cs ├── SequenceRecorder.cs ├── SequenceRecorder.resx ├── StreamPlayer.Designer.cs ├── StreamPlayer.cs ├── StreamPlayer.resx ├── Syroot.BinaryData.dll ├── WaveArchiveEditor.cs ├── WaveMapper.Designer.cs ├── WaveMapper.cs ├── WaveMapper.resx ├── icon.ico ├── libgcc_s_dw2-1.dll ├── libstdc++-6.dll ├── midi2sseq.exe ├── packages.config └── sseq2midi.exe ├── NitroFileLoader ├── Bank.cs ├── CommonStructures.cs ├── Instrument │ ├── DirectInstrument.cs │ ├── DrumSetInstrument.cs │ ├── Instrument.cs │ ├── KeySplitInstrument.cs │ └── NoteInfo.cs ├── NitroFileLoader.csproj ├── NitroStream.cs ├── NitroWave.cs ├── Properties │ └── AssemblyInfo.cs ├── Rom.cs ├── Sequence.cs ├── SequenceArchive.cs ├── Sound Archive │ ├── BankInfo.cs │ ├── GroupEntry.cs │ ├── GroupInfo.cs │ ├── PlayerInfo.cs │ ├── SequenceArchiveInfo.cs │ ├── SequenceInfo.cs │ ├── StreamInfo.cs │ ├── StreamPlayerInfo.cs │ └── WaveArchiveInfo.cs ├── SoundArchive.cs ├── SoundFont2.dll └── WaveArchive.cs ├── NitroStudio2Installer └── NitroStudio2Installer.vdproj ├── README.md └── docs ├── _config.yml ├── favIcon.ico ├── guide ├── bankEditor.md ├── bankGenerator.md ├── fileTypes.md ├── generalEditorControls.md ├── img │ ├── aboutMenu.png │ ├── aboutWindow.png │ ├── adsr.png │ ├── attackTable.png │ ├── bankGenerator.png │ ├── bankInfo.png │ ├── bankWaveMapper.png │ ├── createStream.png │ ├── createWave.png │ ├── dataGrid.png │ ├── decayReleaseTable.png │ ├── editMenu.png │ ├── fileMenu.png │ ├── forceUniqueFile.png │ ├── groupInfo.png │ ├── helpMenu.png │ ├── instrumentInfo.png │ ├── itemIndex.png │ ├── itemIndexPanel.png │ ├── itemInfo.png │ ├── itemInfoPanel.png │ ├── itemTree.png │ ├── mainMenu.png │ ├── openSequenceArchiveFile.png │ ├── piano.png │ ├── saveWarning.png │ ├── sequenceInfo.png │ ├── sequencePlayerInfo.png │ ├── settings.png │ ├── soundPlayer.png │ ├── statusBar.png │ ├── streamInfo.png │ ├── streamPlayerInfo.png │ ├── toolsMenu.png │ ├── waveArchiveInfo.png │ ├── waveArchiveList.png │ ├── windowBar.png │ └── windowLayout.png ├── sequenceArchiveEditor.md ├── sequenceCommands.md ├── sequenceEditor.md ├── sf2DlsImporter.md ├── soundArchive.md ├── streamCreator.md ├── waveArchiveEditor.md └── waveCreator.md ├── index.md └── specs ├── bank.md ├── common.md ├── sequence.md ├── sequenceArchive.md ├── soundData.md ├── stream.md ├── wave.md └── waveArchive.md /Image/Ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Ico.png -------------------------------------------------------------------------------- /Image/Krystal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Krystal.png -------------------------------------------------------------------------------- /Image/Menu/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/close.png -------------------------------------------------------------------------------- /Image/Menu/export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/export.png -------------------------------------------------------------------------------- /Image/Menu/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/help.png -------------------------------------------------------------------------------- /Image/Menu/iconSet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/iconSet.png -------------------------------------------------------------------------------- /Image/Menu/import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/import.png -------------------------------------------------------------------------------- /Image/Menu/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/new.png -------------------------------------------------------------------------------- /Image/Menu/nsm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/nsm.png -------------------------------------------------------------------------------- /Image/Menu/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/open.png -------------------------------------------------------------------------------- /Image/Menu/quitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/quitter.png -------------------------------------------------------------------------------- /Image/Menu/rename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/rename.png -------------------------------------------------------------------------------- /Image/Menu/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/save.png -------------------------------------------------------------------------------- /Image/Menu/saveAs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Menu/saveAs.png -------------------------------------------------------------------------------- /Image/Track/Idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Track/Idle.png -------------------------------------------------------------------------------- /Image/Track/Mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Track/Mute.png -------------------------------------------------------------------------------- /Image/Track/NoteDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Track/NoteDown.png -------------------------------------------------------------------------------- /Image/Tree/FILES.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/FILES.png -------------------------------------------------------------------------------- /Image/Tree/bank.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/bank.ico -------------------------------------------------------------------------------- /Image/Tree/bank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/bank.png -------------------------------------------------------------------------------- /Image/Tree/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/blank.png -------------------------------------------------------------------------------- /Image/Tree/group.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/group.ico -------------------------------------------------------------------------------- /Image/Tree/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/group.png -------------------------------------------------------------------------------- /Image/Tree/lookup.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/lookup.ico -------------------------------------------------------------------------------- /Image/Tree/lookup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/lookup.png -------------------------------------------------------------------------------- /Image/Tree/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/player.png -------------------------------------------------------------------------------- /Image/Tree/psg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/psg.png -------------------------------------------------------------------------------- /Image/Tree/ranged.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/ranged.png -------------------------------------------------------------------------------- /Image/Tree/record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/record.png -------------------------------------------------------------------------------- /Image/Tree/recordArc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/recordArc.ico -------------------------------------------------------------------------------- /Image/Tree/recordArc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/recordArc.png -------------------------------------------------------------------------------- /Image/Tree/recordRegion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/recordRegion.png -------------------------------------------------------------------------------- /Image/Tree/regional.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/regional.png -------------------------------------------------------------------------------- /Image/Tree/seqArc.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/seqArc.ico -------------------------------------------------------------------------------- /Image/Tree/seqArc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/seqArc.png -------------------------------------------------------------------------------- /Image/Tree/sseq.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/sseq.ico -------------------------------------------------------------------------------- /Image/Tree/sseq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/sseq.png -------------------------------------------------------------------------------- /Image/Tree/streamPlayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/streamPlayer.png -------------------------------------------------------------------------------- /Image/Tree/strm.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/strm.ico -------------------------------------------------------------------------------- /Image/Tree/strm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/strm.png -------------------------------------------------------------------------------- /Image/Tree/version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/version.png -------------------------------------------------------------------------------- /Image/Tree/wave.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/wave.ico -------------------------------------------------------------------------------- /Image/Tree/wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/wave.png -------------------------------------------------------------------------------- /Image/Tree/waveArchive.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/waveArchive.ico -------------------------------------------------------------------------------- /Image/Tree/waveArchive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/waveArchive.png -------------------------------------------------------------------------------- /Image/Tree/whiteNoise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/Tree/whiteNoise.png -------------------------------------------------------------------------------- /Image/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/icon.ico -------------------------------------------------------------------------------- /Image/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Image/icon.png -------------------------------------------------------------------------------- /InstallerFolderPermissions/Installer1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace InstallerFolderPermissions { 2 | partial class Installer1 { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose(bool disposing) { 13 | if (disposing && (components != null)) { 14 | components.Dispose(); 15 | } 16 | base.Dispose(disposing); 17 | } 18 | 19 | #region Component Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | components = new System.ComponentModel.Container(); 27 | } 28 | 29 | #endregion 30 | } 31 | } -------------------------------------------------------------------------------- /InstallerFolderPermissions/Installer1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Configuration.Install; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Security.AccessControl; 9 | using System.Security.Principal; 10 | using System.Threading.Tasks; 11 | 12 | namespace InstallerFolderPermissions { 13 | [RunInstaller(true)] 14 | public partial class Installer1 : Installer { 15 | public Installer1() { 16 | InitializeComponent(); 17 | } 18 | public override void Install(IDictionary stateSaver) { 19 | // This gets the named parameters passed in from your custom action 20 | string folder = Context.Parameters["folder"]; 21 | 22 | // This gets the "Authenticated Users" group, no matter what it's called 23 | SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null); 24 | 25 | // Create the rules 26 | FileSystemAccessRule writerule = new FileSystemAccessRule(sid, FileSystemRights.Write, AccessControlType.Allow); 27 | 28 | if (!string.IsNullOrEmpty(folder) && Directory.Exists(folder)) { 29 | // Get your file's ACL 30 | DirectorySecurity fsecurity = Directory.GetAccessControl(folder); 31 | 32 | // Add the new rule to the ACL 33 | fsecurity.AddAccessRule(writerule); 34 | 35 | // Set the ACL back to the file 36 | Directory.SetAccessControl(folder, fsecurity); 37 | } 38 | 39 | // Explicitly call the overriden method to properly return control to the installer 40 | base.Install(stateSaver); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /InstallerFolderPermissions/InstallerFolderPermissions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DBF81EB2-7016-465B-8A95-3F376E439DB0} 8 | Library 9 | Properties 10 | InstallerFolderPermissions 11 | InstallerFolderPermissions 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Component 48 | 49 | 50 | Installer1.cs 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /InstallerFolderPermissions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("InstallerFolderPermissions")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("InstallerFolderPermissions")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dbf81eb2-7016-465b-8a95-3f376e439db0")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Nitro Studio 2.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29102.190 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nitro Studio 2", "Nitro Studio 2\Nitro Studio 2.csproj", "{BF551FB5-A4CE-4F6D-A8F1-3893302F4581}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NitroFileLoader", "NitroFileLoader\NitroFileLoader.csproj", "{132D5DA0-BD98-4FCB-9A9C-73556C16B2C0}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GotaSoundIO", "..\GotaSoundIO\GotaSoundIO.csproj", "{F0BCD085-9DC4-4B22-B791-C725CA8E46F6}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GotaSequenceLib", "..\GotaSequenceLib\GotaSequenceLib.csproj", "{D06E248A-EF7A-4F1E-9A71-76204D61FF80}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GotaSoundBank", "..\GotaSoundBank\GotaSoundBank.csproj", "{2642E217-5595-4E4B-9B6D-F5CFD937EB25}" 15 | EndProject 16 | Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "NitroStudio2Installer", "NitroStudio2Installer\NitroStudio2Installer.vdproj", "{BD16D3DB-EEE2-40D1-B1D9-B28F60BDBF62}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstallerFolderPermissions", "InstallerFolderPermissions\InstallerFolderPermissions.csproj", "{DBF81EB2-7016-465B-8A95-3F376E439DB0}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {BF551FB5-A4CE-4F6D-A8F1-3893302F4581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {BF551FB5-A4CE-4F6D-A8F1-3893302F4581}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {BF551FB5-A4CE-4F6D-A8F1-3893302F4581}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {BF551FB5-A4CE-4F6D-A8F1-3893302F4581}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {132D5DA0-BD98-4FCB-9A9C-73556C16B2C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {132D5DA0-BD98-4FCB-9A9C-73556C16B2C0}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {132D5DA0-BD98-4FCB-9A9C-73556C16B2C0}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {132D5DA0-BD98-4FCB-9A9C-73556C16B2C0}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {F0BCD085-9DC4-4B22-B791-C725CA8E46F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {F0BCD085-9DC4-4B22-B791-C725CA8E46F6}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {F0BCD085-9DC4-4B22-B791-C725CA8E46F6}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {F0BCD085-9DC4-4B22-B791-C725CA8E46F6}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {D06E248A-EF7A-4F1E-9A71-76204D61FF80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {D06E248A-EF7A-4F1E-9A71-76204D61FF80}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {D06E248A-EF7A-4F1E-9A71-76204D61FF80}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {D06E248A-EF7A-4F1E-9A71-76204D61FF80}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {2642E217-5595-4E4B-9B6D-F5CFD937EB25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {2642E217-5595-4E4B-9B6D-F5CFD937EB25}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {2642E217-5595-4E4B-9B6D-F5CFD937EB25}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {2642E217-5595-4E4B-9B6D-F5CFD937EB25}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {BD16D3DB-EEE2-40D1-B1D9-B28F60BDBF62}.Debug|Any CPU.ActiveCfg = Debug 47 | {BD16D3DB-EEE2-40D1-B1D9-B28F60BDBF62}.Release|Any CPU.ActiveCfg = Release 48 | {DBF81EB2-7016-465B-8A95-3F376E439DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {DBF81EB2-7016-465B-8A95-3F376E439DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {DBF81EB2-7016-465B-8A95-3F376E439DB0}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {DBF81EB2-7016-465B-8A95-3F376E439DB0}.Release|Any CPU.Build.0 = Release|Any CPU 52 | EndGlobalSection 53 | GlobalSection(SolutionProperties) = preSolution 54 | HideSolutionNode = FALSE 55 | EndGlobalSection 56 | GlobalSection(ExtensibilityGlobals) = postSolution 57 | SolutionGuid = {92AD1E7F-9A75-4B4E-9721-265524A1A944} 58 | EndGlobalSection 59 | EndGlobal 60 | -------------------------------------------------------------------------------- /Nitro Studio 2/AboutWindow.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace NitroStudio2 2 | { 3 | partial class AboutWindow 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutWindow)); 32 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.textBox1 = new System.Windows.Forms.TextBox(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // pictureBox1 39 | // 40 | this.pictureBox1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.BackgroundImage"))); 41 | this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 42 | this.pictureBox1.Location = new System.Drawing.Point(240, 9); 43 | this.pictureBox1.Name = "pictureBox1"; 44 | this.pictureBox1.Size = new System.Drawing.Size(182, 330); 45 | this.pictureBox1.TabIndex = 0; 46 | this.pictureBox1.TabStop = false; 47 | // 48 | // label1 49 | // 50 | this.label1.AutoSize = true; 51 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 52 | this.label1.Location = new System.Drawing.Point(77, 9); 53 | this.label1.Name = "label1"; 54 | this.label1.Size = new System.Drawing.Size(90, 33); 55 | this.label1.TabIndex = 1; 56 | this.label1.Text = "About"; 57 | this.label1.Click += new System.EventHandler(this.label1_Click); 58 | // 59 | // textBox1 60 | // 61 | this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 62 | | System.Windows.Forms.AnchorStyles.Left))); 63 | this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; 64 | this.textBox1.Cursor = System.Windows.Forms.Cursors.Default; 65 | this.textBox1.Enabled = false; 66 | this.textBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 67 | this.textBox1.Location = new System.Drawing.Point(5, 61); 68 | this.textBox1.Multiline = true; 69 | this.textBox1.Name = "textBox1"; 70 | this.textBox1.ReadOnly = true; 71 | this.textBox1.RightToLeft = System.Windows.Forms.RightToLeft.No; 72 | this.textBox1.Size = new System.Drawing.Size(230, 287); 73 | this.textBox1.TabIndex = 2; 74 | this.textBox1.Text = resources.GetString("textBox1.Text"); 75 | this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; 76 | this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged); 77 | // 78 | // AboutWindow 79 | // 80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 81 | this.AutoValidate = System.Windows.Forms.AutoValidate.Disable; 82 | this.ClientSize = new System.Drawing.Size(434, 341); 83 | this.Controls.Add(this.textBox1); 84 | this.Controls.Add(this.label1); 85 | this.Controls.Add(this.pictureBox1); 86 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 87 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 88 | this.ImeMode = System.Windows.Forms.ImeMode.Disable; 89 | this.MaximizeBox = false; 90 | this.MinimizeBox = false; 91 | this.Name = "AboutWindow"; 92 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 93 | this.Text = "About Nitro Studio 2"; 94 | this.Load += new System.EventHandler(this.AboutWindow_Load); 95 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 96 | this.ResumeLayout(false); 97 | this.PerformLayout(); 98 | 99 | } 100 | 101 | #endregion 102 | 103 | private System.Windows.Forms.PictureBox pictureBox1; 104 | private System.Windows.Forms.Label label1; 105 | private System.Windows.Forms.TextBox textBox1; 106 | } 107 | } -------------------------------------------------------------------------------- /Nitro Studio 2/AboutWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace NitroStudio2 12 | { 13 | public partial class AboutWindow : Form 14 | { 15 | public AboutWindow() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | private void label1_Click(object sender, EventArgs e) 21 | { 22 | 23 | } 24 | 25 | private void textBox1_TextChanged(object sender, EventArgs e) 26 | { 27 | 28 | } 29 | 30 | private void AboutWindow_Load(object sender, EventArgs e) { 31 | 32 | } 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Nitro Studio 2/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Nitro Studio 2/AxInterop.WMPLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/AxInterop.WMPLib.dll -------------------------------------------------------------------------------- /Nitro Studio 2/CreateStreamTool.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.Sound; 2 | using NitroFileLoader; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Data; 7 | using System.Drawing; 8 | using System.IO; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using System.Windows.Forms; 13 | 14 | namespace NitroStudio2 { 15 | public partial class CreateStreamTool : Form { 16 | 17 | /// 18 | /// Swav mode. 19 | /// 20 | bool SwavMode; 21 | 22 | public CreateStreamTool(bool swavMode) { 23 | InitializeComponent(); 24 | outputFormat.SelectedIndex = 2; 25 | SwavMode = swavMode; 26 | if (SwavMode) { 27 | Text = "Create Wave"; 28 | Icon = Properties.Resources.Wav; 29 | } 30 | } 31 | 32 | private void impFileButton_Click(object sender, EventArgs e) { 33 | OpenFileDialog o = new OpenFileDialog(); 34 | o.RestoreDirectory = true; 35 | o.Filter = "Supported Sound Files|*.wav;*.swav;*.strm"; 36 | o.ShowDialog(); 37 | if (o.FileName != "") { 38 | impFileBox.Text = o.FileName; 39 | impFileBox.SelectionStart = outFileBox.Text.Length; 40 | impFileBox.ScrollToCaret(); 41 | impFileBox.Refresh(); 42 | } 43 | } 44 | 45 | private void outFileButton_Click(object sender, EventArgs e) { 46 | SaveFileDialog s = new SaveFileDialog(); 47 | s.RestoreDirectory = true; 48 | s.Filter = SwavMode ? "Sound Wave|*.swav" : "Sound Stream|*.strm"; 49 | s.ShowDialog(); 50 | if (s.FileName != "") { 51 | outFileBox.Text = s.FileName; 52 | outFileBox.SelectionStart = outFileBox.Text.Length; 53 | outFileBox.ScrollToCaret(); 54 | outFileBox.Refresh(); 55 | } 56 | } 57 | 58 | private void exportButton_Click(object sender, EventArgs e) { 59 | 60 | //Test. 61 | if (impFileBox.Text.Equals("")) { 62 | MessageBox.Show("No Input File Selected!"); 63 | return; 64 | } 65 | if (outFileBox.Text.Equals("")) { 66 | MessageBox.Show("No Output File Selected!"); 67 | return; 68 | } 69 | 70 | //Sound file. 71 | SoundFile s; 72 | if (SwavMode) { 73 | s = new Wave(); 74 | } else { 75 | s = new NitroFileLoader.Stream(); 76 | } 77 | 78 | //Switch input file. 79 | SoundFile i; 80 | switch (Path.GetExtension(impFileBox.Text)) { 81 | case ".swav": 82 | i = new Wave(); 83 | break; 84 | case ".strm": 85 | i = new NitroFileLoader.Stream(); 86 | break; 87 | default: 88 | i = new RiffWave(); 89 | break; 90 | } 91 | i.Read(impFileBox.Text); 92 | 93 | //Get conversion type. 94 | Type convType; 95 | switch (outputFormat.SelectedIndex) { 96 | case 0: 97 | convType = typeof(PCM8Signed); 98 | break; 99 | case 1: 100 | convType = typeof(PCM16); 101 | break; 102 | default: 103 | convType = typeof(ImaAdpcm); 104 | break; 105 | } 106 | 107 | //Convert the file. 108 | s.FromOtherStreamFile(i, convType); 109 | 110 | //Save the file. 111 | s.Write(outFileBox.Text); 112 | 113 | } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Nitro Studio 2/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/DutyCycle1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/DutyCycle1.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/DutyCycle2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/DutyCycle2.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/DutyCycle3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/DutyCycle3.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/DutyCycle4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/DutyCycle4.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/DutyCycle5.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/DutyCycle5.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/DutyCycle6.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/DutyCycle6.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/DutyCycle7.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/DutyCycle7.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/Null.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/Null.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Hardware/WhiteNoise.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Hardware/WhiteNoise.wav -------------------------------------------------------------------------------- /Nitro Studio 2/Instrument Selector.cs: -------------------------------------------------------------------------------- 1 | using GotaSequenceLib.Playback; 2 | using GotaSoundIO.Sound; 3 | using NitroFileLoader; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.ComponentModel; 7 | using System.Data; 8 | using System.Drawing; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using System.Windows.Forms; 13 | 14 | namespace NitroStudio2 { 15 | public partial class InstrumentSelector : Form { 16 | 17 | /// 18 | /// Selected instruments. 19 | /// 20 | public List SelectedInstruments = null; 21 | 22 | /// 23 | /// Waves. 24 | /// 25 | private List wavs = new List(); 26 | 27 | /// 28 | /// Player. 29 | /// 30 | public Player Player; 31 | 32 | /// 33 | /// Mixer. 34 | /// 35 | public Mixer Mixer = new Mixer(); 36 | 37 | /// 38 | /// Bank importer. 39 | /// 40 | /// Waves. 41 | /// Ids. 42 | /// Names. 43 | public InstrumentSelector(List waves, List insts, List names) { 44 | 45 | //Init. 46 | InitializeComponent(); 47 | instGrid.CellContentClick += new DataGridViewCellEventHandler(PlayRegionButtonClick); 48 | wavs = waves; 49 | Player = new Player(Mixer); 50 | Player.PrepareForSong(new Bank[] { new Bank() { Instruments = new List() { new DirectInstrument() { Index = 0, NoteInfo = new List() { new NoteInfo() { Key = GotaSequenceLib.Notes.gn9 } } } } } }, new RiffWave[][] { new RiffWave[1] }); 51 | Player.LoadSong(new List() { new GotaSequenceLib.SequenceCommand() { CommandType = GotaSequenceLib.SequenceCommands.ProgramChange, Parameter = (uint)0 }, new GotaSequenceLib.SequenceCommand() { CommandType = GotaSequenceLib.SequenceCommands.Note, Parameter = new GotaSequenceLib.NoteParameter() { Note = GotaSequenceLib.Notes.cn4, Length = 48 * 2, Velocity = 127 } }, new GotaSequenceLib.SequenceCommand() { CommandType = GotaSequenceLib.SequenceCommands.Fin }}); 52 | FormClosing += new FormClosingEventHandler(OnClosing); 53 | 54 | //Add instruments. 55 | int ind = 0; 56 | foreach (var inst in insts) { 57 | instGrid.Rows.Add(new DataGridViewRow()); 58 | var v = instGrid.Rows[instGrid.Rows.Count - 1]; 59 | ((DataGridViewTextBoxCell)v.Cells[1]).Value = inst; 60 | string name = "Instrument " + inst; 61 | try { name = names[ind]; } catch { } 62 | ind++; 63 | ((DataGridViewTextBoxCell)v.Cells[2]).Value = name; 64 | ((DataGridViewCheckBoxCell)v.Cells[3]).Value = true; 65 | } 66 | 67 | } 68 | 69 | /// 70 | /// Finished. 71 | /// 72 | private void finishedButton_Click(object sender, EventArgs e) { 73 | SelectedInstruments = new List(); 74 | foreach (DataGridViewRow r in instGrid.Rows) { 75 | if ((bool)((DataGridViewCheckBoxCell)r.Cells[3]).Value) { 76 | SelectedInstruments.Add(int.Parse(r.Cells[1].Value.ToString())); 77 | } 78 | } 79 | Close(); 80 | } 81 | 82 | /// 83 | /// Play region button. 84 | /// 85 | public void PlayRegionButtonClick(object sender, DataGridViewCellEventArgs e) { 86 | if (e.ColumnIndex != 0 || e.RowIndex < 0) { 87 | return; 88 | } 89 | Player.Stop(); 90 | Player.WaveArchives[0][0] = wavs[e.RowIndex]; 91 | Player.Play(); 92 | } 93 | 94 | private void checkAllToolStripMenuItem_Click(object sender, EventArgs e) { 95 | foreach (DataGridViewRow r in instGrid.Rows) { 96 | r.Cells[3].Value = true; 97 | } 98 | } 99 | 100 | private void uncheckAllToolStripMenuItem_Click(object sender, EventArgs e) { 101 | foreach (DataGridViewRow r in instGrid.Rows) { 102 | r.Cells[3].Value = false; 103 | } 104 | } 105 | 106 | /// 107 | /// On closing. 108 | /// 109 | private void OnClosing(object sender, EventArgs e) { 110 | Mixer.Dispose(); 111 | Player.Dispose(); 112 | } 113 | 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Nitro Studio 2/Interop.WMPLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Interop.WMPLib.dll -------------------------------------------------------------------------------- /Nitro Studio 2/NitroStudioInstrument.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using NitroFileLoader; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows.Forms; 9 | 10 | namespace NitroStudio2 { 11 | 12 | /// 13 | /// Nitro Studio Instrument. 14 | /// 15 | public class NitroStudioInstrument : IOFile { 16 | 17 | /// 18 | /// Instrument. 19 | /// 20 | public Instrument Inst; 21 | 22 | /// 23 | /// Read the file. 24 | /// 25 | /// The reader. 26 | public override void Read(FileReader r) { 27 | 28 | //Skip header. 29 | r.ReadUInt32(); 30 | 31 | //Get type. 32 | byte type = r.ReadByte(); 33 | switch ((InstrumentType)type) { 34 | case InstrumentType.Blank: 35 | break; 36 | case InstrumentType.DrumSet: 37 | Inst = new DrumSetInstrument(); 38 | break; 39 | case InstrumentType.KeySplit: 40 | Inst = new KeySplitInstrument(); 41 | break; 42 | default: 43 | Inst = new DirectInstrument(); 44 | break; 45 | } 46 | 47 | //Placeholder. 48 | if (r.ReadBoolean()) { 49 | MessageBox.Show("An empty instrument cannot be used!"); 50 | return; 51 | } 52 | 53 | //Read data. 54 | Inst.Read(r); 55 | if (Inst as DirectInstrument != null) { 56 | Inst.NoteInfo[0].InstrumentType = (InstrumentType)type; 57 | } 58 | 59 | } 60 | 61 | /// 62 | /// Write the file. 63 | /// 64 | /// The writer. 65 | public override void Write(FileWriter w) { 66 | 67 | //Write header. 68 | w.Write("NIST".ToCharArray()); 69 | w.Write((byte)(Inst == null ? 0 : Inst.Type())); 70 | w.Write(Inst == null); 71 | if (Inst != null) { w.Write(Inst); } 72 | 73 | } 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /Nitro Studio 2/Program.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundBank.DLS; 2 | using GotaSoundBank.SF2; 3 | using GotaSoundIO.Sound; 4 | using NitroFileLoader; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | namespace NitroStudio2 { 13 | static class Program { 14 | 15 | /// 16 | /// Path. 17 | /// 18 | public static string NitroPath = Application.StartupPath; 19 | 20 | /// 21 | /// The main entry point for the application. 22 | /// 23 | [STAThread] 24 | static void Main(string[] args) { 25 | 26 | //Start. 27 | Application.EnableVisualStyles(); 28 | Application.SetCompatibleTextRenderingDefault(false); 29 | 30 | //Argument mode. 31 | if (args.Length > 0) { 32 | 33 | //Switch type. 34 | switch (Path.GetExtension(args[0])) { 35 | 36 | //Sound archive. 37 | case ".sdat": 38 | Application.Run(new MainWindow(args[0])); 39 | break; 40 | 41 | //Sound sequence. 42 | case ".sseq": 43 | Application.Run(new SequenceEditor(args[0])); 44 | break; 45 | 46 | //Sound archive. 47 | case ".ssar": 48 | Application.Run(new SequenceArchiveEditor(args[0])); 49 | break; 50 | 51 | //Sound bank. 52 | case ".sbnk": 53 | Application.Run(new BankEditor(args[0])); 54 | break; 55 | 56 | //Sound wave archive. 57 | case ".swar": 58 | Application.Run(new WaveArchiveEditor(args[0])); 59 | break; 60 | 61 | //Stream. 62 | case ".strm": 63 | RiffWave r = new RiffWave(); 64 | NitroFileLoader.Stream s = new NitroFileLoader.Stream(); 65 | s.Read(args[0]); 66 | r.FromOtherStreamFile(s); 67 | r.Write(MainWindow.NitroPath + "/" + "tmpStream" + 0 + ".wav"); 68 | Application.Run(new StreamPlayer(null, MainWindow.NitroPath + "/" + "tmpStream" + 0 + ".wav", Path.GetFileNameWithoutExtension(args[0]))); 69 | break; 70 | 71 | } 72 | 73 | } else { 74 | 75 | //Start the editor. 76 | Application.Run(new MainWindow()); 77 | 78 | } 79 | 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Nitro Studio 2/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Nitro Studio 2")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Nitro Studio 2")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bf551fb5-a4ce-4f6d-a8f1-3893302f4581")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Nitro Studio 2/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace NitroStudio2.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Nitro Studio 2/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/Ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/Ico.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/Idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/Idle.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/Mute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/Mute.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/NoteDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/NoteDown.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/War.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/War.ico -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/bank.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/bank.ico -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/bank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/bank.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/close.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/export.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/help.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/icon.ico -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/icon.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/import.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/new.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/nsm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/nsm.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/open.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/quitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/quitter.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/rename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/rename.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/save.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/saveAs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/saveAs.png -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/sseq.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/sseq.ico -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/wave.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/wave.ico -------------------------------------------------------------------------------- /Nitro Studio 2/Resources/waveArchive.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Resources/waveArchive.ico -------------------------------------------------------------------------------- /Nitro Studio 2/SaveCloseDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace NitroStudio2 2 | { 3 | partial class SaveCloseDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.label1 = new System.Windows.Forms.Label(); 32 | this.CancelButton = new System.Windows.Forms.Button(); 33 | this.NoButton = new System.Windows.Forms.Button(); 34 | this.YesButton = new System.Windows.Forms.Button(); 35 | this.SuspendLayout(); 36 | // 37 | // label1 38 | // 39 | this.label1.AutoSize = true; 40 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 41 | this.label1.Location = new System.Drawing.Point(46, 9); 42 | this.label1.Name = "label1"; 43 | this.label1.Size = new System.Drawing.Size(226, 13); 44 | this.label1.TabIndex = 1; 45 | this.label1.Text = "Do you want to save before you close the file?\r\n"; 46 | // 47 | // CancelButton 48 | // 49 | this.CancelButton.Location = new System.Drawing.Point(214, 47); 50 | this.CancelButton.Name = "CancelButton"; 51 | this.CancelButton.Size = new System.Drawing.Size(95, 30); 52 | this.CancelButton.TabIndex = 6; 53 | this.CancelButton.Text = "Cancel"; 54 | this.CancelButton.UseVisualStyleBackColor = true; 55 | this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); 56 | // 57 | // NoButton 58 | // 59 | this.NoButton.Location = new System.Drawing.Point(113, 47); 60 | this.NoButton.Name = "NoButton"; 61 | this.NoButton.Size = new System.Drawing.Size(95, 30); 62 | this.NoButton.TabIndex = 5; 63 | this.NoButton.Text = "Close"; 64 | this.NoButton.UseVisualStyleBackColor = true; 65 | this.NoButton.Click += new System.EventHandler(this.NoButton_Click); 66 | // 67 | // YesButton 68 | // 69 | this.YesButton.Location = new System.Drawing.Point(12, 47); 70 | this.YesButton.Name = "YesButton"; 71 | this.YesButton.Size = new System.Drawing.Size(95, 30); 72 | this.YesButton.TabIndex = 4; 73 | this.YesButton.Text = "Save and Close"; 74 | this.YesButton.UseVisualStyleBackColor = true; 75 | this.YesButton.Click += new System.EventHandler(this.YesButton_Click); 76 | // 77 | // SaveCloseDialog 78 | // 79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 81 | this.ClientSize = new System.Drawing.Size(320, 87); 82 | this.ControlBox = false; 83 | this.Controls.Add(this.CancelButton); 84 | this.Controls.Add(this.NoButton); 85 | this.Controls.Add(this.YesButton); 86 | this.Controls.Add(this.label1); 87 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 88 | this.MaximizeBox = false; 89 | this.MinimizeBox = false; 90 | this.Name = "SaveCloseDialog"; 91 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 92 | this.Text = "Warning"; 93 | this.Load += new System.EventHandler(this.SaveCloseDialog_Load); 94 | this.ResumeLayout(false); 95 | this.PerformLayout(); 96 | 97 | } 98 | 99 | #endregion 100 | 101 | private System.Windows.Forms.Label label1; 102 | private System.Windows.Forms.Button CancelButton; 103 | private System.Windows.Forms.Button NoButton; 104 | private System.Windows.Forms.Button YesButton; 105 | } 106 | } -------------------------------------------------------------------------------- /Nitro Studio 2/SaveCloseDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace NitroStudio2 12 | { 13 | public partial class SaveCloseDialog : Form 14 | { 15 | public SaveCloseDialog() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | int returnValue = 0; 21 | 22 | private void SaveCloseDialog_Load(object sender, EventArgs e) 23 | { 24 | 25 | } 26 | 27 | private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 28 | { 29 | } 30 | 31 | private void YesButton_Click(object sender, EventArgs e) 32 | { 33 | returnValue = 0; 34 | this.Close(); 35 | } 36 | 37 | private void NoButton_Click(object sender, EventArgs e) 38 | { 39 | returnValue = 1; 40 | this.Close(); 41 | } 42 | 43 | private void CancelButton_Click(object sender, EventArgs e) 44 | { 45 | returnValue = 2; 46 | this.Close(); 47 | } 48 | 49 | 50 | public int getValue() { 51 | 52 | this.ShowDialog(); 53 | return returnValue; 54 | 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Nitro Studio 2/SaveCloseDialog.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /Nitro Studio 2/SaveQuitDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace NitroStudio2 2 | { 3 | partial class SaveQuitDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.label1 = new System.Windows.Forms.Label(); 32 | this.YesButton = new System.Windows.Forms.Button(); 33 | this.NoButton = new System.Windows.Forms.Button(); 34 | this.CancelButton = new System.Windows.Forms.Button(); 35 | this.SuspendLayout(); 36 | // 37 | // label1 38 | // 39 | this.label1.AutoSize = true; 40 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 41 | this.label1.Location = new System.Drawing.Point(73, 9); 42 | this.label1.Name = "label1"; 43 | this.label1.Size = new System.Drawing.Size(183, 13); 44 | this.label1.TabIndex = 0; 45 | this.label1.Text = "Do you want to save before you exit?\r\n"; 46 | // 47 | // YesButton 48 | // 49 | this.YesButton.Location = new System.Drawing.Point(12, 47); 50 | this.YesButton.Name = "YesButton"; 51 | this.YesButton.Size = new System.Drawing.Size(95, 30); 52 | this.YesButton.TabIndex = 1; 53 | this.YesButton.Text = "Save and Quit"; 54 | this.YesButton.UseVisualStyleBackColor = true; 55 | this.YesButton.Click += new System.EventHandler(this.YesButton_Click); 56 | // 57 | // NoButton 58 | // 59 | this.NoButton.Location = new System.Drawing.Point(113, 47); 60 | this.NoButton.Name = "NoButton"; 61 | this.NoButton.Size = new System.Drawing.Size(95, 30); 62 | this.NoButton.TabIndex = 2; 63 | this.NoButton.Text = "Quit"; 64 | this.NoButton.UseVisualStyleBackColor = true; 65 | this.NoButton.Click += new System.EventHandler(this.NoButton_Click); 66 | // 67 | // CancelButton 68 | // 69 | this.CancelButton.Location = new System.Drawing.Point(214, 47); 70 | this.CancelButton.Name = "CancelButton"; 71 | this.CancelButton.Size = new System.Drawing.Size(95, 30); 72 | this.CancelButton.TabIndex = 3; 73 | this.CancelButton.Text = "Cancel"; 74 | this.CancelButton.UseVisualStyleBackColor = true; 75 | this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); 76 | // 77 | // SaveQuitDialog 78 | // 79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 81 | this.ClientSize = new System.Drawing.Size(320, 87); 82 | this.Controls.Add(this.CancelButton); 83 | this.Controls.Add(this.NoButton); 84 | this.Controls.Add(this.YesButton); 85 | this.Controls.Add(this.label1); 86 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 87 | this.MaximizeBox = false; 88 | this.MinimizeBox = false; 89 | this.Name = "SaveQuitDialog"; 90 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 91 | this.Text = "Warning"; 92 | this.Load += new System.EventHandler(this.SaveQuitDialog_Load); 93 | this.ResumeLayout(false); 94 | this.PerformLayout(); 95 | 96 | } 97 | 98 | #endregion 99 | 100 | private System.Windows.Forms.Label label1; 101 | private System.Windows.Forms.Button YesButton; 102 | private System.Windows.Forms.Button NoButton; 103 | private System.Windows.Forms.Button CancelButton; 104 | } 105 | } -------------------------------------------------------------------------------- /Nitro Studio 2/SaveQuitDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace NitroStudio2 { 5 | public partial class SaveQuitDialog : Form 6 | { 7 | 8 | EditorBase parentTwo; 9 | 10 | public SaveQuitDialog(EditorBase parent2) 11 | { 12 | InitializeComponent(); 13 | parentTwo = parent2; 14 | } 15 | 16 | private void SaveQuitDialog_Load(object sender, EventArgs e) 17 | { 18 | 19 | } 20 | 21 | private void CancelButton_Click(object sender, EventArgs e) 22 | { 23 | this.Close(); 24 | } 25 | 26 | private void NoButton_Click(object sender, EventArgs e) 27 | { 28 | try { parentTwo.Close(); } catch { } 29 | } 30 | 31 | private void YesButton_Click(object sender, EventArgs e) 32 | { 33 | //Save application 34 | //try { parent.save(); } catch { } 35 | //try { parentTwo.save(); } catch { } 36 | try { parentTwo.saveToolStripMenuItem_Click(sender, e); } catch { } 37 | 38 | //Exit application 39 | try { parentTwo.Close(); } catch { } 40 | 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Nitro Studio 2/SaveQuitDialog.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | -------------------------------------------------------------------------------- /Nitro Studio 2/SequenceRecorder.cs: -------------------------------------------------------------------------------- 1 | using GotaSequenceLib; 2 | using GotaSequenceLib.Playback; 3 | using GotaSoundIO.Sound; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.ComponentModel; 7 | using System.Data; 8 | using System.Drawing; 9 | using System.Linq; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using System.Windows.Forms; 13 | 14 | namespace NitroStudio2 { 15 | public partial class SequenceRecorder : Form { 16 | 17 | /// 18 | /// Mixer. 19 | /// 20 | public Mixer Mixer = new Mixer(); 21 | 22 | /// 23 | /// Player. 24 | /// 25 | Player Player; 26 | 27 | /// 28 | /// Commands. 29 | /// 30 | private List commands; 31 | 32 | /// 33 | /// Sequence start. 34 | /// 35 | private int seqStart; 36 | 37 | /// 38 | /// File path. 39 | /// 40 | private string filePath; 41 | 42 | /// 43 | /// Create a new sequence recorder. 44 | /// 45 | /// The banks. 46 | /// Wave archives. 47 | /// Sequence commands. 48 | /// Start index. 49 | public SequenceRecorder(PlayableBank[] banks, RiffWave[][] wars, List commands, int startIndex, string filePath) { 50 | 51 | //Init. 52 | InitializeComponent(); 53 | 54 | //Load stuff. 55 | Player = new Player(Mixer); 56 | Player.PrepareForSong(banks, wars); 57 | this.commands = commands; 58 | this.seqStart = startIndex; 59 | this.filePath = filePath; 60 | 61 | } 62 | 63 | /// 64 | /// Record the sequence. 65 | /// 66 | private void exportButton_Click(object sender, EventArgs e) { 67 | 68 | //Save. 69 | Player.LoadSong(commands, seqStart); 70 | Player.NumLoops = (long)loopsBox.Value; 71 | Player.DontFadeSong = !fadeBox.Checked; 72 | Player.Record(filePath); 73 | Close(); 74 | 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Nitro Studio 2/StreamPlayer.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace NitroStudio2 { 2 | partial class StreamPlayer { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose(bool disposing) { 13 | if (disposing && (components != null)) { 14 | components.Dispose(); 15 | } 16 | base.Dispose(disposing); 17 | } 18 | 19 | #region Windows Form Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(StreamPlayer)); 27 | this.wmp = new AxWMPLib.AxWindowsMediaPlayer(); 28 | ((System.ComponentModel.ISupportInitialize)(this.wmp)).BeginInit(); 29 | this.SuspendLayout(); 30 | // 31 | // wmp 32 | // 33 | this.wmp.Dock = System.Windows.Forms.DockStyle.Fill; 34 | this.wmp.Enabled = true; 35 | this.wmp.Location = new System.Drawing.Point(0, 0); 36 | this.wmp.Name = "wmp"; 37 | this.wmp.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("wmp.OcxState"))); 38 | this.wmp.Size = new System.Drawing.Size(632, 317); 39 | this.wmp.TabIndex = 0; 40 | // 41 | // StreamPlayer 42 | // 43 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 44 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 45 | this.ClientSize = new System.Drawing.Size(632, 317); 46 | this.Controls.Add(this.wmp); 47 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 48 | this.Name = "StreamPlayer"; 49 | this.Text = "s"; 50 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.onClose); 51 | ((System.ComponentModel.ISupportInitialize)(this.wmp)).EndInit(); 52 | this.ResumeLayout(false); 53 | 54 | } 55 | 56 | #endregion 57 | 58 | internal AxWMPLib.AxWindowsMediaPlayer wmp; 59 | } 60 | } -------------------------------------------------------------------------------- /Nitro Studio 2/StreamPlayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | 13 | namespace NitroStudio2 { 14 | public partial class StreamPlayer : Form { 15 | public string Path; 16 | public MainWindow MainWindow; 17 | public StreamPlayer(MainWindow m, string path, string name) { 18 | InitializeComponent(); 19 | Text = "Stream Player - " + name + ".strm"; 20 | wmp.URL = path; 21 | Path = path; 22 | MainWindow = m; 23 | } 24 | private void onClose(object sender, EventArgs e) { 25 | Thread t = new Thread(delete); 26 | t.Start(); 27 | } 28 | private void delete() { 29 | File.Delete(Path); 30 | try { MainWindow.StreamTempCount--; } catch { } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Nitro Studio 2/Syroot.BinaryData.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/Syroot.BinaryData.dll -------------------------------------------------------------------------------- /Nitro Studio 2/WaveMapper.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace NitroStudio2 { 2 | partial class WaveMapper { 3 | /// 4 | /// Required designer variable. 5 | /// 6 | private System.ComponentModel.IContainer components = null; 7 | 8 | /// 9 | /// Clean up any resources being used. 10 | /// 11 | /// true if managed resources should be disposed; otherwise, false. 12 | protected override void Dispose(bool disposing) { 13 | if (disposing && (components != null)) { 14 | components.Dispose(); 15 | } 16 | base.Dispose(disposing); 17 | } 18 | 19 | #region Windows Form Designer generated code 20 | 21 | /// 22 | /// Required method for Designer support - do not modify 23 | /// the contents of this method with the code editor. 24 | /// 25 | private void InitializeComponent() { 26 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WaveMapper)); 27 | this.mapGrid = new System.Windows.Forms.DataGridView(); 28 | this.finishedButton = new System.Windows.Forms.Button(); 29 | this.playColumn = new System.Windows.Forms.DataGridViewButtonColumn(); 30 | this.waveId = new System.Windows.Forms.DataGridViewTextBoxColumn(); 31 | this.waveArchive = new System.Windows.Forms.DataGridViewComboBoxColumn(); 32 | ((System.ComponentModel.ISupportInitialize)(this.mapGrid)).BeginInit(); 33 | this.SuspendLayout(); 34 | // 35 | // mapGrid 36 | // 37 | this.mapGrid.AllowUserToAddRows = false; 38 | this.mapGrid.AllowUserToDeleteRows = false; 39 | this.mapGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 40 | | System.Windows.Forms.AnchorStyles.Left) 41 | | System.Windows.Forms.AnchorStyles.Right))); 42 | this.mapGrid.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 43 | this.mapGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 44 | this.mapGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 45 | this.playColumn, 46 | this.waveId, 47 | this.waveArchive}); 48 | this.mapGrid.Location = new System.Drawing.Point(12, 12); 49 | this.mapGrid.Name = "mapGrid"; 50 | this.mapGrid.Size = new System.Drawing.Size(541, 268); 51 | this.mapGrid.TabIndex = 0; 52 | // 53 | // finishedButton 54 | // 55 | this.finishedButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 56 | | System.Windows.Forms.AnchorStyles.Right))); 57 | this.finishedButton.Location = new System.Drawing.Point(12, 287); 58 | this.finishedButton.Name = "finishedButton"; 59 | this.finishedButton.Size = new System.Drawing.Size(541, 23); 60 | this.finishedButton.TabIndex = 1; 61 | this.finishedButton.Text = "Finished"; 62 | this.finishedButton.UseVisualStyleBackColor = true; 63 | this.finishedButton.Click += new System.EventHandler(this.finishedButton_Click); 64 | // 65 | // playColumn 66 | // 67 | this.playColumn.FillWeight = 57.19987F; 68 | this.playColumn.HeaderText = "Play Sample"; 69 | this.playColumn.Name = "playColumn"; 70 | this.playColumn.Text = "Play"; 71 | this.playColumn.UseColumnTextForButtonValue = true; 72 | // 73 | // waveId 74 | // 75 | this.waveId.FillWeight = 53.29949F; 76 | this.waveId.HeaderText = "Wave Id"; 77 | this.waveId.Name = "waveId"; 78 | this.waveId.ReadOnly = true; 79 | this.waveId.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; 80 | // 81 | // waveArchive 82 | // 83 | this.waveArchive.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 84 | this.waveArchive.FillWeight = 189.5006F; 85 | this.waveArchive.HeaderText = "Wave Archive"; 86 | this.waveArchive.Name = "waveArchive"; 87 | // 88 | // WaveMapper 89 | // 90 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 91 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 92 | this.ClientSize = new System.Drawing.Size(565, 322); 93 | this.Controls.Add(this.finishedButton); 94 | this.Controls.Add(this.mapGrid); 95 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 96 | this.MinimizeBox = false; 97 | this.Name = "WaveMapper"; 98 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 99 | this.Text = "Wave Mapper"; 100 | ((System.ComponentModel.ISupportInitialize)(this.mapGrid)).EndInit(); 101 | this.ResumeLayout(false); 102 | 103 | } 104 | 105 | #endregion 106 | 107 | private System.Windows.Forms.DataGridView mapGrid; 108 | private System.Windows.Forms.Button finishedButton; 109 | private System.Windows.Forms.DataGridViewButtonColumn playColumn; 110 | private System.Windows.Forms.DataGridViewTextBoxColumn waveId; 111 | private System.Windows.Forms.DataGridViewComboBoxColumn waveArchive; 112 | } 113 | } -------------------------------------------------------------------------------- /Nitro Studio 2/WaveMapper.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.Sound; 2 | using NitroFileLoader; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Data; 7 | using System.Drawing; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | 13 | namespace NitroStudio2 { 14 | public partial class WaveMapper : Form { 15 | 16 | /// 17 | /// Wave archives. 18 | /// 19 | public List WarMap = null; 20 | 21 | /// 22 | /// Waves. 23 | /// 24 | private List wavs = new List(); 25 | 26 | /// 27 | /// Player. 28 | /// 29 | public GotaSoundIO.Sound.Playback.StreamPlayer Player = new GotaSoundIO.Sound.Playback.StreamPlayer(); 30 | 31 | /// 32 | /// Bank importer. 33 | /// 34 | /// Waves. 35 | /// Wave archives. 36 | public WaveMapper(List waves, List wars, bool hideId = false) { 37 | 38 | //Check. 39 | if (wars.Count < 1) { 40 | MessageBox.Show("The target bank must be hooked up to at least one wave archive."); 41 | Close(); 42 | return; 43 | } 44 | 45 | //Init. 46 | InitializeComponent(); 47 | mapGrid.CellContentClick += new DataGridViewCellEventHandler(PlayRegionButtonClick); 48 | if (hideId) { mapGrid.Columns[1].Visible = false; } 49 | FormClosing += new FormClosingEventHandler(OnClosing); 50 | 51 | //Wave archive index. 52 | foreach (var w in wars) { 53 | waveArchive.Items.Add("[" + w.Index + "] " + w.Name); 54 | } 55 | 56 | //Add waves. 57 | int num = 0; 58 | wavs = waves; 59 | foreach (var wav in waves) { 60 | mapGrid.Rows.Add(new DataGridViewRow()); 61 | var v = mapGrid.Rows[mapGrid.Rows.Count - 1]; 62 | ((DataGridViewTextBoxCell)v.Cells[1]).Value = num++; 63 | ((DataGridViewComboBoxCell)v.Cells[2]).Value = waveArchive.Items[0]; 64 | } 65 | 66 | } 67 | 68 | /// 69 | /// Finished. 70 | /// 71 | private void finishedButton_Click(object sender, EventArgs e) { 72 | WarMap = new List(); 73 | foreach (DataGridViewRow r in mapGrid.Rows) { 74 | string s = (string)((DataGridViewComboBoxCell)r.Cells[2]).Value; 75 | WarMap.Add(ushort.Parse(s.Split(']')[0].Split('[')[1])); 76 | } 77 | Close(); 78 | } 79 | 80 | /// 81 | /// Play region button. 82 | /// 83 | public void PlayRegionButtonClick(object sender, DataGridViewCellEventArgs e) { 84 | if (e.ColumnIndex != 0 || e.RowIndex < 0) { 85 | return; 86 | } 87 | Player.Stop(); 88 | Player.LoadStream(wavs[e.RowIndex]); 89 | Player.Play(); 90 | } 91 | 92 | /// 93 | /// On closing. 94 | /// 95 | private void OnClosing(object sender, EventArgs e) { 96 | Player.Dispose(); 97 | } 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Nitro Studio 2/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/icon.ico -------------------------------------------------------------------------------- /Nitro Studio 2/libgcc_s_dw2-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/libgcc_s_dw2-1.dll -------------------------------------------------------------------------------- /Nitro Studio 2/libstdc++-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/libstdc++-6.dll -------------------------------------------------------------------------------- /Nitro Studio 2/midi2sseq.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/midi2sseq.exe -------------------------------------------------------------------------------- /Nitro Studio 2/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Nitro Studio 2/sseq2midi.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/Nitro Studio 2/sseq2midi.exe -------------------------------------------------------------------------------- /NitroFileLoader/CommonStructures.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// SDAT header. 12 | /// 13 | public class SDATHeader : FileHeader { 14 | 15 | /// 16 | /// Read the header. 17 | /// 18 | /// The reader. 19 | public override void Read(FileReader r) { 20 | Magic = new string(r.ReadChars(4)); 21 | r.ByteOrder = ByteOrder.BigEndian; 22 | r.ByteOrder = ByteOrder = r.ReadUInt16() == 0xFEFF ?ByteOrder.BigEndian : ByteOrder.LittleEndian; 23 | r.ReadUInt16(); //Version is always constant. 24 | FileSize = r.ReadUInt32(); 25 | HeaderSize = r.ReadUInt16(); 26 | ushort numBlocks = r.ReadUInt16(); 27 | BlockOffsets = new long[numBlocks]; 28 | BlockSizes = new long[numBlocks]; 29 | if (numBlocks == 3) { r.ReadUInt64(); } 30 | for (int i = 0; i < numBlocks; i++) { 31 | BlockOffsets[i] = r.ReadUInt32(); 32 | BlockSizes[i] = r.ReadUInt32(); 33 | } 34 | r.Align(0x20); 35 | } 36 | 37 | /// 38 | /// Write the header. 39 | /// 40 | /// The writer. 41 | public override void Write(FileWriter w) { 42 | w.ByteOrder = ByteOrder.LittleEndian; 43 | w.Write(Magic.ToCharArray()); 44 | w.Write((ushort)0xFEFF); 45 | w.Write((ushort)0x0100); 46 | w.Write((uint)FileSize); 47 | w.Write((ushort)HeaderSize); 48 | w.Write((ushort)BlockOffsets.Length); 49 | if (BlockOffsets.Length == 3) { w.Write((ulong)0); } 50 | for (int i = 0; i < BlockOffsets.Length; i++) { 51 | w.Write((uint)BlockOffsets[i]); 52 | w.Write((uint)BlockSizes[i]); 53 | } 54 | w.Align(0x20); 55 | } 56 | 57 | } 58 | 59 | /// 60 | /// NDS header. 61 | /// 62 | public class NHeader : FileHeader { 63 | 64 | /// 65 | /// Read the header. 66 | /// 67 | /// The reader. 68 | public override void Read(FileReader r) { 69 | Magic = new string(r.ReadChars(4)); 70 | r.ByteOrder = ByteOrder.BigEndian; 71 | r.ByteOrder = ByteOrder = r.ReadUInt16() == 0xFEFF ? ByteOrder.BigEndian : ByteOrder.LittleEndian; 72 | r.ReadUInt16(); //Version is always constant. 73 | FileSize = r.ReadUInt32(); 74 | HeaderSize = r.ReadUInt16(); 75 | r.ReadUInt16(); 76 | BlockOffsets = new long[] { 0x10 }; 77 | } 78 | 79 | /// 80 | /// Write the header. 81 | /// 82 | /// The writer. 83 | public override void Write(FileWriter w) { 84 | HeaderSize = 0x10; 85 | w.ByteOrder = ByteOrder.LittleEndian; 86 | w.Write(Magic.ToCharArray()); 87 | w.Write((ushort)0xFEFF); 88 | w.Write((ushort)0x0100); 89 | w.Write((uint)FileSize); 90 | w.Write((ushort)HeaderSize); 91 | w.Write((ushort)1); 92 | } 93 | 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /NitroFileLoader/Instrument/DirectInstrument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using GotaSoundIO.IO; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Direct instrument. 12 | /// 13 | public class DirectInstrument : Instrument { 14 | 15 | /// 16 | /// Get the instrument type. 17 | /// 18 | /// The instrument type. 19 | public override InstrumentType Type() => NoteInfo[0].InstrumentType; 20 | 21 | /// 22 | /// Max instruments. 23 | /// 24 | /// The max instruments. 25 | public override uint MaxInstruments() => 1; 26 | 27 | /// 28 | /// Read the instrument. 29 | /// 30 | /// The reader. 31 | public override void Read(FileReader r) { 32 | NoteInfo.Add(r.Read()); 33 | NoteInfo.Last().Key = GotaSequenceLib.Notes.gn9; 34 | } 35 | 36 | /// 37 | /// Write the instrument. 38 | /// 39 | /// The writer. 40 | public override void Write(FileWriter w) { 41 | w.Write(NoteInfo[0]); 42 | } 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /NitroFileLoader/Instrument/DrumSetInstrument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using GotaSequenceLib; 7 | using GotaSoundIO.IO; 8 | 9 | namespace NitroFileLoader { 10 | 11 | /// 12 | /// A drum set instrument. 13 | /// 14 | public class DrumSetInstrument : Instrument { 15 | 16 | /// 17 | /// Minimum instrument. 18 | /// 19 | public byte Min; 20 | 21 | /// 22 | /// Read the instrument. 23 | /// 24 | /// The reader. 25 | public override void Read(FileReader r) { 26 | 27 | //Get indices. 28 | byte min = r.ReadByte(); 29 | byte max = r.ReadByte(); 30 | int numInsts = max - min + 1; 31 | Min = min; 32 | 33 | //Read note parameters. 34 | NoteInfo lastInst = null; 35 | byte ind = min; 36 | for (int i = 0; i < numInsts; i++) { 37 | 38 | //Get the instrument type. 39 | InstrumentType t = (InstrumentType)r.ReadUInt16(); 40 | NoteInfo n = r.Read(); 41 | if (lastInst == null) { 42 | lastInst = n; 43 | } else { 44 | if (!n.Equals(lastInst)) { 45 | NoteInfo.Add(lastInst); 46 | NoteInfo.Last().Key = (Notes)(ind - 1); 47 | lastInst = n; 48 | } 49 | } 50 | 51 | //If last instrument. 52 | if (ind == max) { 53 | NoteInfo.Add(n); 54 | NoteInfo.Last().Key = (Notes)ind; 55 | } 56 | 57 | //Increment index. 58 | ind++; 59 | 60 | } 61 | 62 | } 63 | 64 | /// 65 | /// Write the intrument. 66 | /// 67 | /// The writer. 68 | public override void Write(FileWriter w) { 69 | 70 | //Write data. 71 | var indices = NoteInfo.Select(x => x.Key).ToArray(); 72 | w.Write(Min); 73 | w.Write((byte)indices.Last()); 74 | for (int i = Min; i <= (byte)indices.Last(); i++) { 75 | int ind = 0; 76 | for (int j = indices.Count() - 1; j >= 0; j--) { 77 | if (i <= (byte)indices[j]) { 78 | ind = j; 79 | } 80 | } 81 | w.Write((ushort)NoteInfo.Where(x => x.Key == indices[ind]).FirstOrDefault().InstrumentType); 82 | w.Write(NoteInfo.Where(x => x.Key == indices[ind]).FirstOrDefault()); 83 | } 84 | 85 | } 86 | 87 | /// 88 | /// The instrument type. 89 | /// 90 | /// The instrument type. 91 | public override InstrumentType Type() => InstrumentType.DrumSet; 92 | 93 | /// 94 | /// Max instruments. 95 | /// 96 | /// The max instruments. 97 | public override uint MaxInstruments() => 0x80; 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /NitroFileLoader/Instrument/Instrument.cs: -------------------------------------------------------------------------------- 1 | using GotaSequenceLib; 2 | using GotaSoundIO.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace NitroFileLoader { 10 | 11 | /// 12 | /// Instrument. 13 | /// 14 | public abstract class Instrument : IReadable, IWriteable { 15 | 16 | /// 17 | /// Note info. 18 | /// 19 | public List NoteInfo = new List(); 20 | 21 | /// 22 | /// Program number. 23 | /// 24 | public int Index; 25 | 26 | /// 27 | /// Order. 28 | /// 29 | public long GetOrder => Order + Math.Max((int)Type() - 5, 0) * 100000000; 30 | 31 | /// 32 | /// Order. 33 | /// 34 | public long Order; 35 | 36 | /// 37 | /// Read the instrument. 38 | /// 39 | /// The reader. 40 | public abstract void Read(FileReader r); 41 | 42 | /// 43 | /// Write the instrument. 44 | /// 45 | /// The writer. 46 | public abstract void Write(FileWriter w); 47 | 48 | /// 49 | /// Instrument type. 50 | /// 51 | /// The instrument type. 52 | public abstract InstrumentType Type(); 53 | 54 | /// 55 | /// Max instruments. 56 | /// 57 | /// The max instruments. 58 | public abstract uint MaxInstruments(); 59 | 60 | /// 61 | /// Get the note parameter for a note. 62 | /// 63 | /// The note to retrieve. 64 | /// The note parameter. 65 | public NoteInfo GetNoteInfo(Notes note) { 66 | 67 | //Switch instrument type. 68 | switch (Type()) { 69 | 70 | //Direct. 71 | case InstrumentType.PCM: 72 | case InstrumentType.PSG: 73 | case InstrumentType.Noise: 74 | return NoteInfo[0]; 75 | 76 | //Range. 77 | case InstrumentType.DrumSet: 78 | case InstrumentType.KeySplit: 79 | 80 | //Old algorithm. 81 | /*if ((Type() == InstrumentType.DrumSet && (byte)note < (this as DrumSetInstrument).Min) || (byte)note > NoteInfo.Keys.ElementAt(NoteInfo.Keys.Count - 1)) { 82 | return null; 83 | } 84 | int regionNum = 0; 85 | for (int i = NoteInfo.Count - 1; i >= 0; i--) { 86 | if ((byte)note <= NoteInfo.Keys.ElementAt(i)) { 87 | regionNum = i; 88 | } 89 | } 90 | return NoteInfo.Values.ElementAt(regionNum);*/ 91 | 92 | //New algorithm. 93 | if ((Type() == InstrumentType.DrumSet && (byte)note < (this as DrumSetInstrument).Min) || (byte)note > NoteInfo.Select(x => (byte)x.Key).ElementAt(NoteInfo.Count - 1)) { 94 | return null; 95 | } 96 | for (int i = 0; i < NoteInfo.Count; i++) { 97 | if ((byte)note <= (byte)NoteInfo[i].Key) { 98 | return NoteInfo[i]; 99 | } 100 | } 101 | return null; 102 | 103 | } 104 | 105 | //Default is null. 106 | return null; 107 | 108 | } 109 | 110 | } 111 | 112 | /// 113 | /// Instrument type. 114 | /// 115 | public enum InstrumentType : byte { 116 | Blank, 117 | PCM, 118 | PSG, 119 | Noise, 120 | DirectPCM, 121 | Null, 122 | DrumSet = 16, 123 | KeySplit = 17 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /NitroFileLoader/Instrument/KeySplitInstrument.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using GotaSequenceLib; 7 | using GotaSoundIO.IO; 8 | 9 | namespace NitroFileLoader { 10 | 11 | /// 12 | /// A key split instrument. 13 | /// 14 | public class KeySplitInstrument : Instrument { 15 | 16 | /// 17 | /// Read the instrument. 18 | /// 19 | /// The reader. 20 | public override void Read(FileReader r) { 21 | 22 | //Get indices. 23 | List indices = new List(); 24 | for (int i = 0; i < 8; i++) { 25 | byte b = r.ReadByte(); 26 | if (b != 0) { 27 | indices.Add(b); 28 | } 29 | } 30 | 31 | //Read note parameters. 32 | for (int i = 0; i < indices.Count; i++) { 33 | 34 | //Get the instrument type. 35 | InstrumentType t = (InstrumentType)r.ReadUInt16(); 36 | NoteInfo.Add(r.Read()); 37 | NoteInfo.Last().Key = (Notes)indices[i]; 38 | NoteInfo.Last().InstrumentType = t; 39 | 40 | } 41 | 42 | } 43 | 44 | /// 45 | /// Write the intrument. 46 | /// 47 | /// The writer. 48 | public override void Write(FileWriter w) { 49 | 50 | //Get indices. 51 | var indices = NoteInfo.Select(x => (byte)x.Key).ToArray(); 52 | w.Write(indices); 53 | w.Write(new byte[8 - indices.Length]); 54 | 55 | //Write instrument info. 56 | foreach (var v in NoteInfo) { 57 | w.Write((ushort)v.InstrumentType); 58 | w.Write(v); 59 | } 60 | 61 | } 62 | 63 | /// 64 | /// The instrument type. 65 | /// 66 | /// The instrument type. 67 | public override InstrumentType Type() => InstrumentType.KeySplit; 68 | 69 | /// 70 | /// Max instruments. 71 | /// 72 | /// The max instruments. 73 | public override uint MaxInstruments() => 8; 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /NitroFileLoader/Instrument/NoteInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSequenceLib; 2 | using GotaSequenceLib.Playback; 3 | using GotaSoundIO.IO; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace NitroFileLoader { 11 | 12 | /// 13 | /// Note info. 14 | /// 15 | public class NoteInfo : IReadable, IWriteable { 16 | 17 | /// 18 | /// Key to access the note. 19 | /// 20 | public Notes Key; 21 | 22 | /// 23 | /// Instrument type. 24 | /// 25 | public InstrumentType InstrumentType = InstrumentType.PCM; 26 | 27 | /// 28 | /// Wave Id. 29 | /// 30 | public ushort WaveId; 31 | 32 | /// 33 | /// Wave archive Id. 34 | /// 35 | public ushort WarId; 36 | 37 | /// 38 | /// Base note. 39 | /// 40 | public byte BaseNote = 60; 41 | 42 | /// 43 | /// Attack. 44 | /// 45 | public byte Attack = 127; 46 | 47 | /// 48 | /// Decay. 49 | /// 50 | public byte Decay = 127; 51 | 52 | /// 53 | /// Sustain. 54 | /// 55 | public byte Sustain = 127; 56 | 57 | /// 58 | /// Release. 59 | /// 60 | public byte Release = 127; 61 | 62 | /// 63 | /// Pan. 64 | /// 65 | public byte Pan = 0x40; 66 | 67 | /// 68 | /// Read the note info. 69 | /// 70 | /// The reader. 71 | public void Read(FileReader r) { 72 | WaveId = r.ReadUInt16(); 73 | WarId = r.ReadUInt16(); 74 | BaseNote = r.ReadByte(); 75 | Attack = r.ReadByte(); 76 | Decay = r.ReadByte(); 77 | Sustain = r.ReadByte(); 78 | Release = r.ReadByte(); 79 | Pan = r.ReadByte(); 80 | } 81 | 82 | /// 83 | /// Write the note info. 84 | /// 85 | /// The writer. 86 | public void Write(FileWriter w) { 87 | w.Write(WaveId); 88 | w.Write(WarId); 89 | w.Write(BaseNote); 90 | w.Write(Attack); 91 | w.Write(Decay); 92 | w.Write(Sustain); 93 | w.Write(Release); 94 | w.Write(Pan); 95 | } 96 | 97 | /// 98 | /// Convert this to note playback info. 99 | /// 100 | /// This as note playback info. 101 | public NotePlayBackInfo ToNotePlayBackInfo() => new NotePlayBackInfo() { 102 | Attack = Attack, 103 | Decay = Decay, 104 | InstrumentType = TrueType(), 105 | BaseKey = BaseNote, 106 | Pan = Pan, 107 | Release = Release, 108 | Sustain = Sustain, 109 | WarId = WarId, 110 | WaveId = WaveId 111 | }; 112 | 113 | /// 114 | /// True instrument type. 115 | /// 116 | /// 117 | public GotaSequenceLib.Playback.InstrumentType TrueType() { 118 | switch (InstrumentType) { 119 | case InstrumentType.PSG: 120 | return GotaSequenceLib.Playback.InstrumentType.PSG; 121 | case InstrumentType.Noise: 122 | return GotaSequenceLib.Playback.InstrumentType.Noise; 123 | default: 124 | return GotaSequenceLib.Playback.InstrumentType.PCM; 125 | } 126 | } 127 | 128 | /// 129 | /// If the note info equals another note info. 130 | /// 131 | /// The object. 132 | /// If the two objects are equal. 133 | public override bool Equals(object obj) { 134 | 135 | //Note info. 136 | var n = obj as NoteInfo; 137 | if (n == null) { 138 | return false; 139 | } 140 | 141 | //If content matches. 142 | return n.Attack == Attack && n.BaseNote == BaseNote && n.Decay == Decay && n.InstrumentType == InstrumentType && n.Pan == Pan && n.Release == Release && n.Sustain == Sustain && n.WarId == WarId && n.WaveId == WaveId; 143 | 144 | } 145 | 146 | /// 147 | /// Duplicate the note info. 148 | /// 149 | /// New note info clone. 150 | public NoteInfo Duplicate() { 151 | return new NoteInfo() { Attack = Attack, BaseNote = BaseNote, Decay = Decay, InstrumentType = InstrumentType, Key = Key, Pan = Pan, Release = Release, Sustain = Sustain, WarId = WarId, WaveId = WaveId }; 152 | } 153 | 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /NitroFileLoader/NitroFileLoader.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {132D5DA0-BD98-4FCB-9A9C-73556C16B2C0} 8 | Library 9 | Properties 10 | NitroFileLoader 11 | NitroFileLoader 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | .\SoundFont2.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | {D06E248A-EF7A-4F1E-9A71-76204D61FF80} 76 | GotaSequenceLib 77 | 78 | 79 | {2642E217-5595-4E4B-9B6D-F5CFD937EB25} 80 | GotaSoundBank 81 | 82 | 83 | {f0bcd085-9dc4-4b22-b791-c725ca8e46f6} 84 | GotaSoundIO 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /NitroFileLoader/NitroStream.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using GotaSoundIO.Sound; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace NitroFileLoader { 10 | 11 | /// 12 | /// Stream. 13 | /// 14 | public class Stream : SoundFile { 15 | 16 | /// 17 | /// Supported encodings. 18 | /// 19 | /// The supported encodings. 20 | public override Type[] SupportedEncodings() => new Type[] { typeof(ImaAdpcm), typeof(PCM16), typeof(PCM8Signed) }; 21 | 22 | /// 23 | /// Name. 24 | /// 25 | /// The name. 26 | public override string Name() => "STRM"; 27 | 28 | /// 29 | /// Extensions. 30 | /// 31 | /// The extensions. 32 | public override string[] Extensions() => new string[] { "STRM" }; 33 | 34 | /// 35 | /// Description. 36 | /// 37 | /// The description. 38 | public override string Description() => "An STRM stream used in Nintendo DS games."; 39 | 40 | /// 41 | /// If the file supports tracks. 42 | /// 43 | /// It doesn't. 44 | public override bool SupportsTracks() => false; 45 | 46 | /// 47 | /// Preferred encoding. 48 | /// 49 | /// The preferred encoding. 50 | public override Type PreferredEncoding() => typeof(ImaAdpcm); 51 | 52 | /// 53 | /// Read the file. 54 | /// 55 | /// The reader. 56 | public override void Read(FileReader r) { 57 | 58 | //Read header. 59 | r.OpenFile(out _); 60 | 61 | //Head block. 62 | r.OpenBlock(0, out _, out _); 63 | PcmFormat pcmFormat = (PcmFormat)r.ReadByte(); 64 | Loops = r.ReadBoolean(); 65 | int numChannels = r.ReadByte(); 66 | r.ReadByte(); 67 | SampleRate = r.ReadUInt16(); 68 | r.ReadUInt16(); 69 | LoopStart = r.ReadUInt32(); 70 | uint numSamples = r.ReadUInt32(); 71 | if (Loops) { LoopEnd = numSamples; } 72 | r.OpenOffset("dataOffset"); 73 | uint numBlocks = r.ReadUInt32(); 74 | uint blockSize = r.ReadUInt32(); 75 | uint blockSamples = r.ReadUInt32(); 76 | uint lastBlockSize = r.ReadUInt32(); 77 | uint lastBlockSamples = r.ReadUInt32(); 78 | r.ReadBytes(32); 79 | 80 | //Encoding type. 81 | Type encodingType = null; 82 | switch (pcmFormat) { 83 | case PcmFormat.SignedPCM8: 84 | encodingType = typeof(PCM8Signed); 85 | break; 86 | case PcmFormat.PCM16: 87 | encodingType = typeof(PCM16); 88 | break; 89 | case PcmFormat.Encoded: 90 | encodingType = typeof(ImaAdpcm); 91 | break; 92 | } 93 | 94 | //Data block. 95 | r.JumpToOffset("dataOffset", true, true); 96 | Audio.Read(r, encodingType, numChannels, numBlocks, blockSize, blockSamples, lastBlockSize, lastBlockSamples, 0); 97 | 98 | } 99 | 100 | /// 101 | /// Write the file. 102 | /// 103 | /// The writer. 104 | public override void Write(FileWriter w) { 105 | 106 | //Init header. 107 | w.InitFile("STRM", ByteOrder.LittleEndian, null, 2); 108 | long countOff = w.Position - 2; 109 | 110 | //Head block. 111 | w.Write("HEAD".ToCharArray()); 112 | w.Write((uint)0x50); 113 | 114 | //Format. 115 | PcmFormat pcmFormat = PcmFormat.Encoded; 116 | uint blockSamples = (uint)Audio.NumSamples; 117 | uint blockSize = (uint)Audio.DataSize; 118 | if (Audio.EncodingType.Equals(typeof(PCM8Signed))) { 119 | w.Write((byte)PcmFormat.SignedPCM8); 120 | pcmFormat = PcmFormat.SignedPCM8; 121 | } else if (Audio.EncodingType.Equals(typeof(PCM16))) { 122 | w.Write((byte)PcmFormat.PCM16); 123 | pcmFormat = PcmFormat.PCM16; 124 | } else if (Audio.EncodingType.Equals(typeof(ImaAdpcm))) { 125 | w.Write((byte)PcmFormat.Encoded); 126 | pcmFormat = PcmFormat.Encoded; 127 | blockSize = (uint)Audio.BlockSize; 128 | blockSamples = (blockSize - 4) * 2; 129 | } else { 130 | throw new Exception("Invalid channel format!"); 131 | } 132 | w.Write(Loops); 133 | w.Write((byte)Audio.Channels.Count()); 134 | w.Write((byte)0); 135 | w.Write((ushort)SampleRate); 136 | w.Write((ushort)Math.Floor((decimal)523655.96875 * ((decimal)1 / (decimal)SampleRate))); 137 | w.Write(LoopStart); 138 | w.Write(Audio.NumSamples); 139 | w.Write((uint)0x68); 140 | w.Write(Audio.NumBlocks); 141 | w.Write(blockSize); 142 | w.Write(blockSamples); 143 | w.Write(Audio.LastBlockSize); 144 | w.Write(Audio.LastBlockSamples); 145 | w.Write(new byte[0x20]); 146 | long bak = w.Position; 147 | w.Write("DATA".ToCharArray()); 148 | w.Write((uint)0); 149 | Audio.Write(w); 150 | w.Pad(4); 151 | long bak2 = w.Position; 152 | w.Position = bak + 4; 153 | w.Write((uint)(bak2 - bak)); 154 | w.Position = bak2; 155 | w.CloseFile(); 156 | bak = w.Position; 157 | w.Position = countOff; 158 | w.Write((ushort)2); 159 | w.Position = bak; 160 | 161 | } 162 | 163 | /// 164 | /// Before conversion. 165 | /// 166 | public override void BeforeConversion() { 167 | if (Audio.BlockSize == -1) { 168 | Audio.ChangeBlockSize(0x200); 169 | } 170 | } 171 | 172 | /// 173 | /// After conversion. 174 | /// 175 | public override void AfterConversion() { 176 | AlignLoopToBlock((uint)Audio.BlockSamples); 177 | TrimAfterLoopEnd(); 178 | LoopEnd = (uint)Audio.NumSamples; 179 | } 180 | 181 | } 182 | 183 | } 184 | -------------------------------------------------------------------------------- /NitroFileLoader/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("NitroFileLoader")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("NitroFileLoader")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("132d5da0-bd98-4fcb-9a9c-73556c16b2c0")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /NitroFileLoader/Rom.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// An NDS ROM. 12 | /// 13 | public class Rom : IOFile { 14 | 15 | /// 16 | /// Game name. 17 | /// 18 | public string GameName; 19 | 20 | /// 21 | /// Game code. 22 | /// 23 | public string GameCode; 24 | 25 | /// 26 | /// Read the ROM. 27 | /// 28 | /// The reader. 29 | public override void Read(FileReader r) { 30 | throw new NotImplementedException(); 31 | } 32 | 33 | /// 34 | /// Write the ROM. 35 | /// 36 | /// The writer. 37 | public override void Write(FileWriter w) { 38 | throw new NotImplementedException(); 39 | } 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /NitroFileLoader/Sequence.cs: -------------------------------------------------------------------------------- 1 | using GotaSequenceLib; 2 | using GotaSoundIO.IO; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace NitroFileLoader { 10 | 11 | /// 12 | /// Sequence file. 13 | /// 14 | public class Sequence : SequenceFile { 15 | 16 | /// 17 | /// Read the file. 18 | /// 19 | /// The reader. 20 | public override void Read(FileReader r) { 21 | 22 | //Read the sequence. 23 | FileHeader header; 24 | r.OpenFile(out header); 25 | 26 | //Data block. 27 | uint dataSize; 28 | r.OpenBlock(0, out _, out _); 29 | uint off = r.ReadUInt32(); 30 | dataSize = (uint)(header.FileSize - off); 31 | r.Jump(off, true); 32 | var data = r.ReadBytes((int)dataSize).ToList(); 33 | 34 | //Remove padding. 35 | for (int i = data.Count - 1; i >= 0; i--) { 36 | if (data[i] == 0) { 37 | data.RemoveAt(i); 38 | } else { 39 | break; 40 | } 41 | } 42 | 43 | //Set raw data. 44 | RawData = data.ToArray(); 45 | 46 | } 47 | 48 | /// 49 | /// Write the file. 50 | /// 51 | /// The writer. 52 | public override void Write(FileWriter w) { 53 | 54 | //Simple. 55 | w.InitFile("SSEQ", ByteOrder.LittleEndian, null, 1); 56 | w.InitBlock("DATA"); 57 | w.Write((uint)0x1C); 58 | w.Write(RawData); 59 | w.Pad(4); 60 | w.CloseBlock(); 61 | w.CloseFile(); 62 | 63 | } 64 | 65 | /// 66 | /// Convert the file to text. 67 | /// 68 | /// The file as text. 69 | public new string[] ToText() { 70 | 71 | //Command list. 72 | List l = new List(); 73 | 74 | //Add header. 75 | l.Add(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"); 76 | l.Add(";"); 77 | l.Add("; " + Name + ".smft"); 78 | l.Add("; Generated By Nitro Studio 2"); 79 | l.Add(";"); 80 | l.Add(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"); 81 | l.Add(""); 82 | 83 | //For each command. Last one isn't counted. 84 | for (int i = 0; i < Commands.Count - 1; i++) { 85 | 86 | //Add labels. 87 | bool labelAdded = false; 88 | var labels = PublicLabels.Where(x => x.Value == i).Select(x => x.Key); 89 | bool label0Added = false; 90 | foreach (var label in labels) { 91 | if (i != 0 && !labelAdded && Commands[i - 1].CommandType == SequenceCommands.Fin) { 92 | l.Add(" "); 93 | } 94 | if (i == 0) { 95 | label0Added = true; 96 | } 97 | l.Add(label + ":"); 98 | labelAdded = true; 99 | } 100 | if (OtherLabels.Contains(i)) { 101 | if (i != 0 && !labelAdded && Commands[i - 1].CommandType == SequenceCommands.Fin) { 102 | l.Add(" "); 103 | } 104 | if (i != 0) { l.Add("_command_" + i + ":"); } 105 | //else if (Commands[i - 1].CommandType == SequenceCommands.Fin) { l.Add("Command_" + i + ":"); } 106 | labelAdded = true; 107 | } 108 | if (i == 0 && !label0Added) { 109 | l.Add("Sequence_Start:"); 110 | } 111 | 112 | //Add command. 113 | l.Add("\t" + Commands[i].ToString()); 114 | 115 | } 116 | 117 | //Return the list. 118 | return l.ToArray(); 119 | 120 | } 121 | 122 | /// 123 | /// Sequence platform. 124 | /// 125 | /// The sequence platform. 126 | public override SequencePlatform Platform() => new Nitro(); 127 | 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/GroupEntry.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Group entry. 12 | /// 13 | public class GroupEntry : IReadable, IWriteable { 14 | 15 | /// 16 | /// Entry data. 17 | /// 18 | public object Entry; 19 | 20 | /// 21 | /// Type. 22 | /// 23 | public GroupEntryType Type; 24 | 25 | /// 26 | /// Reading Id. 27 | /// 28 | public uint ReadingId; 29 | 30 | /// 31 | /// Load sequence. 32 | /// 33 | public bool LoadSequence; 34 | 35 | /// 36 | /// Load sequence archive. 37 | /// 38 | public bool LoadSequenceArchive; 39 | 40 | /// 41 | /// Load bank. 42 | /// 43 | public bool LoadBank; 44 | 45 | /// 46 | /// Load wave archive. 47 | /// 48 | public bool LoadWaveArchive; 49 | 50 | /// 51 | /// Load flags. 52 | /// 53 | /// The flags. 54 | public void LoadFlags(byte flags) { 55 | LoadSequence = (flags & 0b1) > 0; 56 | LoadBank = (flags & 0b10) > 0; 57 | LoadWaveArchive = (flags & 0b100) > 0; 58 | LoadSequenceArchive = (flags & 0b1000) > 0; 59 | } 60 | 61 | /// 62 | /// Save flags. 63 | /// 64 | /// The flags as a byte. 65 | public byte SaveFlags() { 66 | byte flags = 0; 67 | if (LoadSequence) { flags |= 0b1; } 68 | if (LoadBank) { flags |= 0b10; } 69 | if (LoadWaveArchive) { flags |= 0b100; } 70 | if (LoadSequenceArchive) { flags |= 0b1000; } 71 | return flags; 72 | } 73 | 74 | /// 75 | /// Read the entry. 76 | /// 77 | /// The reader. 78 | public void Read(FileReader r) { 79 | Type = (GroupEntryType)r.ReadByte(); 80 | LoadFlags(r.ReadByte()); 81 | r.ReadUInt16(); 82 | ReadingId = r.ReadUInt32(); 83 | } 84 | 85 | /// 86 | /// Write the entry. 87 | /// 88 | /// The writer 89 | public void Write(FileWriter w) { 90 | w.Write((byte)Type); 91 | w.Write(SaveFlags()); 92 | w.Write((ushort)0); 93 | switch (Type) { 94 | case GroupEntryType.Sequence: 95 | w.Write((uint)(Entry as SequenceInfo).Index); 96 | break; 97 | case GroupEntryType.Bank: 98 | w.Write((uint)(Entry as BankInfo).Index); 99 | break; 100 | case GroupEntryType.WaveArchive: 101 | w.Write((uint)(Entry as WaveArchiveInfo).Index); 102 | break; 103 | case GroupEntryType.SequenceArchive: 104 | w.Write((uint)(Entry as SequenceArchiveInfo).Index); 105 | break; 106 | } 107 | } 108 | 109 | } 110 | 111 | /// 112 | /// Entry type. 113 | /// 114 | public enum GroupEntryType : byte { 115 | Sequence, Bank, WaveArchive, SequenceArchive 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/GroupInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Group info. 12 | /// 13 | public class GroupInfo : IReadable, IWriteable { 14 | 15 | /// 16 | /// Name. 17 | /// 18 | public string Name; 19 | 20 | /// 21 | /// Entry index. 22 | /// 23 | public int Index; 24 | 25 | /// 26 | /// Entries. 27 | /// 28 | public List Entries = new List(); 29 | 30 | /// 31 | /// Read the info. 32 | /// 33 | /// The reader. 34 | public void Read(FileReader r) { 35 | Entries = new List(); 36 | uint numEntries = r.ReadUInt32(); 37 | for (uint i = 0; i < numEntries; i++) { 38 | Entries.Add(r.Read()); 39 | } 40 | } 41 | 42 | /// 43 | /// Write the info. 44 | /// 45 | /// The writer. 46 | public void Write(FileWriter w) { 47 | Entries = Entries.Where(x => x.Entry != null).ToList(); 48 | w.Write((uint)Entries.Count); 49 | foreach (var e in Entries) { 50 | w.Write(e); 51 | } 52 | } 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/PlayerInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Player info. 12 | /// 13 | public class PlayerInfo : IReadable, IWriteable { 14 | 15 | /// 16 | /// Name. 17 | /// 18 | public string Name; 19 | 20 | /// 21 | /// Entry index. 22 | /// 23 | public int Index; 24 | 25 | /// 26 | /// Sequence max. 27 | /// 28 | public ushort SequenceMax; 29 | 30 | /// 31 | /// Channel flags. 32 | /// 33 | public bool[] ChannelFlags = new bool[16]; 34 | 35 | /// 36 | /// Heap size. 37 | /// 38 | public uint HeapSize; 39 | 40 | /// 41 | /// Read the info. 42 | /// 43 | /// The reader. 44 | public void Read(FileReader r) { 45 | SequenceMax = r.ReadUInt16(); 46 | ChannelFlags = r.ReadBitFlags(2); 47 | if (ChannelFlags.Where(x => x == false).Count() == 16) { ChannelFlags = new bool[] { true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true }; } 48 | HeapSize = r.ReadUInt32(); 49 | } 50 | 51 | /// 52 | /// Write the info. 53 | /// 54 | /// The writer. 55 | public void Write(FileWriter w) { 56 | w.Write(SequenceMax); 57 | if (ChannelFlags.Where(x => x == true).Count() == 16) { 58 | w.Write((ushort)0); 59 | } else { 60 | w.WriteBitFlags(ChannelFlags, 2); 61 | } 62 | w.Write(HeapSize); 63 | } 64 | 65 | /// 66 | /// Get bit flags. 67 | /// 68 | public ushort BitFlags() { 69 | 70 | //Flags. 71 | ushort u = 0; 72 | for (int i = 0; i < ChannelFlags.Length; i++) { 73 | if (ChannelFlags[i]) { u |= (ushort)(0b1 << i); } 74 | } 75 | return u; 76 | 77 | } 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/SequenceArchiveInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Sequence archive info. 12 | /// 13 | public class SequenceArchiveInfo : IReadable, IWriteable { 14 | 15 | /// 16 | /// Name. 17 | /// 18 | public string Name; 19 | 20 | /// 21 | /// Entry index. 22 | /// 23 | public int Index; 24 | 25 | /// 26 | /// Force the file to be individualized. 27 | /// 28 | public bool ForceIndividualFile; 29 | 30 | /// 31 | /// File. 32 | /// 33 | public SequenceArchive File; 34 | 35 | /// 36 | /// Reading file Id. 37 | /// 38 | public uint ReadingFileId; 39 | 40 | /// 41 | /// Read the info. 42 | /// 43 | /// The reader. 44 | public void Read(FileReader r) { 45 | ReadingFileId = r.ReadUInt32(); 46 | } 47 | 48 | /// 49 | /// Write the info. 50 | /// 51 | /// The writer. 52 | public void Write(FileWriter w) { 53 | w.Write(ReadingFileId); 54 | } 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/SequenceInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Sequence info. 12 | /// 13 | public class SequenceInfo : IReadable, IWriteable { 14 | 15 | /// 16 | /// Name. 17 | /// 18 | public string Name; 19 | 20 | /// 21 | /// Entry index. 22 | /// 23 | public int Index; 24 | 25 | /// 26 | /// Force the file to be individualized. 27 | /// 28 | public bool ForceIndividualFile; 29 | 30 | /// 31 | /// File. 32 | /// 33 | public Sequence File; 34 | 35 | /// 36 | /// Bank. 37 | /// 38 | public BankInfo Bank; 39 | 40 | /// 41 | /// Player. 42 | /// 43 | public PlayerInfo Player; 44 | 45 | /// 46 | /// Volume. 47 | /// 48 | public byte Volume = 100; 49 | 50 | /// 51 | /// Channel priority. 52 | /// 53 | public byte ChannelPriority = 0x40; 54 | 55 | /// 56 | /// Player priority. 57 | /// 58 | public byte PlayerPriority = 0x40; 59 | 60 | /// 61 | /// Reading file Id. 62 | /// 63 | public uint ReadingFileId; 64 | 65 | /// 66 | /// Reading bank Id. 67 | /// 68 | public ushort ReadingBankId; 69 | 70 | /// 71 | /// Reading player Id. 72 | /// 73 | public byte ReadingPlayerId; 74 | 75 | /// 76 | /// Read the info. 77 | /// 78 | /// The reader. 79 | public void Read(FileReader r) { 80 | ReadingFileId = r.ReadUInt32(); 81 | ReadingBankId = r.ReadUInt16(); 82 | Volume = r.ReadByte(); 83 | ChannelPriority = r.ReadByte(); 84 | PlayerPriority = r.ReadByte(); 85 | ReadingPlayerId = r.ReadByte(); 86 | r.ReadUInt16(); 87 | } 88 | 89 | /// 90 | /// Write the info. 91 | /// 92 | /// The writer. 93 | public void Write(FileWriter w) { 94 | w.Write(ReadingFileId); 95 | w.Write((ushort)(Bank != null ? Bank.Index : ReadingBankId)); 96 | w.Write(Volume); 97 | w.Write(ChannelPriority); 98 | w.Write(PlayerPriority); 99 | w.Write((byte)(Player != null ? Player.Index : ReadingPlayerId)); 100 | w.Write((ushort)0); 101 | } 102 | 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/StreamInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Stream info. 12 | /// 13 | public class StreamInfo : IReadable, IWriteable { 14 | 15 | /// 16 | /// Name. 17 | /// 18 | public string Name; 19 | 20 | /// 21 | /// Entry index. 22 | /// 23 | public int Index; 24 | 25 | /// 26 | /// Force the file to be individualized. 27 | /// 28 | public bool ForceIndividualFile; 29 | 30 | /// 31 | /// File. 32 | /// 33 | public Stream File; 34 | 35 | /// 36 | /// Stream player. 37 | /// 38 | public StreamPlayerInfo Player; 39 | 40 | /// 41 | /// Volume. 42 | /// 43 | public byte Volume = 100; 44 | 45 | /// 46 | /// Priority. 47 | /// 48 | public byte Priority = 0x40; 49 | 50 | /// 51 | /// Reading file Id. 52 | /// 53 | public uint ReadingFileId; 54 | 55 | /// 56 | /// Player Id. 57 | /// 58 | public byte ReadingPlayerId; 59 | 60 | /// 61 | /// Mono to stereo. 62 | /// 63 | public bool MonoToStereo; 64 | 65 | /// 66 | /// Read the info. 67 | /// 68 | /// The reader. 69 | public void Read(FileReader r) { 70 | ReadingFileId = r.ReadUInt32(); 71 | MonoToStereo = (ReadingFileId & 0xFF000000) > 0; 72 | ReadingFileId &= 0xFFFFFF; 73 | Volume = r.ReadByte(); 74 | Priority = r.ReadByte(); 75 | ReadingPlayerId = r.ReadByte(); 76 | r.ReadBytes(5); 77 | } 78 | 79 | /// 80 | /// Write the info. 81 | /// 82 | /// The writer. 83 | public void Write(FileWriter w) { 84 | w.Write((uint)(ReadingFileId | (MonoToStereo ? 0x01000000 : 0))); 85 | w.Write(Volume); 86 | w.Write(Priority); 87 | w.Write((byte)(Player != null ? Player.Index : ReadingPlayerId)); 88 | w.Write(new byte[5]); 89 | } 90 | 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/StreamPlayerInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace NitroFileLoader { 9 | 10 | /// 11 | /// Stream player info. 12 | /// 13 | public class StreamPlayerInfo : IReadable, IWriteable { 14 | 15 | /// 16 | /// Name. 17 | /// 18 | public string Name; 19 | 20 | /// 21 | /// Entry index. 22 | /// 23 | public int Index; 24 | 25 | /// 26 | /// Is stereo. 27 | /// 28 | public bool IsStereo; 29 | 30 | /// 31 | /// Left channel. 32 | /// 33 | public byte LeftChannel; 34 | 35 | /// 36 | /// Right channel. 37 | /// 38 | public byte RightChannel; 39 | 40 | /// 41 | /// Read the info. 42 | /// 43 | /// The reader. 44 | public void Read(FileReader r) { 45 | IsStereo = r.ReadByte() > 1; 46 | LeftChannel = r.ReadByte(); 47 | RightChannel = r.ReadByte(); 48 | r.ReadBytes(21); 49 | } 50 | 51 | /// 52 | /// Write the info. 53 | /// 54 | /// The writer. 55 | public void Write(FileWriter w) { 56 | w.Write((byte)(IsStereo ? 2 : 1)); 57 | w.Write(LeftChannel); 58 | w.Write((byte)(IsStereo ? RightChannel : 0xFF)); 59 | for (int i = 0; i < 0xE; i++) { 60 | w.Write((byte)0xFF); 61 | } 62 | w.Write(new byte[7]); 63 | 64 | } 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /NitroFileLoader/Sound Archive/WaveArchiveInfo.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO.IO; 2 | using GotaSoundIO.Sound; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace NitroFileLoader { 11 | 12 | /// 13 | /// Wave archive info. 14 | /// 15 | public class WaveArchiveInfo : IReadable, IWriteable { 16 | 17 | /// 18 | /// Name. 19 | /// 20 | public string Name; 21 | 22 | /// 23 | /// Entry index. 24 | /// 25 | public int Index; 26 | 27 | /// 28 | /// Force the file to be individualized. 29 | /// 30 | public bool ForceIndividualFile; 31 | 32 | /// 33 | /// File. 34 | /// 35 | public WaveArchive File; 36 | 37 | /// 38 | /// Reading file Id. 39 | /// 40 | public uint ReadingFileId; 41 | 42 | /// 43 | /// Load wave archive individually. 44 | /// 45 | public bool LoadIndividually; 46 | 47 | /// 48 | /// Read the info. 49 | /// 50 | /// The reader. 51 | public void Read(FileReader r) { 52 | ReadingFileId = r.ReadUInt32(); 53 | LoadIndividually = (ReadingFileId & 0xFF000000) > 0; 54 | ReadingFileId &= 0xFFFFFF; 55 | } 56 | 57 | /// 58 | /// Write the info. 59 | /// 60 | /// The writer. 61 | public void Write(FileWriter w) { 62 | w.Write((uint)(ReadingFileId | (LoadIndividually ? 0x01000000 : 0))); 63 | } 64 | 65 | /// 66 | /// Write the text format, and dump files. 67 | /// 68 | /// The path. 69 | /// The name. 70 | public void WriteTextFormat(string path, string name) { 71 | 72 | //SWLS. 73 | List swls = new List(); 74 | int ind = 0; 75 | Directory.CreateDirectory(path + "/" + name); 76 | foreach (var w in File.Waves) { 77 | swls.Add(name + "/" + ind.ToString("D4") + ".adpcm.swav"); 78 | w.Write(path + "/" + name + "/" + ind.ToString("D4") + ".adpcm.swav"); 79 | RiffWave r = new RiffWave(); 80 | r.FromOtherStreamFile(w); 81 | r.Write(path + "/" + name + "/" + ind.ToString("D4") + ".wav"); 82 | ind++; 83 | } 84 | System.IO.File.WriteAllLines(path + "/" + name + ".swls", swls); 85 | 86 | } 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /NitroFileLoader/SoundFont2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/NitroFileLoader/SoundFont2.dll -------------------------------------------------------------------------------- /NitroFileLoader/WaveArchive.cs: -------------------------------------------------------------------------------- 1 | using GotaSoundIO; 2 | using GotaSoundIO.IO; 3 | using GotaSoundIO.Sound; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace NitroFileLoader { 11 | 12 | /// 13 | /// Wave archive. 14 | /// 15 | public class WaveArchive : IOFile { 16 | 17 | /// 18 | /// Waves. 19 | /// 20 | public List Waves = new List(); 21 | 22 | /// 23 | /// Read the wave archive. 24 | /// 25 | /// The reader. 26 | public override void Read(FileReader r) { 27 | 28 | //Open data. 29 | r.OpenFile(out _); 30 | r.OpenBlock(0, out _, out _, false); 31 | r.ReadUInt32(); 32 | uint size = r.ReadUInt32(); 33 | r.ReadUInt32s(8); 34 | var offs = r.Read>(); 35 | Waves = new List(); 36 | for (int i = 0; i < offs.Count; i++) { 37 | uint len; 38 | if (i == offs.Count - 1) { 39 | len = size - (offs[i] - 0x10); 40 | } else { 41 | len = offs[i + 1] - offs[i]; 42 | } 43 | r.Jump(offs[i], true); 44 | Waves.Add(Wave.ReadShortened(r, len)); 45 | } 46 | 47 | } 48 | 49 | /// 50 | /// Write the wave archive. 51 | /// 52 | /// The writer. 53 | public override void Write(FileWriter w) { 54 | 55 | //Write the wave archive. 56 | w.InitFile("SWAR", ByteOrder.LittleEndian, null, 1); 57 | w.InitBlock("DATA"); 58 | w.Write(new uint[8]); 59 | w.Write((uint)Waves.Count()); 60 | long bak = w.Position; 61 | w.Write(new uint[Waves.Count()]); 62 | for (int i = 0; i < Waves.Count(); i++) { 63 | long bak2 = w.Position; 64 | w.Position = bak + i * 4; 65 | w.Write((uint)(bak2 - w.FileOffset)); 66 | w.Position = bak2; 67 | Waves[i].WriteShortened(w); 68 | } 69 | w.Pad(4); 70 | w.CloseBlock(); 71 | w.CloseFile(); 72 | 73 | } 74 | 75 | /// 76 | /// Get the waves. 77 | /// 78 | /// The wave files. 79 | public RiffWave[] GetWaves() { 80 | RiffWave[] w = new RiffWave[Waves.Count]; 81 | for (int i = 0; i < Waves.Count; i++) { 82 | w[i] = new RiffWave(); 83 | w[i].FromOtherStreamFile(Waves[i]); 84 | } 85 | return w; 86 | } 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nitro Studio 2 2 | If Nitro Studio was so good, why isn't there a Nitro Studio 2? Well it was so good so now there's a 2nd one that's even better. It's a lot easier to use over the original and has a ton of new features! Try it out! 3 | 4 | # Dependencies 5 | This tool requires my SoundIO, Sound Bank and Sequence libraries. 6 | 7 | SoundIO: https://github.com/Gota7/GotaSoundIO 8 | 9 | Sound Bank: https://github.com/Gota7/GotaSoundBank 10 | 11 | Sequence Lib: https://github.com/Gota7/GotaSequenceLib 12 | 13 | Please see the website here: 14 | https://gota7.github.io/NitroStudio2/ 15 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker 2 | -------------------------------------------------------------------------------- /docs/favIcon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/favIcon.ico -------------------------------------------------------------------------------- /docs/guide/bankEditor.md: -------------------------------------------------------------------------------- 1 | # Bank Editor 2 | The Bank Editor is used to edit Banks. The Bank Editor adds a few new parts to the window. Each instrument index plus one corresponds to its MIDI program number 3 | 4 | ## New Window Additions 5 | This section covers the new items added to the window. However, these rely on the parent Sound Archive. These items will only appear if a Sound Archive is opened in the Main Window. 6 | 7 | ### Wave Archive List 8 | The Wave Archive List shows what Wave Archives are hooked up to the Bank. If the list is modified for the sake of emulation, it will not change the Wave Archives hooked up to the Bank in the Sound Archive, as the Wave Archive list is just for previewing. 9 | 10 | ![alt text](img/waveArchiveList.png "Wave Archive List.") 11 | 12 | Wave Archive 0 - What Wave Archive to use when a Region's Wave Archive Id is 0. 13 | 14 | Wave Archive 1 - What Wave Archive to use when a Region's Wave Archive Id is 1. 15 | 16 | Wave Archive 2 - What Wave Archive to use when a Region's Wave Archive Id is 2. 17 | 18 | Wave Archive 3 - What Wave Archive to use when a Region's Wave Archive Id is 3. 19 | 20 | ### Piano 21 | The piano can be used to preview an instrument. It has different colors for each Region within the instrument. 22 | 23 | ![alt text](img/piano.png "Piano divided into two Regions.") 24 | 25 | ## Instrument Info 26 | Each instrument has info that tells the Bank what type of instrument it is, and has information for each Region contained within it. 27 | 28 | ![alt text](img/instrumentInfo.png "Sample instrument info.") 29 | 30 | ### Instrument Type 31 | An instrument can be one of three main types: Direct, Drum Set, or Key Split. Nitro Studio 2 will only let you use a type of instrument allowed by the intrument's current list of Regions. 32 | 33 | #### Direct Instrument 34 | A Direct instrument contains exactly one Region that spans the entire keyboard. 35 | 36 | #### Drum Set 37 | A Drum Set contains Regions for sections of the keyboard. 38 | 39 | #### Key Split 40 | A Key Split instrument is like a Drum Set, but the first Region must start from note 0, and this instrument can only have 8 Regions maximum. 41 | 42 | ### Drum Set Range Start 43 | If the instrument is a Drum Set, the first Region will start from this note. 44 | 45 | ### Regions 46 | A Region is a section of the keyboard that tells the Sequence Player how to play a note. A Region starts from the previous Region's end note plus one, and ends at the Regions end note. If it is the first Region, the Region will start at 0, or start at what the Drum Set Range Start has set if the instrument is a Drum Set. For example, A list of Regions with the end notes 40, 59, and 127 defines 3 Regions: one from note 0 to 40, another from note 41 to 59, and one last one from 60 to 127. Note that if the instrument is a Drum Set and the Drum Set Range Start was nonzero, that would be where the first Region starts from. When a note is played, it will look for the Region containing that note and get the playback info for that note. 47 | 48 | End Note - The last note the Region consists of. 49 | 50 | Instrument Type - PCM means that the note will use a Wave sample from a linked Wave Archive. PSG will play an 8-bit noise. Noise will play white noise. Direct PCM was a dropped type and shouldn't be used. Null plays no sound. 51 | 52 | Wave Id / PSG Cycle - If the instrument is a PCM instrument, this is the Wave id in the linked Wave Archive. If it is a PSG instrument, this is the duty cycle. 53 | 54 | Wave Archive Id - If the instrument is a PCM instrument, this will be the index in the Wave Archive List to get the Wave data from. 55 | 56 | Base Note - The original key the Wave sample was recorded in. 57 | 58 | Attack - Attack value. See envelope for more info. 59 | 60 | Decay - Decay value. See envelope for more info. 61 | 62 | Sustain - Sustain value. See envelope for more info. 63 | 64 | Release - Release value. See envelope for more info. 65 | 66 | Pan - Shift the audio to the left or right, where 64 is the middle, 0 is the left, and 127 is the right. 67 | 68 | #### Envelope 69 | An envelope is used to modify how the volume of notes change over time. Here is a chart that visualizes the process: 70 | 71 | ![alt text](img/adsr.png "ADSR Curve.") 72 | 73 | Attack - How long it takes to reach the maximum note velocity. 74 | 75 | Decay - How long it takes from the maximum velocity to reach the sustain velocity. 76 | 77 | Sustain - Velocity for the note to sustain at. 78 | 79 | Release - How long it takes from the sustain velocity to get silence. 80 | 81 | ##### Attack Chart 82 | A chart that converts an attack value to a time in milliseconds. 83 | 84 | ![alt text](img/attackTable.png "Attack values converted to times in milliseconds.") 85 | 86 | ##### Decay/Release Chart 87 | A chart that converts a decay/release value to a time in milliseconds, assuming that sustain is it a maximum. 88 | 89 | ![alt text](img/decayReleaseTable.png "Decay/Release values converted to times in milliseconds.") 90 | 91 | ## Exporting/Replacing Instruments 92 | Instruments can be exported and replaced by using custom formats used by Nitro Studio 2. Using NS2I will contain audio sample data in the instrument, while a NIST file does not. Exporting them is fairly straight forward. 93 | 94 | When you replace an instrument with a NS2I file, for each audio sample in the NS2I, it will look through all of the Wave Archives in the Wave Archive List, and see if any of the Wave Archives contains that sample. If not, it will prompt you to choose which linked Wave Archive to save the audio sample to. 95 | 96 | ![alt text](img/bankWaveMapper.png "Wave Mapper prompting which Wave Archive to save the audio sample to.") 97 | 98 | # Next 99 | Now that you know how to edit Banks, it's time to move on to: 100 | 101 | [Wave Archive Editor](waveArchiveEditor.md) -------------------------------------------------------------------------------- /docs/guide/bankGenerator.md: -------------------------------------------------------------------------------- 1 | # Bank Generator 2 | The Bank Generator Tool is a tool that allows you to create a new Bank from instruments from other Banks. 3 | 4 | ![alt text](img/bankGenerator.png "Bank Generator Tool in action.") 5 | 6 | ## Play 7 | The play button will play middle C for a half note of the instrument that will be added to the new Bank. 8 | 9 | ## Bank 10 | The Bank to copy the instrument from. This list will only contain Banks that include at least one instrument. 11 | 12 | ## Instrument 13 | The instrument index inside of the source Bank to copy to the new Bank. 14 | 15 | ## New Id 16 | What new program number to assign the instrument in the new Bank. 17 | 18 | ## Wave Archive Mode 19 | This dictates how the instrument's audio data should be stored. 20 | 21 | Use Generated Wave Archive - Add the Wave files to a Wave Archive created along with the new Bank. 22 | 23 | Use Existing Wave Archive - Link the Bank to the Wave Archive storing the samples instead. 24 | 25 | ## Create Bank And Wave Archive 26 | Create a new Bank and Wave Archive from the instruments listed above. A new Wave Archive is only created when an instrument is selected to have its samples stored inside the generated Wave Archive. If there are more than 4 Wave Archives being used by the new Bank, a Bank can not be generated. To reduce this, have more instruments use the generated Wave Archive for storing samples. 27 | 28 | # Next 29 | Now that you know how to generate Banks, it's time to move on to: 30 | 31 | [Wave Creator](waveCreator.md) -------------------------------------------------------------------------------- /docs/guide/fileTypes.md: -------------------------------------------------------------------------------- 1 | # File Types 2 | When using Nitro Studio 2, you will encounter many different file types. 3 | 4 | | **Extension Name** | **Extension Description** | **SDAT Or Inside** | **Description** | 5 | |--------------------|---------------------------|--------------------|-----------------| 6 | |SDAT|Sound DATa|Yes|This is the binary format of the Sound Archive| 7 | |SARC|Sound ARChive|No|This is the SDK's text format of a Sound Archive| 8 | |SPRJ|Sound PRoJect|No|This is a Sound Project file that is used by NITRO-SoundMaker to compile Sound Archives| 9 | |SSEQ|Sound SEQuence|Yes|This is the binary form of a Sequence, it's like an MIDI| 10 | |SMFT|SMF Text|No|This is the SDK's text format of a Sequence. It is described to be like an MIDI but in plain text| 11 | |MIDI|Musical Instrument Digital Interface|No|MIDI files don't contain sounds themselves, but rather tell instruments how to play sounds such as what notes to play| 12 | |SSAR|Sound Sequence ARchive|Yes|This is the binary form of a Sequence Archive. It is a long Sequence file that contains multiple entry points for each Sequence within the archive. It's kind of a collection of Sequences but in one file| 13 | |MUS|MUSic List|No|This is the SDK's text format of a Sequence Archive| 14 | |SBNK|Sound BaNK|Yes|This is the binary form of a Bank. It contains instruments that tell the Sequence Player how to play notes. However, this only references audio samples from Wave Archives for instruments and contains no audio samples in itself| 15 | |BNK|Bank|No|This is the SDK's text format of a Bank| 16 | |DLS|DownLoadable Sounds|No|This is used by PC MIDI editors as an instrument bank| 17 | |SF2|Sound Font 2|No|This is used by PC MIDI editors as an instrument bank| 18 | |NS2I|Nitro Studio 2 Instrument|No|An instrument format used in Nitro Studio 2 that contains instrument info and audio samples to easily exchange instruments between different banks| 19 | |NIST|Nitro Studio InSTrument|No|An instrument format used in Nitro Studio that contains instrument info, but unlike NS2I doesn't contain audio samples| 20 | |SWAR|Sound Wave ARchive|Yes|This is the binary form of a Wave Archive. It contains Wave files| 21 | |SWLS|Sound Wave LiSt|No|This is the SDK's text format of a Wave Archive| 22 | |SWAV|Sound Wave|Yes|This is the binary form of a Wave. It contains audio sample data| 23 | |WAV|WAVe|No|This is a standard wave file used by PCs| 24 | |STRM|STReaM|Yes|This is the binary form of a Stream that contains audio sample data| 25 | 26 | # Next 27 | Now that you understand all the different kinds of files used, it's time to move on to: 28 | 29 | [Sequence Commands](sequenceCommands.md) -------------------------------------------------------------------------------- /docs/guide/img/aboutMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/aboutMenu.png -------------------------------------------------------------------------------- /docs/guide/img/aboutWindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/aboutWindow.png -------------------------------------------------------------------------------- /docs/guide/img/adsr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/adsr.png -------------------------------------------------------------------------------- /docs/guide/img/attackTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/attackTable.png -------------------------------------------------------------------------------- /docs/guide/img/bankGenerator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/bankGenerator.png -------------------------------------------------------------------------------- /docs/guide/img/bankInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/bankInfo.png -------------------------------------------------------------------------------- /docs/guide/img/bankWaveMapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/bankWaveMapper.png -------------------------------------------------------------------------------- /docs/guide/img/createStream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/createStream.png -------------------------------------------------------------------------------- /docs/guide/img/createWave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/createWave.png -------------------------------------------------------------------------------- /docs/guide/img/dataGrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/dataGrid.png -------------------------------------------------------------------------------- /docs/guide/img/decayReleaseTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/decayReleaseTable.png -------------------------------------------------------------------------------- /docs/guide/img/editMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/editMenu.png -------------------------------------------------------------------------------- /docs/guide/img/fileMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/fileMenu.png -------------------------------------------------------------------------------- /docs/guide/img/forceUniqueFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/forceUniqueFile.png -------------------------------------------------------------------------------- /docs/guide/img/groupInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/groupInfo.png -------------------------------------------------------------------------------- /docs/guide/img/helpMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/helpMenu.png -------------------------------------------------------------------------------- /docs/guide/img/instrumentInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/instrumentInfo.png -------------------------------------------------------------------------------- /docs/guide/img/itemIndex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/itemIndex.png -------------------------------------------------------------------------------- /docs/guide/img/itemIndexPanel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/itemIndexPanel.png -------------------------------------------------------------------------------- /docs/guide/img/itemInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/itemInfo.png -------------------------------------------------------------------------------- /docs/guide/img/itemInfoPanel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/itemInfoPanel.png -------------------------------------------------------------------------------- /docs/guide/img/itemTree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/itemTree.png -------------------------------------------------------------------------------- /docs/guide/img/mainMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/mainMenu.png -------------------------------------------------------------------------------- /docs/guide/img/openSequenceArchiveFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/openSequenceArchiveFile.png -------------------------------------------------------------------------------- /docs/guide/img/piano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/piano.png -------------------------------------------------------------------------------- /docs/guide/img/saveWarning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/saveWarning.png -------------------------------------------------------------------------------- /docs/guide/img/sequenceInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/sequenceInfo.png -------------------------------------------------------------------------------- /docs/guide/img/sequencePlayerInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/sequencePlayerInfo.png -------------------------------------------------------------------------------- /docs/guide/img/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/settings.png -------------------------------------------------------------------------------- /docs/guide/img/soundPlayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/soundPlayer.png -------------------------------------------------------------------------------- /docs/guide/img/statusBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/statusBar.png -------------------------------------------------------------------------------- /docs/guide/img/streamInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/streamInfo.png -------------------------------------------------------------------------------- /docs/guide/img/streamPlayerInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/streamPlayerInfo.png -------------------------------------------------------------------------------- /docs/guide/img/toolsMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/toolsMenu.png -------------------------------------------------------------------------------- /docs/guide/img/waveArchiveInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/waveArchiveInfo.png -------------------------------------------------------------------------------- /docs/guide/img/waveArchiveList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/waveArchiveList.png -------------------------------------------------------------------------------- /docs/guide/img/windowBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/windowBar.png -------------------------------------------------------------------------------- /docs/guide/img/windowLayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gota7/NitroStudio2/e9feb3e4f0271db802f2cdcc15308cb90d70b6c2/docs/guide/img/windowLayout.png -------------------------------------------------------------------------------- /docs/guide/sequenceArchiveEditor.md: -------------------------------------------------------------------------------- 1 | # Sequence Archive Editor 2 | The Sequence Archive Editor is used to edit Sequence Archives. Unfortunately, there's a lot to it and I'm just too tired at the moment so please just move on to the next section. 3 | 4 | # Next 5 | Now that you know how to edit Sequence Archives, it's time to move on to: 6 | 7 | [Bank Editor](bankEditor.md) -------------------------------------------------------------------------------- /docs/guide/sequenceCommands.md: -------------------------------------------------------------------------------- 1 | # Sequence Commands 2 | When editing Sequences or Sequence Archives you are bound to run into Sequence commands. Sequence commands can also be specified via MIDI controls when the MIDI is converted to a Sequence. 3 | 4 | ## Notes 5 | Notes are specified by note name, type, and number. For example, `cn4` is C Note 4, and `gs5` is G Sharp 5. Instead of saying B Flat, you would have to say A Sharp. The higher the number, the higher the octave. Minus 1 notes also exist, which look like `cnm1` or C Note Minus 1. You can specify a note from `cnm1` to `gn9`. Middle C is `cn4`. Here is a table that lists all the possible notes and gives their MIDI number. 6 | 7 | | **Note** | **Number** | 8 | |----------|------------| 9 | |cnm1|0| 10 | |csm1|1| 11 | |dnm1|2| 12 | |dsm1|3| 13 | |enm1|4| 14 | |fnm1|5| 15 | |fsm1|6| 16 | |gnm1|7| 17 | |gsm1|8| 18 | |anm1|9| 19 | |asm1|10| 20 | |bnm1|11| 21 | |cn0|12| 22 | |cs0|13| 23 | |dn0|14| 24 | |ds0|15| 25 | |en0|16| 26 | |fn0|17| 27 | |fs0|18| 28 | |gn0|19| 29 | |gs0|20| 30 | |an0|21| 31 | |as0|22| 32 | |bn0|23| 33 | |cn1|24| 34 | |cs1|25| 35 | |dn1|26| 36 | |ds1|27| 37 | |en1|28| 38 | |fn1|29| 39 | |fs1|30| 40 | |gn1|31| 41 | |gs1|32| 42 | |an1|33| 43 | |as1|34| 44 | |bn1|35| 45 | |cn2|36| 46 | |cs2|37| 47 | |dn2|38| 48 | |ds2|39| 49 | |en2|40| 50 | |fn2|41| 51 | |fs2|42| 52 | |gn2|43| 53 | |gs2|44| 54 | |an2|45| 55 | |as2|46| 56 | |bn2|47| 57 | |cn3|48| 58 | |cs3|49| 59 | |dn3|50| 60 | |ds3|51| 61 | |en3|52| 62 | |fn3|53| 63 | |fs3|54| 64 | |gn3|55| 65 | |gs3|56| 66 | |an3|57| 67 | |as3|58| 68 | |bn3|59| 69 | |cn4|60| 70 | |cs4|61| 71 | |dn4|62| 72 | |ds4|63| 73 | |en4|64| 74 | |fn4|65| 75 | |fs4|66| 76 | |gn4|67| 77 | |gs4|68| 78 | |an4|69| 79 | |as4|70| 80 | |bn4|71| 81 | |cn5|72| 82 | |cs5|73| 83 | |dn5|74| 84 | |ds5|75| 85 | |en5|76| 86 | |fn5|77| 87 | |fs5|78| 88 | |gn5|79| 89 | |gs5|80| 90 | |an5|81| 91 | |as5|82| 92 | |bn5|83| 93 | |cn6|84| 94 | |cs6|85| 95 | |dn6|86| 96 | |ds6|87| 97 | |en6|88| 98 | |fn6|89| 99 | |fs6|90| 100 | |gn6|91| 101 | |gs6|92| 102 | |an6|93| 103 | |as6|94| 104 | |bn6|95| 105 | |cn7|96| 106 | |cs7|97| 107 | |dn7|98| 108 | |ds7|99| 109 | |en7|100| 110 | |fn7|101| 111 | |fs7|102| 112 | |gn7|103| 113 | |gs7|104| 114 | |an7|105| 115 | |as7|106| 116 | |bn7|107| 117 | |cn8|108| 118 | |cs8|109| 119 | |dn8|110| 120 | |ds8|111| 121 | |en8|112| 122 | |fn8|113| 123 | |fs8|114| 124 | |gn8|115| 125 | |gs8|116| 126 | |an8|117| 127 | |as8|118| 128 | |bn8|119| 129 | |cn9|120| 130 | |cs9|121| 131 | |dn9|122| 132 | |ds9|123| 133 | |en9|124| 134 | |fn9|125| 135 | |fs9|126| 136 | |gn9|127| 137 | 138 | ## Labels 139 | A label is used as a marker. It has its own line, and followed by a colon. For example, `Label_0:` would be a label named `Label_0`. 140 | 141 | ### Private Labels 142 | Labels that start with `_` are private labels and can only be accessed by all commands between the last nonprivate label and the next nonprivate label. However, due to how the Sequence library is programmed, this rule is ignored. 143 | 144 | ## Standard Commands 145 | A command is used to do something. A command can take up to 2 parameters. The equation to converting the volume to a percentage is (Volume / 127) ^ 2 * (Volume2 / 127) ^ 2 * 100. 146 | 147 | | **Command Name** | **Parameter 1** | **Parameter 2** | **MIDI Control** | **Example** | **Description** | 148 | |------------------|-----------------|-----------------|------------------|-------------|-----------------| 149 | |Note|Velocity (0 - 127)|Duration In Ticks (0 - 268435455)|Note On|cn4 127, 48|Plays Middle C with velocity 127 for 48 ticks| 150 | |Wait|Duration In Ticks (0 - 268435455)|N/A|N/A|wait 48|Waits for 48 ticks before continuing| 151 | |Open Track|Track Number (0 - 15)|Label To Start The Track At|N/A|opentrack 3, SeqTrack3|Starts track 3 at the label `SeqTrack3`| 152 | |Jump|Label To Jump To|N/A|Using Nitro Studio 2's converter, a marker with `jump` then followed by a space then the label name|jump SeqMiddle|Jumps to the label `SeqMiddle`. Jumps are usually used for looping| 153 | |Call|Label To Call|N/A|N/A|call SeqPart3|Jumps to the label `SeqPart3` then returns once a Return command is found| 154 | |Pan|Value (0 - 127) Where 64 Is Center, 127 Is All Right, 0 Is All Left|N/A|10|pan 75|Sets the track's pan slightly to the right. Default is 64| 155 | |Volume|Value (0 - 127)|N/A|7|volume 100|Sets the track's volume to 100| 156 | |Main Volume|Value (0 - 127)|N/A|12|main_volume 100|Set's the player's volume to 100. Default is 127| 157 | |Transpose|Value (-64 - 63)|N/A|13|transpose 2|Makes every note 2 semitones higher. Default is 0| 158 | |Pitch Bend|Value (-128 - 127)|N/A|Pitch Wheel|pitchbend 100|Adjusts the pitch to be (100 / 127) ^ 2 * 100 times the Bend Range semitones. Default is 0| 159 | |Bend Range|Value (0 - 127)|N/A|20|bendrange 12|Sets the bend range to be 12 semitones. The default is two. In this example, if a pitchbend of 127 was used, the pich would go up by 12 semitones| 160 | |Priority|Value (0 - 127)|N/A|14|prio 70|Sets the track's priority to 70. Default is 64| 161 | |Note Wait|_on or _off|N/A|N/A|notewait_off|Does not wait for a note to finish before continuing. Default is on| 162 | |Tie|on or off|N/A|N/A|tieon|Notes don't end and new notes just change the pitch and velocity of the playing note. Default is off| 163 | |Portamento|Value (0 - 127)|N/A|84|porta 100|Sets the track's portamento to 100| 164 | |MOD STUFF!!!| 165 | -------------------------------------------------------------------------------- /docs/guide/sequenceEditor.md: -------------------------------------------------------------------------------- 1 | # Sequence Editor 2 | The Sequence Editor is used to edit Sequences. Unfortunately, there's a lot to it and I'm just too tired at the moment so please just move on to the next section. 3 | 4 | # Next 5 | Now that you know how to edit Sequences, it's time to move on to: 6 | 7 | [Sequence Archive Editor](sequenceArchiveEditor.md) -------------------------------------------------------------------------------- /docs/guide/sf2DlsImporter.md: -------------------------------------------------------------------------------- 1 | # DLS/SF2 Importer 2 | The DLS/SF2 Importer is used to replace a Bank and with the instruments of a DLS/SF2, and add the necessary Waves to its linked Wave Archives. 3 | 4 | -------------------------------------------------------------------------------- /docs/guide/streamCreator.md: -------------------------------------------------------------------------------- 1 | # Stream Creator 2 | The Stream Creator is used to create Stream files. 3 | 4 | ![alt text](img/createStream.png "Stream Creator.") 5 | 6 | ## Input File 7 | File to convert to a Stream. Note that converting from an IMA-ADPCM Wave is lossy. 8 | 9 | ## Output File 10 | Where to save the Stream. 11 | 12 | ## Format 13 | The encoding format for the destination Stream. IMA-ADPCM is the most efficient. 14 | 15 | # Next 16 | Now that you know how to create Streams, it's time to move on to: 17 | 18 | [DLS/SF2 Importer](sf2DlsImporter.md) -------------------------------------------------------------------------------- /docs/guide/waveArchiveEditor.md: -------------------------------------------------------------------------------- 1 | # Wave Archive Editor 2 | The Wave Archive Editor is used to edit Wave Archives. The Wave Archive Editor should function exactly as the rest of Nitro Studio 2, and so there is not really anything to say about it. 3 | 4 | # Next 5 | Now that you know how to edit Wave Archives, it's time to move on to: 6 | 7 | [Bank Generator](bankGenerator.md) -------------------------------------------------------------------------------- /docs/guide/waveCreator.md: -------------------------------------------------------------------------------- 1 | # Wave Creator 2 | The Wave Creator is used to create Wave files. 3 | 4 | ![alt text](img/createWave.png "Wave Creator.") 5 | 6 | ## Input File 7 | File to convert to a Wave. Note that converting from an IMA-ADPCM Stream is lossy. 8 | 9 | ## Output File 10 | Where to save the Wave. 11 | 12 | ## Format 13 | The encoding format for the destination Wave. IMA-ADPCM is the most efficient. 14 | 15 | # Next 16 | Now that you know how to create Waves, it's time to move on to: 17 | 18 | [Stream Creator](streamCreator.md) -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # About Nitro Studio 2 2 | Nitro Studio 2 is an editor for Nintendo DS sound archives (SDAT) which contain music, sound effects, and anything audio related in general. Nitro Studio 2 is a sequel to my previous DS music editor, Nitro Studio. I felt that I could add a lot more features and make the program easier and intuitive to use by starting from scratch, and I'd say I succeeded. This editor has a lot more features than the old one. 3 | 4 | ## New Features 5 | Some new features include: 6 | 7 | * Sequence editor. 8 | * Sequence archive editor. 9 | * Sequence archive sequence playback. 10 | * Exporting sequences as WAV. 11 | * Custom MIDI importer/exporter, with the option to use the old one, or even use Nintendo's SDK importer provided you have it. 12 | * SF2/DLS exporting/importing. 13 | * SF2 <-> DLS conversion. 14 | * More accurate saving. 15 | * More accurate SDK exporting. 16 | * New and improved bank editor and bank generator. 17 | * Ability to create SWAVs and STRMs from the tools menu and decide the target encoding. 18 | * Batch exporting MIDI, SF2, and DLS. 19 | * Importing and exporting instruments includes sample data. 20 | * Ability to open any file standalone with Nitro Studio 2. 21 | * Better group editing. 22 | * Better usability and feel overall. 23 | * Trackbar to change position. 24 | * And more! 25 | 26 | ## Downloads 27 | Coming soon! :} 28 | *Cough- Betas are on my discord. -Cough* 29 | 30 | Beta: https://cdn.discordapp.com/attachments/440493269110095876/746771176701034506/Nitro_Studio_2.rar 31 | 32 | Known Bugs: 33 | * Not all buttons work. 34 | * Audio conversion of any kind is faulty. 35 | * Nitro Studio 2 sequence converters are incomplete. 36 | 37 | ## Guide 38 | Don't know where to start? Need help figuring out what something does or how to use a particular tool? Then please read the guides below to answer your own questions. 39 | 40 | [General Editor Controls](guide/generalEditorControls.md) - Goes over the general layout and controls of Nitro Studio 2. 41 | 42 | [Sound Archive General Structure](guide/soundArchive.md) - Explains how the sound archive works as a whole, and the individual parameters for each item. 43 | 44 | [File Types](guide/fileTypes.md) - Goes over the different files that Nitro Studio 2 interacts with. 45 | 46 | [Sequence Commands](guide/sequenceCommands.md) - A list of Sequence commands and their MIDI controllers. 47 | 48 | [Sequence Editor](guide/sequenceEditor.md) - Describes how to use the Sequence Editor. 49 | 50 | [Sequence Archive Editor](guide/sequenceArchiveEditor.md) - Describes how to use the Sequence Archive Editor. 51 | 52 | [Bank Editor](guide/bankEditor.md) - Describes how to use the Bank Editor. 53 | 54 | [Wave Archive Editor](guide/waveArchiveEditor.md) - Describes how to use the Wave Archive Editor. 55 | 56 | [Bank Generator](guide/bankGenerator.md) - Tells you how to create a new Bank from instruments in other Banks. 57 | 58 | [Wave Creator](guide/waveCreator.md) - Shows how to create a Wave. 59 | 60 | [Stream Creator](guide/streamCreator.md) - Shows how to create a Stream. 61 | 62 | [DLS/SF2 Importer](guide/sf2DlsImporter.md) - Looks at importing an SF2/DLS. 63 | 64 | [Putting It All Together: Adding A Song From The Ground Up](guide/finalTest.md) - Goes through the process of adding a new song. 65 | 66 | ## Discord 67 | Need human support as the guides were not sufficient? Found a bug? Want a feature added? Want to get updates or early access to programs I'm working on? 68 | [Then join my discord!](https://discord.gg/6VDPGne) 69 | 70 | ## File Specifications 71 | In case you are a programmer and wish to develop your own tools related to the SDAT, wish to edit parts of files manually, or are just curious about the structure of the formats in general, you can look at the specifications of the different files used within the SDAT below. 72 | 73 | [Common Structures](specs/common.md) - Common structures found throughout the sound archive and its sub-files. 74 | 75 | [Sound Data (SDAT)](specs/soundData.md) - Sound data that contains everything. 76 | 77 | [Sequences (SSEQ)](specs/sequence.md) - Sequences used to play music. 78 | 79 | [Sequence Archives (SSAR)](specs/sequenceArchive.md) - Sequence archives contain a bunch of sequences used to play SFX. 80 | 81 | [Banks (SBNK)](specs/bank.md) - Banks that contain instruments to use with sequences. 82 | 83 | [Wave Archives (SWAR)](specs/waveArchive.md) - Wave archives used to store wave files. 84 | 85 | [Waves (SWAV)](specs/wave.md) - Waves that are used for instrument and SFX samples. 86 | 87 | [Streams (STRM)](specs/stream.md) - Streams to play music and SFX. 88 | 89 | ## Credits 90 | I couldn't have done this alone of course! 91 | 92 | * Nintendo, Images, SDAT Info. 93 | * Kermalis, Sequence Player Base 94 | * Eugene, Testing, Suggestions, Guide. 95 | * Goji Goodra, Testing, Suggestions. 96 | * Josh, SDAT Research. 97 | * Crystal, SDAT Research. 98 | * Nintendon, SDAT Research. 99 | * DJ Bouche, SDAT Research. 100 | * VGMTrans, SDAT Research. 101 | * LoveEmu, SDAT Research, Tools. 102 | * Gota7, Nitro Studio. 103 | 104 | ©2020 Gota7 105 | -------------------------------------------------------------------------------- /docs/specs/bank.md: -------------------------------------------------------------------------------- 1 | # Banks (.sbnk) 2 | SBNKs or Sound Banks contain instrument information. 3 | 4 | ## The Main File 5 | The main file contains of a File Header and a Data Block. 6 | 7 | | **Type** | **Description** | 8 | |----------|-----------------| 9 | |SoundFileHeader|Sound File Header (Magic: SBNK. Always contains 1 block)| 10 | |Block|Data Block| 11 | 12 | ## Data Block Body (Magic: DATA) 13 | Contains all the instruments used in the bank. 14 | 15 | | **Offset** | **Type** | **Description** | 16 | |------------|----------|-----------------| 17 | |0x00|u32[8]|Padding| 18 | |0x20|Table<`InstrumentEntry`>|Instrument Entries| 19 | |----|Instrument[NumInstruments]|Instruments| 20 | 21 | ### Instrument Entry 22 | Each instrument has an entry as follows. If the offset is 0, then the instrument is null and has no data. 23 | 24 | | **Offset** | **Type** | **Description** | 25 | |------------|----------|-----------------| 26 | |0x00|InstrumentType|Instrument Type| 27 | |0x01|a16|Absolute offset to instrument data| 28 | |0x03|u8|Padding| 29 | 30 | #### Instrument Type 31 | An enumeration of the instrument type. Each type is a byte each. 32 | 33 | | **Identifier** | **Description** | 34 | |----------------|-----------------| 35 | |0|Null (no note info whatsoever)| 36 | |1|PCM| 37 | |2|PSG| 38 | |3|White Noise| 39 | |4|Direct PCM (Unused)| 40 | |5|Null (has note info but 0'd out)| 41 | |16|Drum Set| 42 | |17|Key Split| 43 | 44 | ## Instruments 45 | Depending on the type of instrument, its data will differ. 46 | 47 | ### Direct Instrument 48 | This is the default instrument type and has a single note info for the entire key range. Instrument type is decided from the instrument entry linking to this. 49 | 50 | | **Offset** | **Type** | **Description** | 51 | |------------|----------|-----------------| 52 | |0x00|NoteInfo|Note Info| 53 | 54 | ### Drum Set Instrument 55 | This defines instruments individually for a key range. It can not contain another drum set or key split instrument. 56 | 57 | | **Offset** | **Type** | **Description** | 58 | |------------|----------|-----------------| 59 | |0x00|u8|Lower Key| 60 | |0x01|u8|Upper Key| 61 | |0x02|ContainedDirectInstrument[UpperKey - LowerKey + 1]|Instrument data for each key| 62 | 63 | ### Key Split Instrument 64 | This defines instruments to certain regions of the keyboard. It can not contain another drum set or key split instrument. 65 | 66 | | **Offset** | **Type** | **Description** | 67 | |------------|----------|-----------------| 68 | |0x00|u8[8]|Regions. A region works by the key to the byte specified. For example, { 40, 57, 60, 90, 127, 0, 0, 0 } means that there are 5 regions: 0-40, 41-57, 58-60, 61-90, 91-127| 69 | |0x08|ContainedDirectInstrument[NumActualRegions]|Instrument data for each region| 70 | 71 | ### Contained Direct Instrument 72 | A direct instrument inside of a drum set or key split instrument in it has an identifer. 73 | 74 | | **Offset** | **Type** | **Description** | 75 | |------------|----------|-----------------| 76 | |0x00|u8|Padding| 77 | |0x01|InstrumentType|Instrument Type| 78 | |0x02|NoteInfo|Note Info| 79 | 80 | ### Note Info 81 | This is how you play back a note. 82 | 83 | | **Offset** | **Type** | **Description** | 84 | |------------|----------|-----------------| 85 | |0x00|u16|Wave Id (PCM) or Duty Cycle Type (PSG)| 86 | |0x02|u16|Wave Archive Id (PCM) is hooked up to the wave archives specified by the sound data archive for the bank info that uses this file| 87 | |0x04|u8|Base Note| 88 | |0x05|u8|Attack| 89 | |0x06|u8|Decay| 90 | |0x07|u8|Sustain| 91 | |0x08|u8|Release| 92 | |0x09|u8|Pan| -------------------------------------------------------------------------------- /docs/specs/common.md: -------------------------------------------------------------------------------- 1 | # Common Structures 2 | In every type of sound file, you are bound to come across at least one of these structures. Rather than redefining them for each file, it would be better to define them all here for simplicity. 3 | 4 | ## Primitive Types 5 | Every structure is made of the following primitive types. You will come across the following: 6 | 7 | | **Type** | **Description** | 8 | |----------|-----------------| 9 | |u8|8-bit Unsigned Integer| 10 | |u16|16-bit Unsigned Integer| 11 | |u24|32-bit Unsigned Integer| 12 | |u32|32-bit Unsigned Integer| 13 | |r32|32-bit Relative Offset| 14 | |a16|16-bit Absolute Offset| 15 | |a32|32-bit Absolute Offset| 16 | |s8|8-bit Signed Integer| 17 | |s16|16-bit Signed Integer| 18 | |s32|32-bit Signed Integer| 19 | |bool|8-bit Value That's 0 If False| 20 | |string|Since NintendoWare was coded in C++, every string is null terminated and includes '\0' at the end. This null terminator is included in the length of the string| 21 | |char[Array Size]|Char Array. This is like a string, except that it does not have a null terminator, and always has a fixed size| 22 | |VL|A variable length parameter. To read it, read a byte, binary and it with 0x7F, and if binary anding the original value by 0x80 is 1, shift that value left 7 bits, and binary or it with the same process you just did for the next bytes, until anding the value with 0x80 is 0| 23 | 24 | A relative offset is relative to the start of a block. An absolute offset is relative to the start of a file. An offset of 0 means it is a null pointer, and so contains null or no data. 25 | 26 | ## Sound File Header 27 | This is essential for the game to know how to read the data in the file. It is always 0x10 bytes. 28 | 29 | | **Offset** | **Type** | **Description** | 30 | |------------|----------|-----------------| 31 | |0x00|char[4]|Magic identifer for the file| 32 | |0x04|u16|Byte order. 0xFEFF for big endian, and 0xFFFE for little endian. Note, that these values I gave are in big endian| 33 | |0x06|Version|Version of this file. It is always 1.0| 34 | |0x08|u32|Size of this file| 35 | |0x0C|u16|Size of this header| 36 | |0x0E|u16|Number of blocks in the file| 37 | 38 | ### File Version 39 | Version is in the format 0xAABB, where AA is the major version, and BB is the minor version. For example, 0x0100 is 1.0. 40 | 41 | ## Block 42 | A block has a header and a size, and is always padded to 0x4 bytes. Any offset encountered in a block, unless otherwise specified, is relative to the start of that block. 43 | 44 | | **Offset** | **Type** | **Description** | 45 | |------------|----------|-----------------| 46 | |0x00|char[4]|Magic identifer for the block| 47 | |0x08|u32|Size of this block (including this block header)| 48 | |0x0C|u8[BlockSize - 8]|Block body. This is interpreted differently for every file| 49 | |----|---|Padding for 0x4 alignment| 50 | 51 | ## Sound Encoding 52 | Sound encoding is one byte, and has the following enumeration: 53 | 54 | | **Identifier** | **Description** | 55 | |----------------|-----------------| 56 | |0|Signed PCM8| 57 | |1|Signed PCM16| 58 | |2|4-bit IMA-ADPCM| 59 | 60 | ## Table<`Type T`> 61 | This contains a collection of whatever the Type T is. For example, a table could contain u8s, u32s, or anything else. Tables are always padded to 0x4 bytes. 62 | 63 | | **Offset** | **Type** | **Description** | 64 | |------------|----------|-----------------| 65 | |0x00|u32|Number of entries| 66 | |0x04|T[Number of entries]|An array of Type T, with the number of entries set to the value above| 67 | |----|---|Padding for alignment| -------------------------------------------------------------------------------- /docs/specs/sequence.md: -------------------------------------------------------------------------------- 1 | # Sequences (.sseq) 2 | SSEQs or Sound Sequences are like MIDI files, except for the NDS. They execute instructions for instruments to play. 3 | 4 | ## The Main File 5 | The main file contains of a File Header and a Data Block. 6 | 7 | | **Type** | **Description** | 8 | |----------|-----------------| 9 | |SoundFileHeader|Sound File Header (Magic: SSEQ. Always contains 1 block)| 10 | |Block|Data Block| 11 | 12 | ## Data Block Body (Magic: DATA) 13 | Contains sequence commands to execute. 14 | 15 | | **Offset** | **Type** | **Description** | 16 | |------------|----------|-----------------| 17 | |0x00|a32|Absolute offset from the start of the SSEQ file to the sequence data| 18 | |0x08|u8[BlockSize - 0xC - PaddingSize]|Sequence commands. Remember that all blocks are padded to 0x4 bytes, so remove 0s from the end until you hit 0xFF to get an accurate list of data| 19 | 20 | ### Sequence Commands 21 | Here is a table of sequence commands. Each sequence command has a u8 identifier and can be followed by parameters. P1 is parameter one, where P2 is parameter two, etc. In the event that the parameter is a sequence command, the last primary data type for it is not to be read. For example, a variable command that contains a note parameter will not have the variable length parameter (the note length) read, but after that note command is read the variable number for the variable command will be. All offsets are relative to the start of the sequence data. 22 | 23 | | **Identifier** | **Parameters** | **Read Last Parameter In Sequence Command?** | **Command Name** | **Description ** | 24 | |0x00 - 0x7F|u8, VL|NA|Note Command|Plays the specified key with a velocity of P1 for P2 ticks| 25 | |0x80|VL|NA|Wait|Wait for P1 ticks before continuing| 26 | |0x93|u8, VL|NA|Open Track|Open track P1 whose data starts at offset P2| 27 | |0x94|u24|NA|Jump|Jump to offset P1| 28 | |0x95|u24|NA|Call|Jump to offset P1 to execute the instructions there, then resume playback after the return command is encountered| 29 | |0xA0|Sequence Command, s16, s16|No|Random|Replaces the last parameter of P1 with a random number between P2 and P3| 30 | |0xA1|Sequence Command, u8|No|Variable|Replaces the last parameter of P1 with the value of variable P2| 31 | |0xA2|Sequence Command|Yes|If|Executes P1 if the track's conditional flag is set| 32 | |0xB0|u8, s16|NA|Set Variable|Sets variable P1 to have the value P2| 33 | |0xB1|u8, s16|NA|Add Variable|Adds P2 to the variable P1| 34 | |0xB2|u8, s16|NA|Subtract Variable|Subtracts P2 from the variable P1| 35 | |0xB3|u8, s16|NA|Multiply Variable|Multiplies variable P1 by P2| 36 | |0xB4|u8, s16|NA|Divide Variable|Divides variable P1 by P2| 37 | |0xB5|u8, s16|NA|Shift Variable|Sets variable P1 to have the value P2| 38 | |0xB6|u8, s16|NA|Random Variable|Sets variable P1 to have a random value between and including 0 and P2| 39 | |0xB8|u8, s16|NA|Compare Equal|If variable P1 equals P2, set the track conditional flag, else reset the flag| 40 | |0xB9|u8, s16|NA|Compare Greater Than Or Equal|If variable P1 is greater than or equal to P2, set the track conditional flag, else reset the flag| 41 | |0xBA|u8, s16|NA|Compare Greater Than|If variable P1 is greater than P2, set the track conditional flag, else reset the flag| 42 | |0xBB|u8, s16|NA|Compare Less Than Or Equal|If variable P1 is less than or equal to P2, set the track conditional flag, else reset the flag| 43 | |0xBC|u8, s16|NA|Compare Less Than|If variable P1 is less than P2, set the track conditional flag, else reset the flag| 44 | |0xBD|u8, s16|NA|Compare Not Equal|If variable P1 doesn't equal P2, set the track conditional flag, else reset the flag| 45 | |0xC0|u8|NA|Pan|Sets the track panning to P1 where 0x40 is the center| 46 | |0xC1|u8|NA|Volume|Sets the track volume to P1| 47 | |0xC2|u8|NA|Main Volume|Sets the player volume to P1| 48 | |0xC3|s8|NA|Transpose|Sets the track transpose to P1| 49 | |0xC4|s8|NA|Pitchbend|Sets the track pitch bend to P1| 50 | |0xC5|u8|NA|Bend Range|Sets the track bend range to P1| 51 | |0xC6|u8|NA|Priority|Sets the track priority to P1| 52 | |0xC7|bool|NA|Note Wait|Is off by default, but if on waits for a note to finish before continuing| 53 | |0xC8|bool|NA|Tie|If on, notes don't end and new notes just change the pitch and velocity of the playing note| 54 | |0xC9|u8|NA|Portamento|Sets track portamento to P1| 55 | |0xCA|u8|NA|Mod Depth|Sets the track mod depth to P1| 56 | |0xCB|u8|NA|Mod Speed|Sets the track mod speed to P1| 57 | |0xCC|u8|NA|Mod Type|Sets the track mod type to P1| 58 | |0xCD|u8|NA|Mod Range|Sets the track mod range to P1| 59 | |0xCE|bool|NA|Portamento Switch|Enters or cancels portamento mode| 60 | |0xCF|u8|NA|Portamento Time|Sets the portamento time to P1| 61 | |0xD0|u8|NA|Attack|Sets the envelope attack to P1| 62 | |0xD1|u8|NA|Decay|Sets the envelope decay to P1| 63 | |0xD2|u8|NA|Sustain|Sets the envelope sustain to P1| 64 | |0xD3|u8|NA|Release|Sets the envelope release to P1| 65 | |0xD4|u8|NA|Loop Start|Sets the track loop start point, and loop P1 times. It is infinite if P1 is 0| 66 | |0xD5|u8|NA|Volume 2|Sets track volume 2 to P1| 67 | |0xD6|u8|NA|Print Variable|Print variable P1 to a debugger| 68 | |0xE0|s16|NA|Mod Delay|Sets the track mod delay to P1| 69 | |0xE1|s16|NA|Tempo|Sets the tempo to P1| 70 | |0xE2|s16|NA|Sweep Pitch|Sets the track sweep pitch to P1| 71 | |0xFC|None|NA|Loop End|End the track loop| 72 | |0xFD|None|NA|Return|Return from a call| 73 | |0xFE|u16|NA|Allocate Tracks|Bitflag P1 for how to allocate tracks| 74 | |0xFF|None|NA|Fin|End the track or sequence| -------------------------------------------------------------------------------- /docs/specs/sequenceArchive.md: -------------------------------------------------------------------------------- 1 | # Sequence Archives (.ssar) 2 | An SSAR or sound sequence archive is like a giant sequence that contains multiple entry points. Each of those entry points contain sequence info similar to that found in the main sound data archive. 3 | 4 | ## The Main File 5 | The main file contains of a File Header and a Data Block. 6 | 7 | | **Type** | **Description** | 8 | |----------|-----------------| 9 | |SoundFileHeader|Sound File Header (Magic: SSAR. Always contains 1 block)| 10 | |Block|Data Block| 11 | 12 | ## Data Block Body (Magic: DATA) 13 | Contains sequence entries, and sequence commands to execute. 14 | 15 | | **Offset** | **Type** | **Description** | 16 | |------------|----------|-----------------| 17 | |0x00|a32|Absolute offset from the start of the SSAR file to the sequence data. Formula for calulating is 0x20 + 12 * NumSequences| 18 | |0x04|Table<`SequenceEntry`>|Sequences| 19 | |----|u8[-]|See the SSEQ specification on how to parse the sequence commands. Just be sure to separate it from padding by removing 0s until 0xFF is reached| 20 | 21 | ### Sequence Entry 22 | Each sequence inside the sequence archive has the following layout: 23 | 24 | | **Offset** | **Type** | **Description** | 25 | |------------|----------|-----------------| 26 | |0x00|u32|Offset to start of the sequence's sequence data relative to the start of the sequence command data. The rest of the information is 0'd out if this is 0 as that means it is a null entry| 27 | |0x04|u16|Bank Id| 28 | |0x06|u8|Volume| 29 | |0x07|u8|Channel Priority| 30 | |0x08|u8|Player Priority| 31 | |0x09|u8|Player Id| 32 | |0x0A|u16|Padding| -------------------------------------------------------------------------------- /docs/specs/stream.md: -------------------------------------------------------------------------------- 1 | # Streams (.strm) 2 | STRMs or Streams are like WAV files, except that audio data is chunked and can be IMA-ADPCM encoded. 3 | 4 | ## The Main File 5 | The main file contains of a File Header and an Info Block. 6 | 7 | | **Type** | **Description** | 8 | |----------|-----------------| 9 | |SoundFileHeader|Sound File Header (Magic: STRM. Always contains 2 blocks)| 10 | |Block|Info Block| 11 | 12 | ## Head Block (Magic: HEAD) 13 | Contains information on how to read the audio data. 14 | 15 | | **Offset** | **Type** | **Description** | 16 | |------------|----------|-----------------| 17 | |0x00|SoundEncoding|Type of encoding for the data| 18 | |0x01|bool|If the sound loops| 19 | |0x02|u8|Number of audio channels| 20 | |0x03|u8|Padding| 21 | |0x04|u16|Sampling rate of the audio| 22 | |0x06|u16|Clock time of the audio (523655.96875 * (1 / SampleRate)) rounded down for whatever reason| 23 | |0x08|u32|Loop start in samples| 24 | |0x0C|u32|Number of samples| 25 | |0x10|a32|Absolute offset to audio data. Is always 0x68| 26 | |0x14|u32|Number of blocks. Always 1 for encodings not IMA-ADPCM| 27 | |0x18|u32|The size of a block, 0x200 for IMA-ADPCM and the size per audio channel for other encodings| 28 | |0x1C|u32|The number of samples per block, 0x3F8 for IMA-ADPCM and the samples per audio channel for other encodings| 29 | |0x20|u32|Size of the last block| 30 | |0x24|u32|Number of samples in the last block| 31 | |0x28|u8[0x20]|Padding| 32 | 33 | ## Data Block (Magic: DATA) 34 | Contains the raw audio data. It is organized in a fashion such as this: { Block 0 Channel 0, Block 0 Channel 1, Block 1 Channel 0, Block 1 Channel 1, etc. } Each block is IMA-ADPCM encoded separately. -------------------------------------------------------------------------------- /docs/specs/wave.md: -------------------------------------------------------------------------------- 1 | # Waves (.swav) 2 | SWAVs or Sound Waves are like WAV files, except are always only one channel and can be IMA-ADPCM encoded. 3 | 4 | ## The Main File 5 | The main file contains of a File Header and an Data Block. 6 | 7 | | **Type** | **Description** | 8 | |----------|-----------------| 9 | |SoundFileHeader|Sound File Header (Magic: SWAV. Always contains 1 block)| 10 | |Block|Data Block| 11 | 12 | ## Data Block Body (Magic: DATA) 13 | Contains audio information and how to read it. 14 | 15 | | **Offset** | **Type** | **Description** | 16 | |------------|----------|-----------------| 17 | |0x00|SoundEncoding|Type of encoding for the data| 18 | |0x01|bool|If the sound loops| 19 | |0x02|u16|Sampling rate of the audio| 20 | |0x04|u16|Clock time of the audio (16756991 / SampleRate)| 21 | |0x06|u16|Loop start offset. If audio does not loop, this is 1 for IMA-ADPCM and 0 for the other encodings| 22 | |0x08|u32|Loop end offset. If audio does not loop, this is 1 for IMA-ADPCM and 0 for the other encodings| 23 | |0x0C|AudioData|The rest of the block data is audio data for the channel. Its size is BlockSize - 0xC - 0x8| 24 | 25 | ### Converting Data Offset To Sample Position 26 | 27 | | **Encoding** | **Algorithm** | 28 | |--------------|---------------| 29 | |Signed PCM8|Offset| 30 | |Signed PCM16|Offset / 2| 31 | |IMA-ADPCM|Offset * 2 - 8| -------------------------------------------------------------------------------- /docs/specs/waveArchive.md: -------------------------------------------------------------------------------- 1 | # Wave Archives (.swar) 2 | SWARs or Sound Wave Archives are like folders for wave files. 3 | 4 | ## The Main File 5 | The main file contains of a File Header and a Data Block. 6 | 7 | | **Type** | **Description** | 8 | |----------|-----------------| 9 | |SoundFileHeader|Sound File Header (Magic: SWAR. Always contains 1 block)| 10 | |Block|Data Block| 11 | 12 | ## Data Block Body (Magic: DATA) 13 | Contains a series of headerless wave files. Note that the data for the waves is only the content in Data Block Body. 14 | 15 | | **Offset** | **Type** | **Description** | 16 | |------------|----------|-----------------| 17 | |0x00|u32[8]|Padding| 18 | |0x20|Table<`a32`>|Wave offsets| 19 | |----|WaveBlockBody[NumWaves]|Wave file data| --------------------------------------------------------------------------------