diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 13c3038..a6ae9d1 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -17,14 +17,14 @@ "rollForward": false }, "dotnet-reportgenerator-globaltool": { - "version": "5.2.0", + "version": "5.4.5", "commands": [ "reportgenerator" ], "rollForward": false }, "docfx": { - "version": "2.78.2", + "version": "2.78.3", "commands": [ "docfx" ], diff --git a/.editorconfig b/.editorconfig index 1b269f4..f0ee3c7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,6 +16,16 @@ indent_style = space indent_size = 2 max_line_length = 80 +# Verify settings +[*.{received,verified}.{json,txt,xml}] +charset = "utf-8-bom" +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = false +tab_width = 8 +trim_trailing_whitespace = false + # XML project files [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ce824b8 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.verified.txt text eol=lf working-tree-encoding=UTF-8 +*.verified.xml text eol=lf working-tree-encoding=UTF-8 +*.verified.json text eol=lf working-tree-encoding=UTF-8 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2454a48..893a9ee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,6 +34,14 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload test failure logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: verify-test-results + path: | + **/*.received.* + - name: "Bundle" if: ${{ matrix.is_main_build }} run: dotnet run --project build/orchestrator -- --target=Bundle --dotnet-configuration=Release diff --git a/.gitignore b/.gitignore index b5b4377..f9647fe 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,9 @@ build/temp/ *.csproj.user *.DotSettings.user launchSettings.json + +# Test resources +*.received/ +*.received.* +resources/tests/ +!**/Hinox.Tests/Resources/ diff --git a/.vscode/ltex.dictionary.en-US.txt b/.vscode/ltex.dictionary.en-US.txt index ae96a09..2d27bb2 100644 --- a/.vscode/ltex.dictionary.en-US.txt +++ b/.vscode/ltex.dictionary.en-US.txt @@ -1,2 +1,7 @@ Hinox SceneGate +uint +ushort +VAG +SPU +VB diff --git a/README.md b/README.md index 9df41cc..0d8a93d 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,35 @@  

-_Hinox_ is a library part of the [_SceneGate_](https://github.com/SceneGate) -framework that provides support for **PS1 (PSX) file formats.** +_Hinox_ is a set of libraries and utilities part of the +[_SceneGate_](https://github.com/SceneGate) framework that provides support for +**PS1 (PSX) file formats.** ## Supported formats -🚧 Project in an early development phase. No formats are supported yet. +- :speaker: **VAB** audio containers + - Versions 5, 6 and 7 + - Header (VH): read and write + - Body (VB and VAB): read and write -## Usage +## Tool installation -The project provides the following .NET libraries (NuGet packages in nuget.org). -The libraries work on supported versions of .NET. +1. Install [.NET 8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) +2. Install the latest version of the tool: + `dotnet tool install -g SceneGate.Hinox.Utils` + - You can update it with `dotnet tool update -g SceneGate.Hinox.Utils` + - To use preview versions, add the argument + `--prerelease --add-source https://pkgs.dev.azure.com/SceneGate/SceneGate/_packaging/SceneGate-Preview/nuget/v3/index.json` + +## Library installation + +The project provides the following .NET (C#) libraries. Only the latest LTS +version of .NET and higher are supported (no .NET Framework). - [![SceneGate.Hinox](https://img.shields.io/nuget/v/SceneGate.Hinox?label=SceneGate.Hinox&logo=nuget)](https://www.nuget.org/packages/SceneGate.Hinox) - 🚧 **not ready yet** - - `SceneGate.Hinox.Audio`: audio codecs. + - `SceneGate.Hinox.Audio`: audio formats. + +Stable releases are published in nuget.org. Preview releases can be found in this [Azure DevOps package repository](https://dev.azure.com/SceneGate/SceneGate/_packaging?_a=feed&feed=SceneGate-Preview). @@ -62,7 +76,7 @@ your solution file (.sln) with the following content: ## Documentation -Documentation is not yet available, but it will be published in the +Documentation is available in the [project website](https://scenegate.github.io/Hinox). Don't hesitate to ask questions in the diff --git a/docs/articles/dev/features/audio.md b/docs/articles/dev/features/audio.md deleted file mode 100644 index 155f93a..0000000 --- a/docs/articles/dev/features/audio.md +++ /dev/null @@ -1,3 +0,0 @@ -# PS1 audio converters - -TODO diff --git a/docs/articles/dev/features/vab.md b/docs/articles/dev/features/vab.md new file mode 100644 index 0000000..5eb0940 --- /dev/null +++ b/docs/articles/dev/features/vab.md @@ -0,0 +1,3 @@ +# VAB audio converters + +TODO diff --git a/docs/articles/dev/toc.yml b/docs/articles/dev/toc.yml index 5725826..73485cc 100644 --- a/docs/articles/dev/toc.yml +++ b/docs/articles/dev/toc.yml @@ -1,13 +1,7 @@ -- name: ✨ Getting started -- name: Introduction - href: ../../index.md -- name: 🚧 Getting started guide - href: tutorial.md - - name: ♻️ Converters -- name: 🚧 Audio - href: features/audio.md +- name: 🚧 VAB audio + href: features/vab.md -# - name: 📃 API docs -# - name: Namespaces -# href: ../../api/toc.yml +- name: 📃 API docs +- name: Namespaces + href: ../../api/toc.yml diff --git a/docs/articles/dev/tutorial.md b/docs/articles/dev/tutorial.md deleted file mode 100644 index 297e172..0000000 --- a/docs/articles/dev/tutorial.md +++ /dev/null @@ -1,3 +0,0 @@ -# Getting started guide - -TODO diff --git a/docs/articles/specs/audio/vab.md b/docs/articles/specs/audio/vab.md index 60b193b..f2383d4 100644 --- a/docs/articles/specs/audio/vab.md +++ b/docs/articles/specs/audio/vab.md @@ -1,3 +1,176 @@ -# VAB: Very Audio Binary +# VAB specification -TODO +_VAB_ (_very audio binary_?) is an audio format. It defines audio _tones_ +grouped in _programs_. It also acts as a container of VAG audio files. Tones are +linked to a specific VAG audio. Multiple tones with different parameters may +point to the same audio. + +Usually it has the extension `.VAB`. But it may also appear as two separated +files: the header with `.VH` extension and its body (VAG files) with `.VB` +extension. + +## Limitations + +The format have the following limitations: + +- A maximum of 254 waveform files (VAG). +- Up to 128 audio programs with a maximum of 16 tones. +- The body (VB) or total size of waveform files (VAG) must be under 504 KB + (`0x7E000`). + - This is due to a limitation in the hardware of 512 KB in the SPU RAM. + +## Format overview + +The VAB format is divided in the following sections. The VH file will contain +everything except the last part of the body (VB file). + +| Offset | Length | Description | +| ------ | -------- | ------------------------------ | +| 0x0000 | 0x20 | Header information | +| 0x0020 | 0x800 | Programs attributes | +| 0x0820 | variable | Tones attributes | +| ... | 0x200 | Waveforms length table | +| ... | variable | Body with waveforms data (VAG) | + +Quick formulas for variable offsets and lengths: + +- Tones attributes length: `header.programs * 0x200` +- Offset to waveform length table: `0x820` + tones attributes length +- Header size: waveform length table offset + `0x200` +- Offset to body: header size + +## Header (VH) + +### Information + +| Offset | Format | Description | +| ------ | ------- | --------------------------------------------------------- | +| 0x00 | char[4] | Format ID: `pBAV` (`VABp` in little-endian uint) | +| 0x04 | uint | Format version | +| 0x08 | uint | File ID | +| 0x0C | uint | Total size of header and body (even in header only files) | +| 0x10 | ushort | Reserved | +| 0x12 | ushort | Number of program attributes | +| 0x14 | ushort | Total number of tone attributes | +| 0x16 | ushort | Number of waveforms in body (VAG) | +| 0x18 | byte | Master volume | +| 0x19 | byte | Master pan | +| 0x1A | byte | User-defined bank attribute 1 | +| 0x1B | byte | User-defined bank attribute 2 | +| 0x1C | uint | Reserved | + +### Program attributes + +After the header information follows a list of program attribute definitions. +There are always 128 program entries in the format, although only a few of them +will be filled. There are always 16 bytes per entry. + +| Offset | Format | Description | +| ------ | ------ | ------------------------------------ | +| 0x00 | byte | Number of valid tones in the program | +| 0x01 | byte | Master volume for tones | +| 0x02 | byte | Priority of tones | +| 0x03 | byte | Mode, default: `0xE0` | +| 0x04 | byte | Master panning | +| 0x05 | byte | Reserved | +| 0x06 | ushort | Additional attributes | +| 0x08 | uint | Reserved, default: `-1` | +| 0x0C | uint | Reserved, default: `-1` | + +#### Empty programs + +_Empty_ programs do not count towards the count in the header and will have a +tone count of `0`. They may appear in any position of the program list, not +necessarily always at the end (e.g., between valid programs). + +Usually an _empty_ program repeats the same values of the last valid one +(reference program), except for the following fields: + +- Tone count: always 0. +- Master volume: reference program value or 0 for format version 6 and higher. +- Master panning: reference program value or 0 for format version 6 and higher. + +Note that some programs that do not appear at the end, may have unpredictable +values. Most likely they were filled at some point of the development process, +but they end up with no tones. + +### Tone attributes + +After the list of program attributes, there is a list of tones attributes in +order of programs. There are always 16 tones for each program, although as +happen for programs only a few will be not empty. A tone attribute entry has +always 32 bytes. + +| Offset | Format | Description | +| ------ | --------- | -------------------------------------------- | +| 0x00 | byte | Priority | +| 0x01 | byte | Mode, 0: normal, 4: reverberation | +| 0x02 | byte | Tone volume | +| 0x03 | byte | Tone panning | +| 0x04 | byte | Centre tone in semitone units | +| 0x05 | byte | Centre note fine-tuning for pitch correction | +| 0x06 | byte | Note minimum value | +| 0x07 | byte | Note maximum value | +| 0x08 | byte | Vibration width | +| 0x09 | byte | Vibration duration | +| 0x0A | byte | Portamento width | +| 0x0B | byte | Portamento duration | +| 0x0C | byte | Minimum pitch bend | +| 0x0D | byte | Maximum pitch bend | +| 0x0E | byte | Reserved | +| 0x0F | byte | Reserved | +| 0x10 | ushort | Envelope settings for attack and decay | +| 0x12 | ushort | Envelope settings for release and sustain | +| 0x14 | ushort | Program index (0-based) | +| 0x16 | ushort | Waveform index (1-based), 0 for empty tone | +| 0x18 | ushort[4] | Reserved | + +#### Empty tones + +Similar to the empty programs, tones may be empty and be just a placeholder so +it's easier to calculate offsets. Note that an _empty program_ do not have any +tone definitions, as long as a program defines one tone, there will be 16 in the +format. + +_Empty_ tones do not count towards the count in program attributes and will have +a waveform index equal to `0`, except for VAB format 5. In that case process the +tones in order with the count of program attributes, the rest would be empty. +Empty tones may appear in any position of the list, not necessarily always at +the end (e.g., between valid tones, good luck detecting for format 5). + +The content of an empty tone changes depending on the format version: + +- Fields `0x00` to `0x0E`: + - Version 5 (and lower?): reference tone values + - Version 6 and higher: `0x00` byte filled + - Except for note minimum and maximum values that are always `0x00`. +- Reserved fields: reference tone values +- Envelope settings: + - Version 5 (and lower?): reference tone + - Version 6: `0x00` byte filled + - Version 7 and higher: first: `0x80FF`, second: `0x5FC0`. +- Waveform index: + - Version 5 (and lower?): reference tone value + - Version 6 and higher: `0x00`. + +Note that some tones that do not appear at the end, may have unpredictable +values. Most likely they were filled at some point of the development process, +but the linked waveform file was removed. + +### Waveform length table + +The last part of the header is a table with the waveform (VAG) data lengths. +Each length value is a 16-bits unsigned integer 3-bits right-shifted (multiply +by 8 the format value). + +The first value should be ignored, and it is always `0x00`. Probably due to +waveform index being 1-based in the tone attributes. + +The table is always `0x200` bytes long. The remaining bytes are `0x00` filled. + +To calculate a waveform offset, sum the lengths of the previous files. + +## Body (VB) + +The body contains a set of waveform audio files. The format is `VAG` **without +header**. They usually start with 16-bytes `0x00`. diff --git a/docs/articles/specs/toc.yml b/docs/articles/specs/toc.yml index 5a8316d..405a548 100644 --- a/docs/articles/specs/toc.yml +++ b/docs/articles/specs/toc.yml @@ -1,3 +1,3 @@ - name: 🔉 audio -- name: 🚧 VAB +- name: VAB href: audio/vab.md diff --git a/docs/articles/tool/install.md b/docs/articles/tool/install.md new file mode 100644 index 0000000..9bf5d51 --- /dev/null +++ b/docs/articles/tool/install.md @@ -0,0 +1,42 @@ +# hinox-utils: Installation + +**hinox-utils** is a console application delivered as a _dotnet-tool_. + +## Prerequisites + +The utility requires the +[.NET 8.0 runtime](https://dotnet.microsoft.com/en-us/download/dotnet/8.0). You +can verify the installation by running `dotnet --list-runtimes` from a terminal. +If it says `Microsoft.NETCore.App` 8.0 or higher is installed, it should be +fine. + +## Installation + +There are two official ways to get the tool. Both methods download the same +binary. + +### GitHub release page + +Download the latest stable version from the +[GitHub release page](https://github.com/SceneGate/Hinox/releases) of the Hinox +project. + +Preview versions can be downloaded for logged GitHub users from the project +_Action_ pipeline artifacts. But they expire after a few days. Using the _.NET +tool_ method may be easier for preview builds. + +### .NET tool + +If you prefer to use _dotnet tool_, install the program globally for the current +user by running the following command from a terminal: +`dotnet tool install -g SceneGate.Hinox.Utils` + +The application will be available to run via `dotnet hinox-utils`. + +To try a preview version, add the following argument to any of the above +commands: +`--prerelease --add-source https://pkgs.dev.azure.com/SceneGate/SceneGate/_packaging/SceneGate-Preview/nuget/v3/index.json` + +To update the application to the latest version run: +`dotnet tool update -g SceneGate.Hinox.Utils`. Add the above argument to update +to the latest preview. diff --git a/docs/articles/tool/toc.yml b/docs/articles/tool/toc.yml new file mode 100644 index 0000000..7b20838 --- /dev/null +++ b/docs/articles/tool/toc.yml @@ -0,0 +1,9 @@ +- name: ✨ Getting started +- name: Introduction + href: ../../index.md + +- name: 🛠️ hinox-utils +- name: Installation + href: install.md +- name: 🚧 VAB + href: vab.md diff --git a/docs/articles/tool/vab.md b/docs/articles/tool/vab.md new file mode 100644 index 0000000..d91a00a --- /dev/null +++ b/docs/articles/tool/vab.md @@ -0,0 +1,13 @@ +# hinox-utils: VAB + +## Export + +TODO + +## Import + +TODO + +## Test + +TODO diff --git a/docs/docfx.json b/docs/docfx.json index 099382f..c52aed9 100644 --- a/docs/docfx.json +++ b/docs/docfx.json @@ -1,25 +1,25 @@ { - // "metadata": [ - // { - // "src": [ - // { - // "files": [ - // "Hinox/*.csproj" - // ], - // "src": "../src" - // } - // ], - // "dest": "api", - // "includePrivateMembers": false, - // "disableGitFeatures": false, - // "disableDefaultFilter": false, - // "noRestore": false, - // "namespaceLayout": "flattened", - // "memberLayout": "samePage", - // "EnumSortOrder": "alphabetic", - // "allowCompilationErrors": false - // } - // ], + "metadata": [ + { + "src": [ + { + "files": [ + "Hinox/*.csproj" + ], + "src": "../src" + } + ], + "dest": "api", + "includePrivateMembers": false, + "disableGitFeatures": false, + "disableDefaultFilter": false, + "noRestore": false, + "namespaceLayout": "flattened", + "memberLayout": "samePage", + "EnumSortOrder": "alphabetic", + "allowCompilationErrors": false + } + ], "build": { "content": [ { diff --git a/docs/index.md b/docs/index.md index b34dd21..bfb769d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,46 +1,40 @@ # Hinox [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://choosealicense.com/licenses/mit/) -_Hinox_ is a library part of the [_SceneGate_](https://github.com/SceneGate) -framework that provides support for _PS1_ (PSX) file formats. +_Hinox_ is a set of libraries and utilities part of the +[_SceneGate_](https://github.com/SceneGate) framework that provides support for +_PS1_ (PSX) file formats. ## Supported formats -🚧 Project in an early development phase. No formats are supported yet. +- :speaker: **VAB** audio containers + - Versions 5, 6 and 7 + - Reading and writing header (VH) and body (VB and VAB) + - Tool to export and import. + - Limitation: the VAG format and its audio codec are not supported yet. -## Usage +## Tooling -The project provides the following .NET libraries (NuGet packages in nuget.org). -The libraries work on supported versions of .NET. +The project provides an application to convert files between different formats. +This is a _console_ application, it doesn't have a graphical interface (no +window). Use a terminal like _Windows Terminal_ on Windows or bash on Unix. + +Follow the [installation](./articles/tool/install.md) instructions, then head +directly to some of its commands like the [VAB export](./articles/tool/vab.md). + +## Development libraries + +The Hinox .NET (C#) library provides models representing file formats and +[Yarhl](https://scenegate.github.io/Yarhl/docs/core/formats/converters.html) +converters for their (de)serialization. Check-out the additional dev categories +for information in the APIs available. - [![SceneGate.Hinox](https://img.shields.io/nuget/v/SceneGate.Hinox?label=SceneGate.Hinox&logo=nuget)](https://www.nuget.org/packages/SceneGate.Hinox) - 🚧 **not ready yet** - `SceneGate.Hinox.Audio`: audio codecs. -### Preview release - -Preview releases can be found in this -[Azure DevOps package repository](https://dev.azure.com/SceneGate/SceneGate/_packaging?_a=feed&feed=SceneGate-Preview). -To use a preview release, create a file `nuget.config` in the same directory of -your solution file (.sln) with the following content: - -```xml - - - - - - - - - - - - - - - - -``` +It's recommended to become familiar with the basic concepts of Yarhl before +starting to use this project. Check-out its +[tutorial](https://scenegate.github.io/Yarhl/docs/core/getting-started/tutorial.html) +for a quick introduction. ## Special thanks diff --git a/docs/toc.yml b/docs/toc.yml index 6dbb38a..cb0bcb5 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -1,3 +1,6 @@ +- name: Tool + href: articles/tool/ + - name: Dev guides href: articles/dev/ diff --git a/resources/imhex/vab.hexpat b/resources/imhex/vab.hexpat new file mode 100644 index 0000000..364e9ee --- /dev/null +++ b/resources/imhex/vab.hexpat @@ -0,0 +1,126 @@ +#pragma author pleonex +#pragma description PS audio container VAB + +#pragma MIME application/x-psx-vab +#pragma magic [ 70 42 41 56 ] @ 0x00 + + +#define MAX_PROGRAMS 0x80 +#define MAX_TONES 0x10 +#define MAX_WAVEFORMS 254 + +import type.magic; +import std.core; +import std.mem; + +bool displayEmptyPrograms in; +bool displayEmptyTones in; + +struct VhHeader { + type::Magic<"pBAV"> fileId; + u32 version; + u32 vabId; + u32 vabSize; + u16 reserved0; + + u16 programCount; + u16 toneCount; + u16 waveformCount; + + u8 masterVolume; + u8 masterPan; + u8 bankAttributes1; + u8 bankAttributes2; + u32 reserved1; +}; + +struct VhProgramAttributes { + u8 toneCount; + u8 masterVolume; + u8 priority; + u8 mode; + u8 masterPanning; + u8 reserved0; + u16 attributes; + u32 reserved1; + u32 reserved2; + + // Hide empty programs + if (!displayEmptyPrograms && toneCount == 0) { + continue; + } +} [[format("format_program")]]; + +fn format_program(VhProgramAttributes attr) { + return std::format("[tones: {}]", attr.toneCount); +}; + +struct VhToneAttributes { + u8 priority; + u8 mode; + u8 volume; + u8 panning; + u8 centre; + u8 fine; + u8 minimum; + u8 maximum; + u8 vibrationWidth; + u8 vibrationTime; + u8 portamentoWidth; + u8 portamentoTime; + u8 pitchBendMinimum; + u8 pitchBendMaximum; + u8 reserved0; + u8 reserved1; + u16 envelopeSettings1; + u16 envelopeSettings2; + u16 programIndex; + u16 waveformIndex; // starting at 1, 0 for invalid tone + u64 reserved2; + + if (!displayEmptyTones && waveformIndex == 0) { + continue; + } +} [[format("format_tone")]]; + +fn format_tone(VhToneAttributes attr) { + return std::format("[program: #{}, waveform: #{}]", attr.programIndex, attr.waveformIndex); +}; + +// u16 wrapper for multiplying value by 8 (<< 3) +struct WaveformLength { + u16 length; +} [[sealed, static, transform("transform_waveform_length"), format("transform_waveform_length")]]; + +fn transform_waveform_length(ref WaveformLength l) { + u32 result = l.length << 3; + return result; +}; + +struct Vh { + VhHeader header; + VhProgramAttributes programs[MAX_PROGRAMS]; + VhToneAttributes tones[MAX_TONES * header.programCount]; + + // waveform lengths table + padding[2]; // because waveformIndex is 1-based (for 0 as null) this is always 0 + WaveformLength waveformLengths[while(std::mem::read_unsigned($, 2) != 0)]; + padding[(MAX_WAVEFORMS - std::core::member_count(waveformLengths) + 1) * 2]; +}; + +struct Vag { + u32 length = parent.parent.vabHeader.waveformLengths[std::core::array_index()]; + u8 data[length]; +} [[sealed]]; + +struct Vb { + Vag waveForms[std::core::member_count(parent.vabHeader.waveformLengths)]; +}; + +struct Vab { + Vh vabHeader; + Vb vabBody; +}; + + +Vab vab @ 0x0000; \ No newline at end of file diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index ca4d0d6..c5d77f5 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -1,11 +1,21 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Hinox.Tests/Audio/Binary2VabHeaderTests.cs b/src/Hinox.Tests/Audio/Binary2VabHeaderTests.cs new file mode 100644 index 0000000..af1068d --- /dev/null +++ b/src/Hinox.Tests/Audio/Binary2VabHeaderTests.cs @@ -0,0 +1,77 @@ +namespace SceneGate.Hinox.Tests.Audio; + +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using NUnit.Framework; +using SceneGate.Hinox.Audio; +using SceneGate.Hinox.Tests.Framework; +using VerifyNUnit; +using Yarhl.FileSystem; +using Yarhl.IO; + +[TestFixture] +public class Binary2VabHeaderTests +{ + private static IEnumerable VhSnapshotTestFiles => + TestDataBase.ReadTestCaseDataListFile(TestDataBase.VabResources, "vh_snapshots.txt"); + + private static IEnumerable VhFullSnapshotTestFiles => + TestDataBase.ReadTestCaseDataListFile(TestDataBase.VabResources, "vh_snapshots_full.txt"); + + private static IEnumerable VhReadingTestFiles => + TestDataBase.ReadTestCaseDataGlobFile(TestDataBase.VabResources, "vh_read.txt"); + + [TestCaseSource(nameof(VhSnapshotTestFiles))] + public Task VerifyDeserializationForSnapshots(string filename) + { + string filePath = Path.Combine(TestDataBase.VabResources, "Snapshots", filename); + TestDataBase.IgnoreIfFileDoesNotExist(filePath); + + using Node testNode = NodeFactory.FromFile(filePath, FileOpenMode.Read) + .TransformWith(); + VabHeader actual = testNode.GetFormatAs(); + + Verifier.UseProjectRelativeDirectory("Resources/VAB/Snapshots"); + return Verifier.Verify(actual) + .UseFileName(filename) + .AddExtraSettings(x => { + x.DefaultValueHandling = Argon.DefaultValueHandling.Include; + x.Converters.Add(new HexadecimalVerifierJsonConverter()); + }); + } + + [TestCaseSource(nameof(VhFullSnapshotTestFiles))] + public Task VerifyDeserializationForSnapshotsWithFullContent(string filename) + { + string filePath = Path.Combine(TestDataBase.VabResources, "Snapshots", filename); + TestDataBase.IgnoreIfFileDoesNotExist(filePath); + + using Node testNode = NodeFactory.FromFile(filePath, FileOpenMode.Read) + .TransformWith(new Binary2VabHeader(includePaddingTones: true, throwOnInvalid: false)); + VabHeader actual = testNode.GetFormatAs(); + + Verifier.UseProjectRelativeDirectory("Resources/VAB/Snapshots"); + return Verifier.Verify(actual) + .UseFileName(filename) + .AddExtraSettings(x => { + x.DefaultValueHandling = Argon.DefaultValueHandling.Include; + x.Converters.Add(new HexadecimalVerifierJsonConverter()); + }); + } + + [TestCaseSource(nameof(VhReadingTestFiles))] + public void ValidateAllFiles(string filePath) + { + TestDataBase.IgnoreIfFileDoesNotExist(filePath); + + using Node testNode = NodeFactory.FromFile(filePath, FileOpenMode.Read); + + Assert.That( + () => testNode.TransformWith( + new Binary2VabHeader(includePaddingTones: true, throwOnInvalid: false)), + Throws.Nothing); + Assert.That(testNode.Format, Is.TypeOf()); + } +} diff --git a/src/Hinox.Tests/Audio/BinaryVab2ContainerTests.cs b/src/Hinox.Tests/Audio/BinaryVab2ContainerTests.cs new file mode 100644 index 0000000..2215f0c --- /dev/null +++ b/src/Hinox.Tests/Audio/BinaryVab2ContainerTests.cs @@ -0,0 +1,43 @@ +namespace SceneGate.Hinox.Tests.Audio; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using NUnit.Framework; +using SceneGate.Hinox.Audio; +using SceneGate.Hinox.Tests.Framework; +using VerifyNUnit; +using Yarhl.FileSystem; +using Yarhl.IO; + +[TestFixture] +public class BinaryVab2ContainerTests +{ + private static IEnumerable VabSnapshotTestFiles => + TestDataBase.ReadTestCaseDataListFile(TestDataBase.VabResources, "vab_snapshots.txt"); + + [TestCaseSource(nameof(VabSnapshotTestFiles))] + public Task VerifyUnpackForSnapshots(string vabName) + { + string vabPath = Path.Combine(TestDataBase.VabResources, "Snapshots", vabName); + TestDataBase.IgnoreIfFileDoesNotExist(vabPath); + + using var vabBinary = new BinaryFormat(vabPath, FileOpenMode.Read); + var actual = new BinaryVab2Container().Convert(vabBinary); + + Verifier.UseProjectRelativeDirectory("Resources/VAB/Snapshots"); + return Verifier.Verify(actual.Root.Children) + .UseFileName(vabName) + .AddExtraSettings(x => { + x.DefaultValueHandling = Argon.DefaultValueHandling.Include; + x.Converters.Add(new BinaryVerifierJsonConverter()); + x.Converters.Add(new HexadecimalVerifierJsonConverter()); + }) + .IgnoreMembers>(x => x.Disposed, x => x.Path, x => x.Parent) + .IgnoreMembers(x => x.IsContainer); + } +} diff --git a/src/Hinox.Tests/Audio/BinaryVabBody2ContainerTests.cs b/src/Hinox.Tests/Audio/BinaryVabBody2ContainerTests.cs new file mode 100644 index 0000000..8ef056b --- /dev/null +++ b/src/Hinox.Tests/Audio/BinaryVabBody2ContainerTests.cs @@ -0,0 +1,43 @@ +namespace SceneGate.Hinox.Tests.Audio; + +using System.Collections; +using System.IO; +using System.Threading.Tasks; +using NUnit.Framework; +using SceneGate.Hinox.Audio; +using SceneGate.Hinox.Tests.Framework; +using VerifyNUnit; +using Yarhl.FileSystem; +using Yarhl.IO; + +[TestFixture] +public class BinaryVabBody2ContainerTests +{ + private static IEnumerable VbSnapshotTestFiles => + TestDataBase.ReadTestCaseDataListFile(TestDataBase.VabResources, "vb_snapshots.txt"); + + [TestCaseSource(nameof(VbSnapshotTestFiles))] + public Task VerifyUnpackForSnapshots(string vbName, string vhName) + { + string vbPath = Path.Combine(TestDataBase.VabResources, "Snapshots", vbName); + string vhPath = Path.Combine(TestDataBase.VabResources, "Snapshots", vhName); + TestDataBase.IgnoreIfFileDoesNotExist(vbPath); + TestDataBase.IgnoreIfFileDoesNotExist(vhPath); + + using var vhBinary = new BinaryFormat(vhPath, FileOpenMode.Read); + var header = new Binary2VabHeader().Convert(vhBinary); + + using var vbBinary = new BinaryFormat(vbPath, FileOpenMode.Read); + var actual = new BinaryVabBody2Container(header).Convert(vbBinary); + + Verifier.UseProjectRelativeDirectory("Resources/VAB/Snapshots"); + return Verifier.Verify(actual.Root.Children) + .UseFileName(vbName) + .AddExtraSettings(x => { + x.DefaultValueHandling = Argon.DefaultValueHandling.Include; + x.Converters.Add(new BinaryVerifierJsonConverter()); + }) + .IgnoreMembers>(x => x.Disposed, x => x.Path, x => x.Parent) + .IgnoreMembers(x => x.IsContainer); + } +} diff --git a/src/Hinox.Tests/Audio/Container2BinaryVabBodyTests.cs b/src/Hinox.Tests/Audio/Container2BinaryVabBodyTests.cs new file mode 100644 index 0000000..9b4b2ef --- /dev/null +++ b/src/Hinox.Tests/Audio/Container2BinaryVabBodyTests.cs @@ -0,0 +1,95 @@ +namespace SceneGate.Hinox.Tests.Audio; + +using System; +using System.Collections.Generic; +using System.IO; +using NUnit.Framework; +using SceneGate.Hinox.Audio; +using VerifyTests; +using Yarhl.FileSystem; +using Yarhl.IO; + +[TestFixture] +public class Container2BinaryVabBodyTests +{ + private static IEnumerable VbWritingTestFiles => + TestDataBase.ReadTestCaseDataListFile(TestDataBase.VabResources, "vb_write.txt"); + + [TestCaseSource(nameof(VbWritingTestFiles))] + public void WriteIdenticalFormat(string vbName, string vhName) + { + string vbPath = Path.Combine(TestDataBase.VabResources, "Snapshots", vbName); + string vhPath = Path.Combine(TestDataBase.VabResources, "Snapshots", vhName); + TestDataBase.IgnoreIfFileDoesNotExist(vbPath); + TestDataBase.IgnoreIfFileDoesNotExist(vhPath); + + using var originalBinary = new BinaryFormat(vbPath, FileOpenMode.Read); + + using var vbBinary = new BinaryFormat(vbPath, FileOpenMode.Read); + using var vhBinary = new BinaryFormat(vhPath, FileOpenMode.Read); + var header = new Binary2VabHeader().Convert(vhBinary); + var deserialized = new BinaryVabBody2Container(header).Convert(vbBinary); + + BinaryFormat newBinary = new Container2BinaryVabBody().Convert(deserialized); + + bool identical = newBinary.Stream.Compare(originalBinary.Stream); + if (!identical) { + string failedPath = Path.Combine(TestDataBase.VabResources, "Failed", vbName); + newBinary.Stream.WriteTo(failedPath); + } + + Assert.That(identical, Is.True, "Streams are different"); + } + + [Test] + public void WriteWithNonBinaryNodesThrowsException() + { + NodeContainerFormat container = new(); + + container.Root.Add(new Node("invalid", new NodeContainerFormat())); + + var converter = new Container2BinaryVabBody(); + Assert.That(() => converter.Convert(container), Throws.InstanceOf()); + } + + [Test] + public void WriteWithHeaderIgnoresIt() + { + NodeContainerFormat container = new(); + + container.Root.Add(new Node("header", new VabHeader())); + + var converter = new Container2BinaryVabBody(); + using var result = converter.Convert(container); + + Assert.That(result, Is.Not.Null); + } + + [Test] + public void WriteMoreNodesThanLimitThrowsException() + { + NodeContainerFormat container = new(); + + for (int i = 0; i < VabHeader.MaximumWaveforms + 1; i++) { + container.Root.Add(new Node($"{i}", new BinaryFormat())); + } + + var converter = new Container2BinaryVabBody(); + Assert.That(() => converter.Convert(container), Throws.InstanceOf()); + } + + [Test] + public void WriteTotalBodyLargerThanLimitThrowsException() + { + NodeContainerFormat container = new(); + + using var largeStream = new DataStream(); + var writer = new DataWriter(largeStream); + writer.WriteTimes(0, VabHeader.MaximumTotalWaveformsSize + 1); + + container.Root.Add(new Node("0", new BinaryFormat(largeStream))); + + var converter = new Container2BinaryVabBody(); + Assert.That(() => converter.Convert(container), Throws.InstanceOf()); + } +} diff --git a/src/Hinox.Tests/Audio/Container2BinaryVabTests.cs b/src/Hinox.Tests/Audio/Container2BinaryVabTests.cs new file mode 100644 index 0000000..46413e7 --- /dev/null +++ b/src/Hinox.Tests/Audio/Container2BinaryVabTests.cs @@ -0,0 +1,35 @@ +namespace SceneGate.Hinox.Tests.Audio; + +using System.Collections.Generic; +using System.IO; +using NUnit.Framework; +using SceneGate.Hinox.Audio; +using Yarhl.IO; + +[TestFixture] +public class Container2BinaryVabTests +{ + private static IEnumerable VabWritingTestFiles => + TestDataBase.ReadTestCaseDataListFile(TestDataBase.VabResources, "vab_write.txt"); + + [TestCaseSource(nameof(VabWritingTestFiles))] + public void WriteIdenticalFormat(string vabName) + { + string vabPath = Path.Combine(TestDataBase.VabResources, "Snapshots", vabName); + TestDataBase.IgnoreIfFileDoesNotExist(vabPath); + + using var originalBinary = new BinaryFormat(vabPath, FileOpenMode.Read); + + var deserialized = new BinaryVab2Container(includePaddingTones: true, throwOnInvalid: false) + .Convert(originalBinary); + using BinaryFormat newBinary = new Container2BinaryVab().Convert(deserialized); + + bool identical = newBinary.Stream.Compare(originalBinary.Stream); + if (!identical) { + string failedPath = Path.Combine(TestDataBase.VabResources, "Failed", vabName); + newBinary.Stream.WriteTo(failedPath); + } + + Assert.That(identical, Is.True, "Streams are different"); + } +} diff --git a/src/Hinox.Tests/Audio/VabHeader2BinaryTests.cs b/src/Hinox.Tests/Audio/VabHeader2BinaryTests.cs new file mode 100644 index 0000000..a58bcfb --- /dev/null +++ b/src/Hinox.Tests/Audio/VabHeader2BinaryTests.cs @@ -0,0 +1,35 @@ +namespace SceneGate.Hinox.Tests.Audio; + +using System.Collections.Generic; +using System.IO; +using NUnit.Framework; +using SceneGate.Hinox.Audio; +using Yarhl.IO; + +[TestFixture] +public class VabHeader2BinaryTests +{ + private static IEnumerable VhWritingTestFiles => + TestDataBase.ReadTestCaseDataGlobFile(TestDataBase.VabResources, "vh_write.txt"); + + [TestCaseSource(nameof(VhWritingTestFiles))] + public void WriteIdenticalFormat(string filePath) + { + TestDataBase.IgnoreIfFileDoesNotExist(filePath); + + using var originalBinary = new BinaryFormat(filePath, FileOpenMode.Read); + + var deserialized = new Binary2VabHeader(includePaddingTones: true, throwOnInvalid: false) + .Convert(originalBinary); + BinaryFormat newBinary = new VabHeader2Binary().Convert(deserialized); + + bool identical = newBinary.Stream.Compare(originalBinary.Stream); + if (!identical) { + string relativePath = Path.GetRelativePath(TestDataBase.VabResources, filePath); + string failedPath = Path.Combine(TestDataBase.VabResources, "Failed", relativePath); + newBinary.Stream.WriteTo(failedPath); + } + + Assert.That(identical, Is.True, "Streams are different"); + } +} diff --git a/src/Hinox.Tests/Audio/VagFormatAnalyzerTests.cs b/src/Hinox.Tests/Audio/VagFormatAnalyzerTests.cs new file mode 100644 index 0000000..d0f4c36 --- /dev/null +++ b/src/Hinox.Tests/Audio/VagFormatAnalyzerTests.cs @@ -0,0 +1,85 @@ +namespace SceneGate.Hinox.Tests.Audio; + +using NUnit.Framework; +using SceneGate.Hinox.Audio; +using Yarhl.IO; + +[TestFixture] +public class VagFormatAnalyzerTests +{ + [Test] + public void GetChannelsLengthWithRawAudioReturnsStreamLength() + { + using var audio = new DataStream(); + var writer = new DataWriter(audio); + + // Random data that may look like SPU ADPCM + writer.WriteTimes(0x00, 16); + writer.Write([0x16, 0x00, 0x42, 0x30, 0xE2, 0x2E, 0x01, 0x2F, 0xD1, 0x40, 0x02, 0x21, 0xBD, 0x02, 0xFB, 0x23]); + + long actualLength = VagFormatAnalyzer.GetChannelsLength(audio); + + Assert.That(actualLength, Is.EqualTo(audio.Length)); + } + + [Test] + public void GetChannelsLengthWithPsxVagpSkipHeader() + { + const int HeaderLength = 0x30; + using var audio = new DataStream(); + var writer = new DataWriter(audio); + + // Just the format ID for quick detection trigger + writer.Write("VAGp", nullTerminator: false); + writer.WriteUntilLength(0x00, HeaderLength); + + // Random data that may look like SPU ADPCM + writer.WriteTimes(0x00, 16); + writer.Write([0x16, 0x00, 0x42, 0x30, 0xE2, 0x2E, 0x01, 0x2F, 0xD1, 0x40, 0x02, 0x21, 0xBD, 0x02, 0xFB, 0x23]); + + long actualLength = VagFormatAnalyzer.GetChannelsLength(audio); + + Assert.That(actualLength, Is.EqualTo(audio.Length - HeaderLength)); + } + + [Test] + public void GetChannelsLengthWithVagEditGeneratedVag() + { + const int HeaderLength = 0x30; + const int ChannelsLength = 0x20; + + using var audio = new DataStream(); + var writer = new DataWriter(audio) { + Endianness = EndiannessMode.BigEndian, + }; + + // Only the channels length and sample rate + writer.WriteTimes(0x00, 0x0C); + writer.Write(ChannelsLength); + writer.Write(11_025); + writer.WriteUntilLength(0x00, HeaderLength); + + // Random data that may look like SPU ADPCM + writer.WriteTimes(0x00, 16); + writer.Write([0x16, 0x00, 0x42, 0x30, 0xE2, 0x2E, 0x01, 0x2F, 0xD1, 0x40, 0x02, 0x21, 0xBD, 0x02, 0xFB, 0x23]); + + long actualLength = VagFormatAnalyzer.GetChannelsLength(audio); + + Assert.That(actualLength, Is.EqualTo(ChannelsLength)); + } + + [Test] + public void GetChannelsLengthWithEmptyFileReturnsAsFullAudio() + { + using var audio = new DataStream(); + var writer = new DataWriter(audio) { + Endianness = EndiannessMode.BigEndian, + }; + + writer.WriteTimes(0x00, 0x30); + + long actualLength = VagFormatAnalyzer.GetChannelsLength(audio); + + Assert.That(actualLength, Is.EqualTo(0x30)); + } +} diff --git a/src/Hinox.Tests/Framework/BinaryVerifierJsonConverter.cs b/src/Hinox.Tests/Framework/BinaryVerifierJsonConverter.cs new file mode 100644 index 0000000..e0fa424 --- /dev/null +++ b/src/Hinox.Tests/Framework/BinaryVerifierJsonConverter.cs @@ -0,0 +1,40 @@ +namespace SceneGate.Hinox.Tests.Framework; + +using System; +using System.IO; +using System.Security.Cryptography; +using VerifyTests; +using Yarhl.IO; + +/// +/// JSON converter for Yarhl binary formats implementing . +/// +public class BinaryVerifierJsonConverter : WriteOnlyJsonConverter +{ + /// + public override void Write(VerifyJsonWriter writer, IBinary value) + { + var stream = value.Stream; + + stream.PushToPosition(0); + string hash; + try { + using var sha256 = SHA256.Create(); + sha256.ComputeHash(stream); + + hash = Convert.ToHexString(sha256.Hash); + } + finally { + stream.PopPosition(); + } + + writer.WriteStartObject(); + + writer.WriteMember(value, $"0x{stream.Offset:X}", nameof(DataStream.Offset)); + writer.WriteMember(value, $"0x{stream.Position:X}", nameof(Stream.Position)); + writer.WriteMember(value, $"0x{stream.Length:X}", nameof(Stream.Length)); + writer.WriteMember(value, hash, "SHA256"); + + writer.WriteEndObject(); + } +} diff --git a/src/Hinox.Tests/Framework/HexadecimalVerifierJsonConverter.cs b/src/Hinox.Tests/Framework/HexadecimalVerifierJsonConverter.cs new file mode 100644 index 0000000..8ae341f --- /dev/null +++ b/src/Hinox.Tests/Framework/HexadecimalVerifierJsonConverter.cs @@ -0,0 +1,39 @@ +namespace SceneGate.Hinox.Tests.Framework; + +using System; +using System.Linq; +using System.Reflection; +using VerifyTests; + +/// +/// JSON converter of objects with integer values in hexadecimal. +/// +/// +public class HexadecimalVerifierJsonConverter : WriteOnlyJsonConverter +{ + private static readonly Type[] HexadecimalTypes = [ + typeof(byte), typeof(sbyte), + typeof(short), typeof(ushort), + typeof(int), typeof(uint), + typeof(long), typeof(ulong), + ]; + + /// + public override void Write(VerifyJsonWriter writer, T value) + { + writer.WriteStartObject(); + + PropertyInfo[] objProperties = value.GetType() + .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty); + + foreach (PropertyInfo prop in objProperties) { + if (HexadecimalTypes.Contains(prop.PropertyType)) { + writer.WriteMember(value, $"0x{prop.GetValue(value):X}", prop.Name); + } else { + writer.WriteMember(value, prop.GetValue(value), prop.Name); + } + } + + writer.WriteEndObject(); + } +} diff --git a/src/Hinox.Tests/Hinox.Tests.csproj b/src/Hinox.Tests/Hinox.Tests.csproj index 44bb76f..7886b93 100644 --- a/src/Hinox.Tests/Hinox.Tests.csproj +++ b/src/Hinox.Tests/Hinox.Tests.csproj @@ -13,11 +13,19 @@ + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/src/Hinox.Tests/Resources/.gitignore b/src/Hinox.Tests/Resources/.gitignore new file mode 100644 index 0000000..8660278 --- /dev/null +++ b/src/Hinox.Tests/Resources/.gitignore @@ -0,0 +1,6 @@ +Validation/ + +# Audio +*.vb +*.vh +*.vab diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/DRA_ch08.vab.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/DRA_ch08.vab.verified.txt new file mode 100644 index 0000000..df94d66 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/DRA_ch08.vab.verified.txt @@ -0,0 +1,631 @@ +[ + { + Format: { + Offset: 0x1E20, + Position: 0x0, + Length: 0xA20, + SHA256: 95A3515F5F1DFC5EEFCD730518634358B7731236B6EDE4A70B64108ABDA951ED + }, + Name: audio0000, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x2840, + Position: 0x0, + Length: 0xF10, + SHA256: CBFA802044408D78678773A3D40EF8CFE1C2CC79FB28B0A02486944268E6D40D + }, + Name: audio0001, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3750, + Position: 0x0, + Length: 0xB30, + SHA256: F53F18CD551A2FF7C25D997B7040A3FC9458C161FDA5FE887C78056DD0C82770 + }, + Name: audio0002, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x4280, + Position: 0x0, + Length: 0x27F0, + SHA256: 58E160EBC1D3BEE103D04E89D4B06A52EC7BEC2EA1013C804062F16C627E5059 + }, + Name: audio0003, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6A70, + Position: 0x0, + Length: 0x360, + SHA256: 8A201AF121B76E0179037F482AF884DC6FB68CE0911D7FF9BFBEB9B452C55978 + }, + Name: audio0004, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6DD0, + Position: 0x0, + Length: 0x4B0, + SHA256: 09DC3516109D9B58316AC2B8418A88F47D3D323C4B0A9A6CD685AF1690845F2B + }, + Name: audio0005, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x7280, + Position: 0x0, + Length: 0xD80, + SHA256: 7545AF81B9A8D5340F6C6B272554EDC99D9ABFE47DD27E29639EAC12E539FA61 + }, + Name: audio0006, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x8000, + Position: 0x0, + Length: 0xD90, + SHA256: 3582F3A2DA51281C777DDA475C9AD8605402EECD5C53E0A4CAA277EBC2620C9F + }, + Name: audio0007, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x8D90, + Position: 0x0, + Length: 0x10D0, + SHA256: A20082ADCC18AD6831761FF436C3C19A7D5A3399BB92E189D0ACC2A45EA1DD04 + }, + Name: audio0008, + Children: null, + Tags: null + }, + { + Format: { + Version: 0x7, + VabId: 0x0, + Reserved0: 0xEEEE, + MasterVolume: 0x7F, + MasterPan: 0x40, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0xFFFFFFFF, + ProgramsAttributes: [ + { + Index: 0, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 110, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -29441, + EnvelopeSettings2: 24526, + ProgramIndex: 0, + WaveformIndex: 0, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 1, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 105, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -27905, + EnvelopeSettings2: 24527, + ProgramIndex: 1, + WaveformIndex: 1, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 105, + Panning: 64, + Centre: 94, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -27905, + EnvelopeSettings2: 24527, + ProgramIndex: 1, + WaveformIndex: 1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 2, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 110, + Panning: 64, + Centre: 90, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -29697, + EnvelopeSettings2: 24525, + ProgramIndex: 2, + WaveformIndex: 2, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 3, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 100, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -30209, + EnvelopeSettings2: 24526, + ProgramIndex: 3, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 100, + Panning: 64, + Centre: 92, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -29697, + EnvelopeSettings2: 24526, + ProgramIndex: 3, + WaveformIndex: 3, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 4, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 5, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: false, + Priority: 0, + Mode: 4, + Volume: 120, + Panning: 64, + Centre: 72, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -29185, + EnvelopeSettings2: 24526, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 90, + Panning: 64, + Centre: 70, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -29441, + EnvelopeSettings2: 21838, + ProgramIndex: 5, + WaveformIndex: 3, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 6, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 7, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 8, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 9, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 10, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 95, + Fine: 17, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -27905, + EnvelopeSettings2: 24524, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 11, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 95, + Fine: 17, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -28417, + EnvelopeSettings2: 24524, + ProgramIndex: 11, + WaveformIndex: 5, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 12, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 115, + Panning: 64, + Centre: 95, + Fine: 62, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -28417, + EnvelopeSettings2: 24523, + ProgramIndex: 12, + WaveformIndex: 6, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 13, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 127, + Panning: 64, + Centre: 95, + Fine: 62, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -28673, + EnvelopeSettings2: 24524, + ProgramIndex: 13, + WaveformIndex: 7, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 14, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 4, + Volume: 127, + Panning: 64, + Centre: 95, + Fine: 62, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -27649, + EnvelopeSettings2: 24523, + ProgramIndex: 14, + WaveformIndex: 8, + Reserved2: 54888453694881984 + } + ] + } + ], + WaveformSizes: [ + 2592, + 3856, + 2864, + 10224, + 864, + 1200, + 3456, + 3472, + 4304 + ] + }, + Name: header, + Children: null, + Tags: null + } +] \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/DRA_mv23.vh.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/DRA_mv23.vh.verified.txt new file mode 100644 index 0000000..46ab5f0 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/DRA_mv23.vh.verified.txt @@ -0,0 +1,3865 @@ +{ + Version: 0x7, + VabId: 0x0, + Reserved0: 0xEEEE, + MasterVolume: 0x7F, + MasterPan: 0x40, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0xFFFFFFFF, + ProgramsAttributes: [ + { + Index: 0, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -25601, + EnvelopeSettings2: 24526, + ProgramIndex: 0, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 1, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -25601, + EnvelopeSettings2: 24525, + ProgramIndex: 1, + WaveformIndex: 1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 2, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 3, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 4, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 5, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -25601, + EnvelopeSettings2: 24530, + ProgramIndex: 5, + WaveformIndex: 2, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 6, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 125, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -25601, + EnvelopeSettings2: 24530, + ProgramIndex: 6, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 6, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 7, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 125, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -25601, + EnvelopeSettings2: 24530, + ProgramIndex: 7, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 7, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 8, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 9, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 10, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 11, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 12, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 60, + Fine: 0, + Minimum: 0, + Maximum: 120, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24528, + ProgramIndex: 12, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 12, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 13, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 14, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 15, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 16, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 17, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 18, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 19, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 20, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 21, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 22, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 23, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 24, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 25, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 26, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 27, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 28, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 29, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 30, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 31, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 32, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 33, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 34, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 35, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 36, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 37, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 38, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 39, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 40, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 41, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 42, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 43, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 44, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 45, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 46, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 47, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 48, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 49, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 50, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 51, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 52, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 53, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 54, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 55, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 56, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 57, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 58, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 59, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 60, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 61, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 62, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 63, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 64, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 65, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 66, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 67, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 68, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 69, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 70, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 71, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 72, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 73, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 74, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 75, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 76, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 77, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 78, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 79, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 80, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 81, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 82, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 83, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 84, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 85, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 86, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 87, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 88, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 89, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 90, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 91, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 92, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 93, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 94, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 95, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 96, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 97, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 98, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 99, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 100, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 101, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 102, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 103, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 104, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 105, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 106, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 107, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 108, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 109, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 110, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 111, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 112, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 113, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 114, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 115, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 116, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 117, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 118, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 119, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 120, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 121, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 122, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 123, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 124, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 125, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 126, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 127, + MasterVolume: 0, + Priority: 255, + Mode: 255, + MasterPanning: 0, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + } + ], + WaveformSizes: [ + 832, + 928, + 4816, + 6384, + 7488 + ] +} \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/MG_AUDIO1.VB.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/MG_AUDIO1.VB.verified.txt new file mode 100644 index 0000000..8387320 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/MG_AUDIO1.VB.verified.txt @@ -0,0 +1,90 @@ +[ + { + Format: { + Offset: 0x0, + Position: 0x0, + Length: 0xD30, + SHA256: 1FA753CE387CFA25CEA102F0CF36DB692C1F739F82203E5F795498964EB07447 + }, + Name: audio0000, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xD30, + Position: 0x0, + Length: 0x3DA0, + SHA256: C4EBD0AD1BF1D748DA2A15C91EE97CA66DEB204F79FE71F165FBFA0827082BAF + }, + Name: audio0001, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x4AD0, + Position: 0x0, + Length: 0x13F0, + SHA256: A0BC708D1A56FBDFD986E16CC422A9863F9FDA5B5527AAE3B5891AFD16E9A2A9 + }, + Name: audio0002, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x5EC0, + Position: 0x0, + Length: 0x4680, + SHA256: 1243CFB48C2F251F718FB5DEECAA1778D46BFE734F8F6CDF580BBFB8F6A03435 + }, + Name: audio0003, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xA540, + Position: 0x0, + Length: 0xB760, + SHA256: 5112DA9E85158AD83D7877EA014070BEE0E1969FBFE83ED5AC110470D5FBD53E + }, + Name: audio0004, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x15CA0, + Position: 0x0, + Length: 0x5130, + SHA256: 1210A66CA10D902B0236D47F2D08BBAC4F03199CB4FE05DA6D5E064392C93D41 + }, + Name: audio0005, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1ADD0, + Position: 0x0, + Length: 0x12660, + SHA256: 4C311B4D28B640A33490ED6FAC112B5EBEEFCF564FDD6689A6D5CB31E9A18D92 + }, + Name: audio0006, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x2D430, + Position: 0x0, + Length: 0x2380, + SHA256: 62A5B00699A0C23DED7B0F17E13B245CA7EEF35B8B91E573265624582EED241E + }, + Name: audio0007, + Children: null, + Tags: null + } +] \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/MG_AUDIO1.VH.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/MG_AUDIO1.VH.verified.txt new file mode 100644 index 0000000..da5b745 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/MG_AUDIO1.VH.verified.txt @@ -0,0 +1,59 @@ +{ + Version: 0x5, + VabId: 0x0, + Reserved0: 0x0, + MasterVolume: 0x7F, + MasterPan: 0x40, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0x0, + ProgramsAttributes: [ + { + Index: 0, + MasterVolume: 127, + Priority: 0, + Mode: 224, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: 0, + Reserved2: 0, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 64, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 2, + PitchBendMaximum: 2, + Reserved0: 0, + Reserved1: 0, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 0, + ProgramIndex: 0, + WaveformIndex: 0, + Reserved2: 0 + } + ] + } + ], + WaveformSizes: [ + 3376, + 15776, + 5104, + 18048, + 46944, + 20784, + 75360, + 9088 + ] +} \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/MOHO_MOHO9.VB.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/MOHO_MOHO9.VB.verified.txt new file mode 100644 index 0000000..ed75147 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/MOHO_MOHO9.VB.verified.txt @@ -0,0 +1,519 @@ +[ + { + Format: { + Offset: 0x0, + Position: 0x0, + Length: 0x13F0, + SHA256: 16F2F6948283A2579FDF4BA16F3B63251B045B46CC1ADC95AE2477C5C17B2E88 + }, + Name: audio0000, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x13F0, + Position: 0x0, + Length: 0x2190, + SHA256: 0BDF5FAAAC23E4B58B45A64B3548657E65A1D947EE12D0849CBC3F0F2918640E + }, + Name: audio0001, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3580, + Position: 0x0, + Length: 0x4DA0, + SHA256: DC4EA9EDC82A530DBC491160FF499DBD5BF6C0FEFCEF0CBB8F3FD4ECB7F91DE3 + }, + Name: audio0002, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x8320, + Position: 0x0, + Length: 0x2550, + SHA256: 63A9D7D405E6748FB25A498A4DFF37EA1C03D4295CBCE62D329A7AA848CEB884 + }, + Name: audio0003, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xA870, + Position: 0x0, + Length: 0x36F0, + SHA256: 4585E2687C8E0408F3ED91DEC5BF8ADB4AFD8D9BE5EA53A6F7621FD7269A8725 + }, + Name: audio0004, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xDF60, + Position: 0x0, + Length: 0x1D90, + SHA256: 92EF05FFD148DCF3C75CBDD3EA6D18B27573CC92ECD355F22DB1FCB2C3957AE5 + }, + Name: audio0005, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xFCF0, + Position: 0x0, + Length: 0x3490, + SHA256: 58423EA574895BF028CD1D87A3B4C5AE5B7B4914B4DD6AA3DD416C58EB1CAC1F + }, + Name: audio0006, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x13180, + Position: 0x0, + Length: 0x10B0, + SHA256: BA76B25AD4CD7C1309D8AC4F9D821D4BC1B4181D530E651FA97A791857D2529F + }, + Name: audio0007, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x14230, + Position: 0x0, + Length: 0x14A0, + SHA256: A7871E5B21E3582CBFCF728D93C6FA8E3C06B8124967E65274ED52A6F5EBB49A + }, + Name: audio0008, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x156D0, + Position: 0x0, + Length: 0x1E90, + SHA256: EEE64C1CC04FC7307930841756CCE4A40F9CB1FA04192449BEB6470F92E183E3 + }, + Name: audio0009, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x17560, + Position: 0x0, + Length: 0x21E0, + SHA256: 202C01F3CA135C9EFA185F52C05A3E7FC2EAE1E48DC19A24D634FF651054E5B7 + }, + Name: audio0010, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x19740, + Position: 0x0, + Length: 0x2010, + SHA256: 287B3E100A492951690E779DF20A2E819107ADBB3BA1889B2ACE935717588490 + }, + Name: audio0011, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1B750, + Position: 0x0, + Length: 0xFC0, + SHA256: C4F3A4597BC33DF95850A1D7A27EEF641B3807378CCBAAAD4E7960B821F7826C + }, + Name: audio0012, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1C710, + Position: 0x0, + Length: 0x3990, + SHA256: 085E591092928DAB9A56D4576C12AD3DC8D6CC2F066EE6FBCC3DFA05663A05BD + }, + Name: audio0013, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x200A0, + Position: 0x0, + Length: 0x30B0, + SHA256: ABC15AEFCDAF76C35F3B723C594CFB760D5A1521BA222E12EBD74EDC9CC46830 + }, + Name: audio0014, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x23150, + Position: 0x0, + Length: 0x1500, + SHA256: 466DBFAE0CC8D0E17634040561618D6635642E424BFE693507139437D6640E20 + }, + Name: audio0015, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x24650, + Position: 0x0, + Length: 0x1240, + SHA256: 5DAB713AAF9F3964EFEF699381253652F0ABCF025992C6A8DB9F3AF1F83B1966 + }, + Name: audio0016, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x25890, + Position: 0x0, + Length: 0x1FB0, + SHA256: A5D3667CB3D91024DC2F9F6F13732BAE3CF277B62E8AE5293AB1C0378D1E9D34 + }, + Name: audio0017, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x27840, + Position: 0x0, + Length: 0x1510, + SHA256: 0A1DACCC69DDABB5645A6CF8AE57774BC42ED894549B23660112674075E69C27 + }, + Name: audio0018, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x28D50, + Position: 0x0, + Length: 0x1240, + SHA256: E59DEE8CFFC9313216B825293FA0FD13801B8D8A465F26478A8CAB5A207FF693 + }, + Name: audio0019, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x29F90, + Position: 0x0, + Length: 0x68B0, + SHA256: 66706B07BFE4B670A03C102FB7800A132B70822956707352DA0054EED547C68E + }, + Name: audio0020, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x30840, + Position: 0x0, + Length: 0x6FB0, + SHA256: 1F95B748CC3085B5AB6BC8BA12A78E2088FCA1A7911F68EC4079FEBB9E0CC2B9 + }, + Name: audio0021, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x377F0, + Position: 0x0, + Length: 0x44B0, + SHA256: 5747774A340793C900A15DC305A15EFE714FE4721D17DE8D5F49C398AAEA5D8F + }, + Name: audio0022, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3BCA0, + Position: 0x0, + Length: 0x2F20, + SHA256: FAB2A277EE1EEF2D80ED0894B6A27760D3AD399959A8C4012576C16753A9EE55 + }, + Name: audio0023, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3EBC0, + Position: 0x0, + Length: 0x2BE0, + SHA256: 30E4FE5E5ABED44BA757808A6F8E9E53175D2C42512DB7BF99137EB9CAF02DE6 + }, + Name: audio0024, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x417A0, + Position: 0x0, + Length: 0x3940, + SHA256: 96A10287E8A447CEA3B9EEE27CE986448386D30EB02522F796F93E6285BBD446 + }, + Name: audio0025, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x450E0, + Position: 0x0, + Length: 0x7020, + SHA256: 0F8D2836529473C48775AE38F654AF16A88F4323E703C1DAD51BF957C53821F7 + }, + Name: audio0026, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x4C100, + Position: 0x0, + Length: 0x4B90, + SHA256: BAC55FADB670AB85BD70803408C1D3CA8112F04461AFF49727CB78D4203A6735 + }, + Name: audio0027, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x50C90, + Position: 0x0, + Length: 0x42B0, + SHA256: F1CCEBCF23B4469EF084880ADFFE4C3D6B17141DE2A121A2315ED68D92C92488 + }, + Name: audio0028, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x54F40, + Position: 0x0, + Length: 0x12A0, + SHA256: AEE24292C8128A4940F9CB845604E70E54149EB22376B418E6C43C09E5503B25 + }, + Name: audio0029, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x561E0, + Position: 0x0, + Length: 0x14C0, + SHA256: 8FCD7FE35C89C0D82914CD2161D05EEF637661D1B85F98DE8C5FCAF3BDC068C0 + }, + Name: audio0030, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x576A0, + Position: 0x0, + Length: 0x11B0, + SHA256: 6BD418BE6A81F474FE500E8EC8F5322E3E2C9D62CE0EBC7C38B551BE1DAC953E + }, + Name: audio0031, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x58850, + Position: 0x0, + Length: 0x1260, + SHA256: 4262292C5ECAA552050557E79C2900E97DB1D372A30FC2BEC162B83867D2E38B + }, + Name: audio0032, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x59AB0, + Position: 0x0, + Length: 0x1160, + SHA256: F0387541230F25F7C2C4FD2AA17071FA6299377CEAF1C9709FDC9FFFAE0C5761 + }, + Name: audio0033, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x5AC10, + Position: 0x0, + Length: 0x2C20, + SHA256: 1F5A51A6AB927E60964FFDDFDAE657164C3D9F122662746EECA3398BAF8567C7 + }, + Name: audio0034, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x5D830, + Position: 0x0, + Length: 0x2980, + SHA256: E8FC925BCBC548FA481386CB9AF99EBEE9271F2BD637B23E53EADE8E331AA825 + }, + Name: audio0035, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x601B0, + Position: 0x0, + Length: 0x3040, + SHA256: 10F35F3DA4AF4B7BA385F1E110C84D385FA71C8BEC8AC39539CF62B85F068E0C + }, + Name: audio0036, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x631F0, + Position: 0x0, + Length: 0x20F0, + SHA256: FBD0F3025D6F9FDE6E62371FE9F723E1260D32C03E0EE5B965170630ECA56967 + }, + Name: audio0037, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x652E0, + Position: 0x0, + Length: 0x1330, + SHA256: 756BAAD951AB6CB9F46055B6ECE0FF4D018B596E9D13A024873164C6AC986B90 + }, + Name: audio0038, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x66610, + Position: 0x0, + Length: 0x1460, + SHA256: 8B9617A2B2AD1DC1B253FE2491C6B699E296CD9920696787BF4C6EFFF1B06E90 + }, + Name: audio0039, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x67A70, + Position: 0x0, + Length: 0x1600, + SHA256: B6470B50A66971759F853369544D3814C1438F8062FFF4E8B7222E735F1D7B8A + }, + Name: audio0040, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x69070, + Position: 0x0, + Length: 0x1A40, + SHA256: C98BF0D29D5BD5912E64AC066A41D1EEC898B9277BF159FAD403FED43C2EDA56 + }, + Name: audio0041, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6AAB0, + Position: 0x0, + Length: 0x1510, + SHA256: CC5DAF581575B9CB93372D6D29BC629515359216AB32FA928902B7641A3E969F + }, + Name: audio0042, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6BFC0, + Position: 0x0, + Length: 0x2980, + SHA256: 235493AB38BA6F2A4C87F15370C7B8EEAB4E479037C3E68E8B93D38F62690FBB + }, + Name: audio0043, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6E940, + Position: 0x0, + Length: 0x1AB0, + SHA256: C8A7AF2DBF236D078A234E070A0F395484812DBEDE9EBA679128E3ABCAF25BC0 + }, + Name: audio0044, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x703F0, + Position: 0x0, + Length: 0x19A0, + SHA256: F39B6C4BEB89996C79DE218E78B3E23A0B200F96C0CA519039D24CCE30AE4D8E + }, + Name: audio0045, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x71D90, + Position: 0x0, + Length: 0x1370, + SHA256: A3D7184A47996A9F9CCF768EE9399D090093B7926C8E4BCE387C8C29A896362D + }, + Name: audio0046, + Children: null, + Tags: null + } +] \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/MOHO_MOHO9.VH.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/MOHO_MOHO9.VH.verified.txt new file mode 100644 index 0000000..d63b093 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/MOHO_MOHO9.VH.verified.txt @@ -0,0 +1,2227 @@ +{ + Version: 0x6, + VabId: 0x0, + Reserved0: 0xEEEE, + MasterVolume: 0x7F, + MasterPan: 0x40, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0xFFFFFFFF, + ProgramsAttributes: [ + { + Index: 0, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 80, + Panning: 64, + Centre: 81, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 12, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 1, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 2, + MasterVolume: 100, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 2, + WaveformIndex: 2, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 3, + MasterVolume: 115, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 3, + WaveformIndex: 3, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 4, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 79, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32560, + EnvelopeSettings2: 16384, + ProgramIndex: 4, + WaveformIndex: 4, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 5, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 80, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 5, + WaveformIndex: 4, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 6, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 86, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 6, + WaveformIndex: 4, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 7, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 7, + WaveformIndex: 6, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 8, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 8, + WaveformIndex: 7, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 9, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 9, + WaveformIndex: 17, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 10, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 104, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 10, + WaveformIndex: 9, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 11, + MasterVolume: 100, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 85, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 11, + WaveformIndex: 10, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 12, + MasterVolume: 100, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 86, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 12, + WaveformIndex: 11, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 13, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 13, + WaveformIndex: 5, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 14, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 14, + WaveformIndex: 13, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 15, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 15, + WaveformIndex: 15, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 16, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 16, + WaveformIndex: 16, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 17, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 87, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 17, + WaveformIndex: 16, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 18, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 75, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 18, + WaveformIndex: 8, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 19, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 75, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 19, + WaveformIndex: 18, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 20, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 20, + WaveformIndex: 19, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 21, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 90, + Panning: 4, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 21, + WaveformIndex: 28, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 90, + Panning: 124, + Centre: 86, + Fine: 50, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 21, + WaveformIndex: 28, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 22, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 60, + Panning: 4, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 22, + WaveformIndex: 21, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 60, + Panning: 124, + Centre: 88, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 22, + WaveformIndex: 21, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 23, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 95, + Panning: 4, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 23, + WaveformIndex: 24, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 110, + Panning: 124, + Centre: 88, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 23, + WaveformIndex: 24, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 24, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 80, + Panning: 4, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 24, + WaveformIndex: 20, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 75, + Panning: 124, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 24, + WaveformIndex: 26, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 25, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 110, + Panning: 4, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 25, + WaveformIndex: 23, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 110, + Panning: 124, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 25, + WaveformIndex: 27, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 26, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 4, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 26, + WaveformIndex: 22, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 124, + Centre: 82, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 26, + WaveformIndex: 22, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 27, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 120, + Panning: 54, + Centre: 88, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 27, + WaveformIndex: 25, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 120, + Panning: 84, + Centre: 85, + Fine: 99, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 27, + WaveformIndex: 25, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 28, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 83, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -20737, + EnvelopeSettings2: 24512, + ProgramIndex: 28, + WaveformIndex: 14, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 29, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 29, + WaveformIndex: 29, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 30, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 30, + WaveformIndex: 30, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 31, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 31, + WaveformIndex: 31, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 32, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 32, + WaveformIndex: 32, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 33, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 33, + WaveformIndex: 33, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 34, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 34, + WaveformIndex: 34, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 35, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 35, + WaveformIndex: 35, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 36, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 36, + WaveformIndex: 36, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 37, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 37, + WaveformIndex: 37, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 38, + MasterVolume: 90, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 38, + WaveformIndex: 38, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 39, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 75, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 39, + WaveformIndex: 39, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 40, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 40, + WaveformIndex: 40, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 41, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 41, + WaveformIndex: 41, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 42, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 42, + WaveformIndex: 42, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 43, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 43, + WaveformIndex: 43, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 44, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 88, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 44, + WaveformIndex: 44, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 45, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 88, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 45, + WaveformIndex: 45, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 46, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 87, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 46, + WaveformIndex: 42, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 47, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 87, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 47, + WaveformIndex: 43, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 48, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 48, + WaveformIndex: 44, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 49, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 49, + WaveformIndex: 45, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 50, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 87, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 50, + WaveformIndex: 40, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 51, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 87, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 51, + WaveformIndex: 41, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 52, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 75, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 52, + WaveformIndex: 46, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 53, + MasterVolume: 127, + Priority: 0, + Mode: 19, + MasterPanning: 63, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 75, + Panning: 64, + Centre: 84, + Fine: 0, + Minimum: 0, + Maximum: 127, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: 0, + EnvelopeSettings2: 0, + ProgramIndex: 53, + WaveformIndex: 0, + Reserved2: 54888453694881984 + } + ] + } + ], + WaveformSizes: [ + 5104, + 8592, + 19872, + 9552, + 14064, + 7568, + 13456, + 4272, + 5280, + 7824, + 8672, + 8208, + 4032, + 14736, + 12464, + 5376, + 4672, + 8112, + 5392, + 4672, + 26800, + 28592, + 17584, + 12064, + 11232, + 14656, + 28704, + 19344, + 17072, + 4768, + 5312, + 4528, + 4704, + 4448, + 11296, + 10624, + 12352, + 8432, + 4912, + 5216, + 5632, + 6720, + 5392, + 10624, + 6832, + 6560, + 4976 + ] +} \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/RE2_ROOM60C0_snd0.vb.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/RE2_ROOM60C0_snd0.vb.verified.txt new file mode 100644 index 0000000..53f3818 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/RE2_ROOM60C0_snd0.vb.verified.txt @@ -0,0 +1,244 @@ +[ + { + Format: { + Offset: 0x0, + Position: 0x0, + Length: 0x30, + SHA256: 4A6B20A637CDF77436FA98C9BFC335B109B787DDFA50FB687B2F394F4E70CBD6 + }, + Name: audio0000, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x30, + Position: 0x0, + Length: 0xA00, + SHA256: 844BE9C0364225168F14FAD8DE911032F4CC83BFECB8C6E9E0B20144952489E8 + }, + Name: audio0001, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xA30, + Position: 0x0, + Length: 0x10C0, + SHA256: 6EDAD0F2D5A93A452A33509124320EC139553EFC2615D575FB475DF67FCF46B7 + }, + Name: audio0002, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1AF0, + Position: 0x0, + Length: 0xD20, + SHA256: C1B8BDA18591FFEF9D4B9F84EC171974F0250780412C8AD97D4E0A58E457E9F6 + }, + Name: audio0003, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x2810, + Position: 0x0, + Length: 0xCE0, + SHA256: CA76117EF548A47E0D65EC366EFC7FCD96754D59715F53615CB78162871EFAAA + }, + Name: audio0004, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x34F0, + Position: 0x0, + Length: 0xF00, + SHA256: 6848133A99AD9AFD634EEB991E9798DE7C8F72E318D27A83919BBFB3740673B6 + }, + Name: audio0005, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x43F0, + Position: 0x0, + Length: 0x930, + SHA256: CC40262B305752D28CA54BFE7FAC7D5042DDFB6D218124A338A21F8A9A0B80ED + }, + Name: audio0006, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x4D20, + Position: 0x0, + Length: 0x16C0, + SHA256: D9443254AFDDF86533ED023E99F3CB64C5404CA9BF0B13E63B43C0C80D0AAC82 + }, + Name: audio0007, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x63E0, + Position: 0x0, + Length: 0x1800, + SHA256: 8C2F88B8F105E11C0C14CCFDD58D035B5718B9F4C99A31EE7AFA4F77CEB511B5 + }, + Name: audio0008, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x7BE0, + Position: 0x0, + Length: 0x20F0, + SHA256: 510B4AEC1E2B687BFD196760CC80ECA261D85A77DD0BCF950F4963A22B9E8221 + }, + Name: audio0009, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x9CD0, + Position: 0x0, + Length: 0x22F0, + SHA256: 43461C37526ED8AC0BC45F56CCE17D386868B1C05A17CD00AB52FC16B09A8955 + }, + Name: audio0010, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xBFC0, + Position: 0x0, + Length: 0x8BE0, + SHA256: DA69CACAB05A039EF4087EB077884B15D42DB4252CAEA8E900249B4287AC0839 + }, + Name: audio0011, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x14BA0, + Position: 0x0, + Length: 0x22F0, + SHA256: 43461C37526ED8AC0BC45F56CCE17D386868B1C05A17CD00AB52FC16B09A8955 + }, + Name: audio0012, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x16E90, + Position: 0x0, + Length: 0xA70, + SHA256: E4FA37D36D566F4CFF429F8490C76BA09DA76E36BD13082D3A57328AE4C4713D + }, + Name: audio0013, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x17900, + Position: 0x0, + Length: 0x5E0, + SHA256: 12480EF5FAC1277CACD06B59975E755BF7670056179E938A891C0F9ECA607B5D + }, + Name: audio0014, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x17EE0, + Position: 0x0, + Length: 0x1420, + SHA256: DDA9A22A36472B2C266CC6C4612A52611F3830F08D86ADC117054CA490C666E2 + }, + Name: audio0015, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x19300, + Position: 0x0, + Length: 0x1A80, + SHA256: EDC4B921AF94469AC29CC15CB3B597CAC399395F0857B87F4F20DE8804ABB788 + }, + Name: audio0016, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1AD80, + Position: 0x0, + Length: 0x1B10, + SHA256: 16B3AB2B6B580E46706CF13A9395BA43C28717BC50076537A93C1B55144B473E + }, + Name: audio0017, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1C890, + Position: 0x0, + Length: 0xAF0, + SHA256: 146B20F4E4D4C875624808B017BFA6098E19AF0EA766DC01A5A5313B7AAA6745 + }, + Name: audio0018, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1D380, + Position: 0x0, + Length: 0x5B0, + SHA256: 6AECD7A934172B1059F1A2CE98414C06E221E07A8F6B329E13F1C04E96123105 + }, + Name: audio0019, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1D930, + Position: 0x0, + Length: 0x400, + SHA256: 1B2F0563CBDE02447E885855CAA6E1945E6A38BA8252B84C134B82B4368D1E7E + }, + Name: audio0020, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1DD30, + Position: 0x0, + Length: 0x6360, + SHA256: 782C982C31BD339C52082855D1124519822623C327C45B02A3BB46E5A9252CCC + }, + Name: audio0021, + Children: null, + Tags: null + } +] \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/RE2_ROOM60C0_snd0.vh.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/RE2_ROOM60C0_snd0.vh.verified.txt new file mode 100644 index 0000000..904fa9f --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/RE2_ROOM60C0_snd0.vh.verified.txt @@ -0,0 +1,662 @@ +{ + Version: 0x7, + VabId: 0x0, + Reserved0: 0xEEEE, + MasterVolume: 0x7F, + MasterPan: 0x40, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0xFFFFFFFF, + ProgramsAttributes: [ + { + Index: 0, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 64, + Centre: 83, + Fine: 59, + Minimum: 59, + Maximum: 59, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 85, + Panning: 64, + Centre: 86, + Fine: 39, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 85, + Panning: 64, + Centre: 86, + Fine: 39, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 86, + Fine: 0, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 50, + Panning: 64, + Centre: 87, + Fine: 0, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 14, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 60, + Panning: 64, + Centre: 86, + Fine: 0, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 14, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 89, + Fine: 109, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 2, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 75, + Panning: 64, + Centre: 90, + Fine: 0, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 6, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 89, + Fine: 0, + Minimum: 67, + Maximum: 67, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 6, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 94, + Fine: 39, + Minimum: 68, + Maximum: 68, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 104, + Fine: 59, + Minimum: 69, + Maximum: 69, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 21, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 64, + Centre: 83, + Fine: 59, + Minimum: 70, + Maximum: 70, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 80, + Panning: 64, + Centre: 89, + Fine: 57, + Minimum: 71, + Maximum: 71, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 90, + Fine: 57, + Minimum: 72, + Maximum: 72, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 11, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 91, + Fine: 57, + Minimum: 73, + Maximum: 73, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 9, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 92, + Fine: 57, + Minimum: 74, + Maximum: 74, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 0, + WaveformIndex: 10, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 1, + MasterVolume: 127, + Priority: 255, + Mode: 255, + MasterPanning: 64, + Reserved0: 255, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 64, + Centre: 83, + Fine: 59, + Minimum: 59, + Maximum: 59, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 78, + Fine: 57, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 8, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 80, + Panning: 64, + Centre: 85, + Fine: 0, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 16, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 64, + Centre: 83, + Fine: 59, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 93, + Fine: 57, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 15, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 82, + Fine: 57, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 17, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 70, + Panning: 64, + Centre: 95, + Fine: 57, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 18, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 90, + Fine: 0, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 19, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 85, + Fine: 57, + Minimum: 67, + Maximum: 67, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 8128, + ProgramIndex: 1, + WaveformIndex: 20, + Reserved2: 54888453694881984 + } + ] + } + ], + WaveformSizes: [ + 48, + 2560, + 4288, + 3360, + 3296, + 3840, + 2352, + 5824, + 6144, + 8432, + 8944, + 35808, + 8944, + 2672, + 1504, + 5152, + 6784, + 6928, + 2800, + 1456, + 1024, + 25440 + ] +} \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/S001.vab.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/S001.vab.verified.txt new file mode 100644 index 0000000..ad3c8e9 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/S001.vab.verified.txt @@ -0,0 +1,463 @@ +[ + { + Format: { + Offset: 0xA20, + Position: 0x0, + Length: 0x7C0, + SHA256: CE08D21C813B9782A2ECB1A04C46BB627CB7AD90291E4D0A69D151FB166567ED + }, + Name: audio0000, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x11E0, + Position: 0x0, + Length: 0x730, + SHA256: 8DBB09D350CF3D26D9D64C8C3E86E0C0FB71AE16B750DB5F7F843BDA6BDCF938 + }, + Name: audio0001, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1910, + Position: 0x0, + Length: 0x640, + SHA256: 9E2C94A6E1C4FC5AB401EA2CA85FBDCAF47C3F728216AAA9351ACFA75761122E + }, + Name: audio0002, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1F50, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0003, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1FB0, + Position: 0x0, + Length: 0xC50, + SHA256: 6DA78B6C90942CC807790477DA8B3591050620E8B6ED628296D7A32E731AC733 + }, + Name: audio0004, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x2C00, + Position: 0x0, + Length: 0x14E0, + SHA256: 81729BD6D8A66038CFF25448BF68A51154438C5E51E26199F4AB05087DAA8663 + }, + Name: audio0005, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x40E0, + Position: 0x0, + Length: 0xD90, + SHA256: D911C1461F207F7C50E6143C0DCB949C8B2D34BE021893437DF9AA66171345C7 + }, + Name: audio0006, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x4E70, + Position: 0x0, + Length: 0x10B0, + SHA256: E167FBBDD2EEA376301E0FBFCCFE8F34E3ED19EFC5139BC44D92B025373A5C5F + }, + Name: audio0007, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x5F20, + Position: 0x0, + Length: 0x1FE0, + SHA256: BD4B1810A290DEB13BAA400E1D2CACC9B50F0FFA2E1EA10E87062C799CC7F2D7 + }, + Name: audio0008, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x7F00, + Position: 0x0, + Length: 0x3150, + SHA256: A173A5ED050225922C39431E4FA8C82C942ECF0E2C05AA588BC3FBE7A64B9F61 + }, + Name: audio0009, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xB050, + Position: 0x0, + Length: 0x1610, + SHA256: AD3C0AFAA3FAE490FE0051CD29885489E3BB0E32898411CB318097C954A13455 + }, + Name: audio0010, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xC660, + Position: 0x0, + Length: 0xF40, + SHA256: EDBEE6F0444F47BF1B6D0642054530E3B699342FBBFE53C0D705B3F9F0817D20 + }, + Name: audio0011, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xD5A0, + Position: 0x0, + Length: 0x2170, + SHA256: 4EB0A31F14D8198654AABBB27663ED5A2D232865DCDBAF0BC83E451993A093D8 + }, + Name: audio0012, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xF710, + Position: 0x0, + Length: 0x11A0, + SHA256: 6EB31CB0F22660463704EF80FE8C24269D5F259DC609B4FB81BDC95556BD773F + }, + Name: audio0013, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x108B0, + Position: 0x0, + Length: 0x2160, + SHA256: 55D1EA3C07DD8995EBCA05319EA131C119FEE2BAE3B54D339ECA85843DFB7983 + }, + Name: audio0014, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x12A10, + Position: 0x0, + Length: 0x10A0, + SHA256: 57EF31D491C71FB5BFF7070090F9A074F58E9A40A561FFAFE688D50272D3C91D + }, + Name: audio0015, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x13AB0, + Position: 0x0, + Length: 0x1D90, + SHA256: CC7F95C7FA8BD986C17594A7F152B9E565482D7E3115875A279658B4AA68399C + }, + Name: audio0016, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x15840, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0017, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x158A0, + Position: 0x0, + Length: 0x1130, + SHA256: BC011C9FB8AD89C36C4EC444140205AEACD18A3DB12D9116B687020514B74573 + }, + Name: audio0018, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x169D0, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0019, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x16A30, + Position: 0x0, + Length: 0x830, + SHA256: C033781D3B7D35AAC3FC6E645A000CCC05BB291946BD6D9DA731D5BE54721C57 + }, + Name: audio0020, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x17260, + Position: 0x0, + Length: 0x1880, + SHA256: 0EE3DAF7DFC4720786B8E5DB4F4221823FE39B81F5801B1B0413DE54E69943F6 + }, + Name: audio0021, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x18AE0, + Position: 0x0, + Length: 0x10E0, + SHA256: 3F8DCBD141DF5C0AEF1D381172B5E1A915A6B42BC52645107D930107BD024A5C + }, + Name: audio0022, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x19BC0, + Position: 0x0, + Length: 0x2390, + SHA256: 9CF74C4A88E10D401DB92D83FA685D3F0E1B37079B8D025039343C88C02ABF36 + }, + Name: audio0023, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1BF50, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0024, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1BFB0, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0025, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1C010, + Position: 0x0, + Length: 0x1160, + SHA256: B9E79F53348857676EB16BD0E3AECDFCD82FECA771E1CA33CFCDFCFD0FCCED91 + }, + Name: audio0026, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1D170, + Position: 0x0, + Length: 0xDE0, + SHA256: 5409FC6AB02C975EC6CDE047FA65EBE056213658394BCEDFAEC9760754E2DFD5 + }, + Name: audio0027, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1DF50, + Position: 0x0, + Length: 0x1AC0, + SHA256: 643B0B26F0A048F38D1243ED4CB06CDF3406D75A4237576EF60F71192EA28F82 + }, + Name: audio0028, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1FA10, + Position: 0x0, + Length: 0x1970, + SHA256: 3A8ED3984D9ECF054362B94E9805ED628F5296FA7099495169341F494AF9BB4E + }, + Name: audio0029, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x21380, + Position: 0x0, + Length: 0x1B00, + SHA256: 632AD2A9CAD718ACD89EDA9EF85164B5DF6BC9E872180D79428B44EA9FEFBCD4 + }, + Name: audio0030, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x22E80, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0031, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x22EE0, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0032, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x22F40, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0033, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x22FA0, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0034, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x23000, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0035, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x23060, + Position: 0x0, + Length: 0x60, + SHA256: 7E123B807CB8473A835F9AB59877CB96DBF7DAD28324A308A1A7F7132DAEEFB9 + }, + Name: audio0036, + Children: null, + Tags: null + }, + { + Format: { + Version: 0x5, + VabId: 0x0, + Reserved0: 0xEEEE, + MasterVolume: 0x0, + MasterPan: 0x0, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0xFFFFFFFF, + WaveformSizes: [ + 1984, + 1840, + 1600, + 96, + 3152, + 5344, + 3472, + 4272, + 8160, + 12624, + 5648, + 3904, + 8560, + 4512, + 8544, + 4256, + 7568, + 96, + 4400, + 96, + 2096, + 6272, + 4320, + 9104, + 96, + 96, + 4448, + 3552, + 6848, + 6512, + 6912, + 96, + 96, + 96, + 96, + 96, + 96 + ] + }, + Name: header, + Children: null, + Tags: null + } +] \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/TC1_001.vh.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/TC1_001.vh.verified.txt new file mode 100644 index 0000000..0eaf45f --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/TC1_001.vh.verified.txt @@ -0,0 +1,3036 @@ +{ + Version: 0x7, + VabId: 0x0, + Reserved0: 0xEEEE, + MasterVolume: 0x73, + MasterPan: 0x40, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0xFFFFFFFF, + ProgramsAttributes: [ + { + Index: 0, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 32, + Mode: 0, + Volume: 0, + Panning: 64, + Centre: 60, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 31, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 33, + Mode: 0, + Volume: 0, + Panning: 64, + Centre: 60, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 31, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 24, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 66, + Fine: 107, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 25, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 66, + Fine: 107, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 24, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 67, + Fine: 107, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 12, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 25, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 67, + Fine: 107, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 12, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 1, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 2, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 6, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 6, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 85, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 40, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 40, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 86, + Fine: 67, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 41, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 41, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 87, + Fine: 67, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 42, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 42, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 88, + Fine: 67, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 43, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 43, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 89, + Fine: 67, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 44, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 2, + WaveformIndex: 44, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 3, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 27, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 27, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 28, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 28, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 4, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 7, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 7, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 21, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 21, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 5, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 29, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 29, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 30, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 30, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 6, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 6, + WaveformIndex: 20, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 6, + WaveformIndex: 20, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 125, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 6, + WaveformIndex: 31, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 125, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 6, + WaveformIndex: 31, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 7, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 82, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 22, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 82, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 22, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 23, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 83, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 23, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 24, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 24, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 85, + Fine: 67, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 25, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 85, + Fine: 67, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 25, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 86, + Fine: 67, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 26, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 86, + Fine: 67, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 26, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 88, + Fine: 67, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 32, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 88, + Fine: 67, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 32, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 89, + Fine: 67, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 33, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 89, + Fine: 67, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 7, + WaveformIndex: 33, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 8, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 28, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 77, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 29, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 78, + Fine: 70, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 16, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 17, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 80, + Fine: 70, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 18, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 81, + Fine: 70, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 10, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 10, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 9, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 17, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 78, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 14, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 14, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 17, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 61, + Fine: 0, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 37, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 37, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 36, + Mode: 0, + Volume: 105, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 2, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 38, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 38, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 10, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 28, + Mode: 0, + Volume: 80, + Panning: 64, + Centre: 77, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 29, + Mode: 0, + Volume: 80, + Panning: 64, + Centre: 78, + Fine: 70, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 16, + Mode: 0, + Volume: 80, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 17, + Mode: 0, + Volume: 80, + Panning: 64, + Centre: 80, + Fine: 70, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 28, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 81, + Fine: 70, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 29, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 82, + Fine: 70, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 16, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 83, + Fine: 70, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 17, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 84, + Fine: 70, + Minimum: 67, + Maximum: 67, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 10, + WaveformIndex: 39, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 11, + MasterVolume: 0, + Priority: 89, + Mode: 40, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 12, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 29, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 77, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 2, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 2, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 16, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 2, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 8, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 8, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 19, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 79, + Fine: 100, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 11, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 11, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 21, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 90, + Fine: 70, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 13, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 22, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 91, + Fine: 70, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 13, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 23, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 92, + Fine: 70, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 13, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 21, + Mode: 0, + Volume: 120, + Panning: 64, + Centre: 89, + Fine: 67, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 34, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 34, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 13, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 21, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 78, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 21, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 1, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 1, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 21, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 9, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 9, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 21, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 80, + Fine: 50, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 9, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 9, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 22, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 81, + Fine: 70, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 36, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 36, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 29, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 82, + Fine: 70, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 35, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 35, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 14, + MasterVolume: 127, + Priority: 89, + Mode: 40, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 20, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 78, + Fine: 80, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 15, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 15, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 21, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 16, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 16, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 19, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 80, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 17, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 17, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 110, + Panning: 96, + Centre: 81, + Fine: 70, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 18, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 110, + Panning: 32, + Centre: 80, + Fine: 70, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 18, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 120, + Panning: 32, + Centre: 82, + Fine: 70, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 19, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 120, + Panning: 96, + Centre: 81, + Fine: 70, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 14, + WaveformIndex: 19, + Reserved2: 54888453694881984 + } + ] + } + ], + WaveformSizes: [ + 2096, + 2016, + 3520, + 2208, + 2352, + 27760, + 18208, + 5568, + 4032, + 3600, + 16064, + 7392, + 29392, + 17680, + 11024, + 4592, + 3456, + 20832, + 16144, + 15744, + 21616, + 2848, + 6896, + 8096, + 6736, + 7280, + 9232, + 24176, + 36400, + 9216, + 9008, + 26512, + 40320, + 12688, + 13552, + 5408, + 16416, + 7152, + 8464, + 3184, + 6592, + 2672, + 2992, + 3760, + 3376 + ] +} \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/TC1_002.vb.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/TC1_002.vb.verified.txt new file mode 100644 index 0000000..a3a057a --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/TC1_002.vb.verified.txt @@ -0,0 +1,497 @@ +[ + { + Format: { + Offset: 0x0, + Position: 0x0, + Length: 0x830, + SHA256: ABF0A919750F8739F80124CAC4D3C0A5A180F5EF0F625094ABF0B98453D06515 + }, + Name: audio0000, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x830, + Position: 0x0, + Length: 0x7E0, + SHA256: 5759FCECD3A317A8937D18E0A68C1371D30F9F2B48D06EFD8CA021A58CE0F887 + }, + Name: audio0001, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1010, + Position: 0x0, + Length: 0xDC0, + SHA256: 541639B9A9FF027F6574AD07B2406DDE22841413DA8FE1571FEBCBBAFA2B3593 + }, + Name: audio0002, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1DD0, + Position: 0x0, + Length: 0x8A0, + SHA256: CF7FD1EE2E9436C71E92716C217C10D031E0A53A13BB687AE2130263D8A43DA5 + }, + Name: audio0003, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x2670, + Position: 0x0, + Length: 0x930, + SHA256: F69FC835941BE71589286418CAEDDF4E7FA6100C40222071037D54542840289B + }, + Name: audio0004, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x2FA0, + Position: 0x0, + Length: 0x6C70, + SHA256: D4912046FC2ABB9F3031D05F6B2D4C47F71359E6CD9AB2ADBE44D3DD8F947F08 + }, + Name: audio0005, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x9C10, + Position: 0x0, + Length: 0x4720, + SHA256: 212D90AED0BB3870A896E8B1D06D3147C4E90281450B5D1D5C556BDA200E03F1 + }, + Name: audio0006, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xE330, + Position: 0x0, + Length: 0x15C0, + SHA256: 05D4759259341FDCECD4936B73D363CB9A8E52C68AC060F0311B6F0DA1A7805A + }, + Name: audio0007, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0xF8F0, + Position: 0x0, + Length: 0xFC0, + SHA256: 60CB27ABBB182D1181FE4C6316380C847645D9802538AFB73A716957A3C9A7E5 + }, + Name: audio0008, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x108B0, + Position: 0x0, + Length: 0xE10, + SHA256: ACC0D7E533D1A76B9DC420F3D7384FB6ACE6493C8C3F180C34AFC6F6D474C377 + }, + Name: audio0009, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x116C0, + Position: 0x0, + Length: 0x3EC0, + SHA256: BFBD3DCF41643042BC5D50DF00E98EA10EABF51161282ADAB1DC6A92C2D87C68 + }, + Name: audio0010, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x15580, + Position: 0x0, + Length: 0x1CE0, + SHA256: ED940D860635326F630AF6E035FE882FD6B7D10DF258C28195294F8AFF76A8AD + }, + Name: audio0011, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x17260, + Position: 0x0, + Length: 0x72D0, + SHA256: 63005FA0D2C489C89977C6E0A007BC475984CCF026244F76DFEFE76E42E6ECB0 + }, + Name: audio0012, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x1E530, + Position: 0x0, + Length: 0x4510, + SHA256: 5D9C02270C5E584080987EC31BDB932959B29221837F3BF25282EDCB5F06483C + }, + Name: audio0013, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x22A40, + Position: 0x0, + Length: 0x2B10, + SHA256: 5555E72695CA403FE9F48235B35CF882D6695254DEC16036ADA2F7E8FE3C7089 + }, + Name: audio0014, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x25550, + Position: 0x0, + Length: 0x11F0, + SHA256: CF62E5B0756F02102B326819E914D6CEA0AC6E98CA429CB4AD6405C595C26EFD + }, + Name: audio0015, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x26740, + Position: 0x0, + Length: 0xD80, + SHA256: 430F30379DA3F07CA06004A813FF439A33C5174E08FFCB3C8DC4FB0E65E45325 + }, + Name: audio0016, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x274C0, + Position: 0x0, + Length: 0x5160, + SHA256: 82018B25A5AA4A706187ED25F73AB283F0C7A6F970D4F9DCCAFB7850EDA3EBE1 + }, + Name: audio0017, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x2C620, + Position: 0x0, + Length: 0x3F10, + SHA256: B7FF48AB9F908782DFF2D2B35B336F10513B2480473905D5D08A9CB7341A6DC6 + }, + Name: audio0018, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x30530, + Position: 0x0, + Length: 0x3D80, + SHA256: 8166208D9BD11301CDC871AEEBDCD04D9BC9DE05DF8638F80B1C20078F818EB6 + }, + Name: audio0019, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x342B0, + Position: 0x0, + Length: 0x5470, + SHA256: B60A0B72E79B3CE867E28ECFD34A2C8A3B1E57AA99A31DFE21EC0CA9B12181E4 + }, + Name: audio0020, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x39720, + Position: 0x0, + Length: 0xB20, + SHA256: 937774B6499CA92576778ED4D535381DA2C5372D9439C9CD2395C54C7306FA3E + }, + Name: audio0021, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3A240, + Position: 0x0, + Length: 0x1AF0, + SHA256: F305ACB92D7A37A3F7AADE3993ABDCD3F227ED4CC846620F6F9788002B0A0BA1 + }, + Name: audio0022, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3BD30, + Position: 0x0, + Length: 0x1FA0, + SHA256: 86F50614E018418F172AA8BCC69C53F9EBBF4428CADDED597387793E8B1DA597 + }, + Name: audio0023, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3DCD0, + Position: 0x0, + Length: 0x1A50, + SHA256: C4F2D951513A5EF66FDFAE35CD3628B0344A13EA376EB944DFE389929B113F0E + }, + Name: audio0024, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x3F720, + Position: 0x0, + Length: 0x1C70, + SHA256: 8A796319A263564A995FF3F758EAFEFAAAE5FDD84BC76DC86D2BA347CB2F3156 + }, + Name: audio0025, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x41390, + Position: 0x0, + Length: 0x2410, + SHA256: 91E503071300943B4FDAEA96CA64FFF8D55D988CE4752F76349538DB491BFFCF + }, + Name: audio0026, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x437A0, + Position: 0x0, + Length: 0x5E70, + SHA256: 6D7C11B5030FD1CE2C4A2D46CDD30ED0DD7ECE2000B7D58855329820FB7464C8 + }, + Name: audio0027, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x49610, + Position: 0x0, + Length: 0x8E30, + SHA256: 6D17B8EEBFA9BCDC2155164D6E427A9EC3F3235DB2234459704BA047C07630B0 + }, + Name: audio0028, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x52440, + Position: 0x0, + Length: 0x2400, + SHA256: B4992DDB51777EF77F2C3EE74A63E9B80DCA6E2D96DA292B2521A9460F26886B + }, + Name: audio0029, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x54840, + Position: 0x0, + Length: 0x2330, + SHA256: BD25EFEC7AC70F1609AD4DAAF175AE9AD725956F15ECA087C28D472C6779C023 + }, + Name: audio0030, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x56B70, + Position: 0x0, + Length: 0x6790, + SHA256: 94B11C50DA372BC06F149E22446A389003A5FD43E41826B903C1E3E3CD08933B + }, + Name: audio0031, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x5D300, + Position: 0x0, + Length: 0x9D80, + SHA256: 6A11786E31B4D83551E9D626AC9317E40F8EC53CFAFF9672720DA2DC63FD7C1C + }, + Name: audio0032, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x67080, + Position: 0x0, + Length: 0x3190, + SHA256: 1D61FED222F96EC732DED7EBBEC1B15F725A87865A67B6DE8B91562BB39088A6 + }, + Name: audio0033, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6A210, + Position: 0x0, + Length: 0x34F0, + SHA256: 9BE9B8BE8483F1A54678B64AB3FE9B78D8F65ADB14068926E171D2842C6A8878 + }, + Name: audio0034, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6D700, + Position: 0x0, + Length: 0x1520, + SHA256: A0660E3367768C4BF88662A915EAA7017C595D9A16D1DA87412BC9F0B35392FB + }, + Name: audio0035, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x6EC20, + Position: 0x0, + Length: 0x4020, + SHA256: 9471B3C2A0E2B727BFB39375B268CEEF8B44D547A3511032E89CB558EF01D4A2 + }, + Name: audio0036, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x72C40, + Position: 0x0, + Length: 0x1BF0, + SHA256: 8520F51F72B2CABAD8349AA126B8B7DE044B27794C3669CDEF46D924D975F738 + }, + Name: audio0037, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x74830, + Position: 0x0, + Length: 0x2110, + SHA256: 513589D945A31A7633BBA0A7EFFA62E9C70D020FB73036B5D052F1AB14C78B49 + }, + Name: audio0038, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x76940, + Position: 0x0, + Length: 0xC70, + SHA256: FEDC1BBF92127FF7A9086C6891AE0B4F40D1E33161AB27BFF990830191056281 + }, + Name: audio0039, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x775B0, + Position: 0x0, + Length: 0x19C0, + SHA256: 6E27CA38033D453EC9AC7728FC5C061F9653244B8807F0F939659DADF7252CBC + }, + Name: audio0040, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x78F70, + Position: 0x0, + Length: 0xA70, + SHA256: E8D5C078A3B8748DFB1F051538DBE60D547AD74BA44FE3156BEDD541C636E12B + }, + Name: audio0041, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x799E0, + Position: 0x0, + Length: 0xBB0, + SHA256: DB87D87FB43C00B693CF40FEE7F827EA209DF29486CB97AA0D930E8CCBC2CEC6 + }, + Name: audio0042, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x7A590, + Position: 0x0, + Length: 0xEB0, + SHA256: 7EBE101989EE0710DBDC0EC1D0A3F11BA3306EDF5CB2C06277B1775C984DE1D3 + }, + Name: audio0043, + Children: null, + Tags: null + }, + { + Format: { + Offset: 0x7B440, + Position: 0x0, + Length: 0xD30, + SHA256: 09AEF79DA0CCD719A3F8F499753BB2F0A01D16FACD62479E3F77A369D4105D08 + }, + Name: audio0044, + Children: null, + Tags: null + } +] \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/Snapshots/TIM1_3.vh.verified.txt b/src/Hinox.Tests/Resources/VAB/Snapshots/TIM1_3.vh.verified.txt new file mode 100644 index 0000000..60aa4af --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/Snapshots/TIM1_3.vh.verified.txt @@ -0,0 +1,5041 @@ +{ + Version: 0x7, + VabId: 0x0, + Reserved0: 0xEEEE, + MasterVolume: 0x64, + MasterPan: 0x40, + BankAttribute1: 0x0, + BankAttribute2: 0x0, + Reserved1: 0xFFFFFFFF, + ProgramsAttributes: [ + { + Index: 0, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 24, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 65, + Fine: 107, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 12, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 25, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 65, + Fine: 107, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 0, + WaveformIndex: 12, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 0, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 1, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 26, + Mode: 0, + Volume: 120, + Panning: 96, + Centre: 82, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 1, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 27, + Mode: 0, + Volume: 120, + Panning: 32, + Centre: 83, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 1, + WaveformIndex: 4, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 1, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 2, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 3, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 85, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 0, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 86, + Fine: 67, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 87, + Fine: 67, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 5, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 88, + Fine: 67, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 15, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 15, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 89, + Fine: 67, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 15, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 15, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 90, + Fine: 67, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 16, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 16, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 91, + Fine: 67, + Minimum: 67, + Maximum: 67, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 16, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 3, + WaveformIndex: 16, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 4, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 1, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 1, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 85, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 17, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 17, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 86, + Fine: 67, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 17, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 4, + WaveformIndex: 17, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 4, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 5, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 84, + Fine: 67, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 2, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 2, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 30, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 85, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 18, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 18, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 31, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 86, + Fine: 67, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 3, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 18, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 5, + WaveformIndex: 18, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 5, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 6, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 7, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 8, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 18, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 77, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 6, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 6, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 29, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 73, + Fine: 67, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 2, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 19, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 19, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 16, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 81, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 20, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 8, + WaveformIndex: 20, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 8, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 9, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 17, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 60, + Fine: 0, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 21, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 9, + WaveformIndex: 21, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 9, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 10, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 11, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 12, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 20, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 78, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 3, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 20, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 90, + Fine: 70, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 22, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 22, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 23, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 79, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 20547, + ProgramIndex: 12, + WaveformIndex: 7, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 7, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 23, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 80, + Fine: 70, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 8, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 8, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 18, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 81, + Fine: 0, + Minimum: 64, + Maximum: 64, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 9, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 9, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 19, + Mode: 0, + Volume: 90, + Panning: 64, + Centre: 83, + Fine: 100, + Minimum: 65, + Maximum: 65, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 10, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 10, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 19, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 83, + Fine: 100, + Minimum: 66, + Maximum: 66, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 11, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 11, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 23, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 84, + Fine: 70, + Minimum: 67, + Maximum: 67, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 24, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 12, + WaveformIndex: 24, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 13, + MasterVolume: 127, + Priority: 121, + Mode: 20, + MasterPanning: 64, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: [ + { + IsValid: true, + Priority: 18, + Mode: 0, + Volume: 110, + Panning: 64, + Centre: 77, + Fine: 70, + Minimum: 60, + Maximum: 60, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 13, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 18, + Mode: 0, + Volume: 115, + Panning: 64, + Centre: 78, + Fine: 70, + Minimum: 61, + Maximum: 61, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 14, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 14, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 19, + Mode: 0, + Volume: 100, + Panning: 64, + Centre: 92, + Fine: 70, + Minimum: 62, + Maximum: 62, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 23, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 23, + Reserved2: 54888453694881984 + }, + { + IsValid: true, + Priority: 22, + Mode: 0, + Volume: 127, + Panning: 64, + Centre: 77, + Fine: 67, + Minimum: 63, + Maximum: 63, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 4, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: 25, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24515, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + }, + { + IsValid: false, + Priority: 0, + Mode: 0, + Volume: 0, + Panning: 0, + Centre: 0, + Fine: 0, + Minimum: 0, + Maximum: 0, + VibrationWidth: 0, + VibrationTime: 0, + PortamentoWidth: 0, + PortamentoTime: 0, + PitchBendMinimum: 0, + PitchBendMaximum: 0, + Reserved0: 177, + Reserved1: 178, + EnvelopeSettings1: -32513, + EnvelopeSettings2: 24512, + ProgramIndex: 13, + WaveformIndex: -1, + Reserved2: 54888453694881984 + } + ] + }, + { + Index: 14, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 15, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 16, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 17, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 18, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 19, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 20, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 21, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 22, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 23, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 24, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 25, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 26, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 27, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 28, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 29, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 30, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 31, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 32, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 33, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 34, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 35, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 36, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 37, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 38, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 39, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 40, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 41, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 42, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 43, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 44, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 45, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 46, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 47, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 48, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 49, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 50, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 51, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 52, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 53, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 54, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 55, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 56, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 57, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 58, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 59, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 60, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 61, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 62, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 63, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 64, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 65, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 66, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 67, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 68, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 69, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 70, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 71, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 72, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 73, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 74, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 75, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 76, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 77, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 78, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 79, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 80, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 81, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 82, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 83, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 84, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 85, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 86, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 87, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 88, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 89, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 90, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 91, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 92, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 93, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 94, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 95, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 96, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 97, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 98, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 99, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 100, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 101, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 102, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 103, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 104, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 105, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 106, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 107, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 108, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 109, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 110, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 111, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 112, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 113, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 114, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 115, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 116, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 117, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 118, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 119, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 120, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 121, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 122, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 123, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 124, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 125, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 126, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + }, + { + Index: 127, + MasterVolume: 0, + Priority: 121, + Mode: 20, + MasterPanning: 0, + Reserved0: 0, + Attributes: 0, + Reserved1: -1, + Reserved2: -1, + TonesAttributes: null + } + ], + WaveformSizes: [ + 3904, + 4640, + 3808, + 8064, + 4336, + 10640, + 16064, + 21136, + 15312, + 5360, + 7152, + 7392, + 29984, + 12016, + 5440, + 3440, + 7184, + 4432, + 7008, + 13856, + 6208, + 7152, + 6832, + 912, + 12544, + 7808 + ] +} \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/vab_snapshots.txt b/src/Hinox.Tests/Resources/VAB/vab_snapshots.txt new file mode 100644 index 0000000..448f41b --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vab_snapshots.txt @@ -0,0 +1,5 @@ +# V5 - 0 programs +S001.vab + +# [Digimon Rumble Arena PAL] V7 - Empty tones between valid +DRA_ch08.vab diff --git a/src/Hinox.Tests/Resources/VAB/vab_write.txt b/src/Hinox.Tests/Resources/VAB/vab_write.txt new file mode 100644 index 0000000..6e1804a --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vab_write.txt @@ -0,0 +1,2 @@ +S001.vab +DRA_ch08.vab diff --git a/src/Hinox.Tests/Resources/VAB/vb_snapshots.txt b/src/Hinox.Tests/Resources/VAB/vb_snapshots.txt new file mode 100644 index 0000000..e97efa9 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vb_snapshots.txt @@ -0,0 +1,11 @@ +# [RE2] V7 +RE2_ROOM60C0_snd0.vb,RE2_ROOM60C0_snd0.vh + +# [TimeCrisis1] V7 - Empty programs in between +TC1_002.vb,TC1_001.vh + +# [MartianGothic] V5 +MG_AUDIO1.VB,MG_AUDIO1.VH + +# [MoHo] V6 +MOHO_MOHO9.VB,MOHO_MOHO9.VH diff --git a/src/Hinox.Tests/Resources/VAB/vb_write.txt b/src/Hinox.Tests/Resources/VAB/vb_write.txt new file mode 100644 index 0000000..e97efa9 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vb_write.txt @@ -0,0 +1,11 @@ +# [RE2] V7 +RE2_ROOM60C0_snd0.vb,RE2_ROOM60C0_snd0.vh + +# [TimeCrisis1] V7 - Empty programs in between +TC1_002.vb,TC1_001.vh + +# [MartianGothic] V5 +MG_AUDIO1.VB,MG_AUDIO1.VH + +# [MoHo] V6 +MOHO_MOHO9.VB,MOHO_MOHO9.VH diff --git a/src/Hinox.Tests/Resources/VAB/vh_read.txt b/src/Hinox.Tests/Resources/VAB/vh_read.txt new file mode 100644 index 0000000..ea1233e --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vh_read.txt @@ -0,0 +1,9 @@ +**/*.vh +**/*.vab + +# RE1 +**/*.hed + +# Ignore repeated or failed files +!Snapshots/**/* +!Failed/**/* \ No newline at end of file diff --git a/src/Hinox.Tests/Resources/VAB/vh_snapshots.txt b/src/Hinox.Tests/Resources/VAB/vh_snapshots.txt new file mode 100644 index 0000000..45e6a03 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vh_snapshots.txt @@ -0,0 +1,11 @@ +# [RE2] V7 +RE2_ROOM60C0_snd0.vh + +# [TimeCrisis1] V7 - Empty programs in between +TC1_001.vh + +# [MartianGothic] V5 +MG_AUDIO1.VH + +# [MoHo] V6 +MOHO_MOHO9.VH diff --git a/src/Hinox.Tests/Resources/VAB/vh_snapshots_full.txt b/src/Hinox.Tests/Resources/VAB/vh_snapshots_full.txt new file mode 100644 index 0000000..9b948ce --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vh_snapshots_full.txt @@ -0,0 +1,7 @@ +## Snapshots extracted with all program and tone attributes including padding + +# [TimeCrisis1] Single padding tone with custom attributes +TIM1_3.vh + +# [Digimon Rumble Arena NTSC] Tone pointing to a non-existing waveform +DRA_mv23.vh diff --git a/src/Hinox.Tests/Resources/VAB/vh_write.txt b/src/Hinox.Tests/Resources/VAB/vh_write.txt new file mode 100644 index 0000000..d9b50f3 --- /dev/null +++ b/src/Hinox.Tests/Resources/VAB/vh_write.txt @@ -0,0 +1,8 @@ +**/*.vh + +# RE1 +**/*.hed + +# Ignore repeated or failed files +!Snapshots/**/* +!Failed/**/* diff --git a/src/Hinox.Tests/TestDataBase.cs b/src/Hinox.Tests/TestDataBase.cs new file mode 100644 index 0000000..0946524 --- /dev/null +++ b/src/Hinox.Tests/TestDataBase.cs @@ -0,0 +1,84 @@ +namespace SceneGate.Hinox.Tests; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Extensions.FileSystemGlobbing; +using NUnit.Framework; + +public static class TestDataBase +{ + public static string VabResources => Path.Combine(RootFromOutputPath, "VAB"); + + public static string RootFromOutputPath { + get { + string envVar = Environment.GetEnvironmentVariable("SCENEGATE_TEST_DIR"); + if (!string.IsNullOrEmpty(envVar)) { + return envVar; + } + + string programDir = AppDomain.CurrentDomain.BaseDirectory; + string path = Path.Combine( + programDir, + "..", // framework + "..", // configuration + "..", // bin + "Resources"); + return Path.GetFullPath(path); + } + } + + public static void IgnoreIfFileDoesNotExist(string file) + { + if (!File.Exists(file)) { + string msg = $"[{TestContext.CurrentContext.Test.ClassName}] Missing resource file: {file}"; + TestContext.Progress.WriteLine(msg); + Assert.Ignore(msg); + } + } + + public static IEnumerable ReadListFile(string testDir, string fileName) + { + string filePath = Path.Combine(testDir, fileName); + if (!File.Exists(filePath)) { + return []; + } + + return File.ReadAllLines(filePath) + .Select(line => line.Trim()) + .Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith('#')); + } + + public static IEnumerable ReadTestCaseDataListFile(string testDir, string fileName) + { + return ReadListFile(testDir, fileName) + .Select(data => data.Split(',')) + .Select(data => new TestCaseData(data)); + } + + public static IEnumerable ReadGlobFile(string testDir, string fileName) + { + string filePath = Path.Combine(testDir, fileName); + if (!File.Exists(filePath)) { + return []; + } + + IEnumerable patterns = ReadListFile(testDir, fileName); + IEnumerable includePatterns = patterns.Where(l => l[0] != '!'); + IEnumerable excludePatterns = patterns.Where(l => l[0] == '!').Select(l => l[1..]); + + var matcher = new Matcher(StringComparison.OrdinalIgnoreCase); + matcher.AddIncludePatterns(includePatterns); + matcher.AddExcludePatterns(excludePatterns); + + return matcher.GetResultsInFullPath(testDir); + } + + public static IEnumerable ReadTestCaseDataGlobFile(string testDir, string fileName) + { + return ReadGlobFile(testDir, fileName) + .Select(p => new TestCaseData(p) + .SetArgDisplayNames(Path.GetRelativePath(RootFromOutputPath, p))); + } +} diff --git a/src/Hinox.Tests/VerifyConventionsCheck.cs b/src/Hinox.Tests/VerifyConventionsCheck.cs new file mode 100644 index 0000000..8cbe585 --- /dev/null +++ b/src/Hinox.Tests/VerifyConventionsCheck.cs @@ -0,0 +1,12 @@ +namespace SceneGate.Hinox.Tests; + +using System.Threading.Tasks; +using NUnit.Framework; +using VerifyNUnit; + +[TestFixture] +public class VerifyConventionsCheck +{ + [Test] + public Task Run() => VerifyChecks.Run(); +} diff --git a/src/Hinox.Utils/AppLoggerFactory.cs b/src/Hinox.Utils/AppLoggerFactory.cs new file mode 100644 index 0000000..a06b587 --- /dev/null +++ b/src/Hinox.Utils/AppLoggerFactory.cs @@ -0,0 +1,61 @@ +namespace SceneGate.Hinox.Utils; + +using Microsoft.Extensions.Logging; +using NLog; +using NLog.Config; +using NLog.Extensions.Logging; +using NLog.Targets; + +internal static class AppLoggerFactory +{ + private static Microsoft.Extensions.Logging.LogLevel minimumLevel = Microsoft.Extensions.Logging.LogLevel.Warning; + + private static readonly Lazy factory = new(CreateFactory); + + public static Microsoft.Extensions.Logging.LogLevel MinimumLevel { + get => minimumLevel; + set { + if (factory.IsValueCreated) { + throw new InvalidOperationException("Cannot change verbosity after factory initialization"); + } + + minimumLevel = value; + } + } + + public static ILogger CreateLogger() + { + return factory.Value.CreateLogger(); + } + + private static ILoggerFactory CreateFactory() + { + LogManager.ThrowConfigExceptions = true; + var nlogConfig = CreateNLogConfiguration(); + var nlogProviderConfig = CreateNLogProviderConfiguration(); + + return LoggerFactory.Create(builder => + builder.AddNLog(nlogConfig, nlogProviderConfig) + .SetMinimumLevel(MinimumLevel)); + } + + private static LoggingConfiguration CreateNLogConfiguration() + { + var config = new LoggingConfiguration(); + + var coloredConsole = new ColoredConsoleTarget { + Layout = "${level:uppercase=true}: ${logger:shortName=true} => ${message:withException=true}", + AutoFlush = true, + }; + config.AddRuleForAllLevels(coloredConsole); + + return config; + } + + private static NLogProviderOptions CreateNLogProviderConfiguration() + { + return new NLogProviderOptions() { + RemoveLoggerFactoryFilter = false, + }; + } +} diff --git a/src/Hinox.Utils/Audio/ExportSingleVabCommand.cs b/src/Hinox.Utils/Audio/ExportSingleVabCommand.cs new file mode 100644 index 0000000..6c813d2 --- /dev/null +++ b/src/Hinox.Utils/Audio/ExportSingleVabCommand.cs @@ -0,0 +1,207 @@ +namespace SceneGate.Hinox.Utils.Audio; + +using System.ComponentModel; +using System.Text; +using Data.HashFunction; +using Data.HashFunction.CRC; +using Microsoft.Extensions.Logging; +using SceneGate.Hinox.Audio; +using Spectre.Console; +using Spectre.Console.Cli; +using YamlDotNet.Serialization; +using Yarhl.FileSystem; +using Yarhl.IO; + +[Description("Extract the audios from a VAB or VH/VB format")] +internal class ExportSingleVabCommand : Command +{ + private ILogger logger = null!; + + public sealed class Settings : CommandSettings + { + [CommandOption("--vab")] + [Description("Path to the VAB file. Ignore if VH and VB paths are provided.")] + public string? VabPath { get; set; } + + [CommandOption("--vh")] + [Description("Path to the VH file (VAB header). Ignore if VAB path is provided.")] + public string? HeaderPath { get; set; } + + [CommandOption("--vb")] + [Description("Path to the VB file (VAB body). Ignore if VAB path is provided.")] + public string? BodyPath { get; set; } + + [CommandOption("--files")] + [Description("Optional path to a previously exported files.yml for having custom names when exporting")] + public string? NamesPath { get; set; } + + [CommandOption("-o|--output")] + [Description("Path to the directory to write the output files.")] + public required string OutputPath { get; set; } + + [CommandOption("--support-non-compliant")] + [Description("Support non-compliant formats")] + [DefaultValue(false)] + public bool SupportNonCompliant { get; set; } + + [CommandOption("-v|--verbosity")] + [Description("Logging output verbosity")] + [DefaultValue(LogLevel.Warning)] + public LogLevel Verbosity { get; set; } + + public override ValidationResult Validate() + { + if (string.IsNullOrEmpty(OutputPath)) { + return ValidationResult.Error("Output path is mandatory"); + } + + if (!string.IsNullOrEmpty(VabPath) && !string.IsNullOrEmpty(HeaderPath)) { + return ValidationResult.Error("Specify either a VAB path or VH/VB paths, no both"); + } + + if (!string.IsNullOrEmpty(VabPath) && !File.Exists(VabPath)) { + return ValidationResult.Error($"The input VAB file '{VabPath}' does NOT exists"); + } + + if (!string.IsNullOrEmpty(HeaderPath) && string.IsNullOrEmpty(BodyPath)) { + return ValidationResult.Error($"A VB file is mandatory when providing a VH file"); + } + + if (!string.IsNullOrEmpty(HeaderPath) && !File.Exists(HeaderPath)) { + return ValidationResult.Error($"The input VH file '{HeaderPath}' does NOT exists"); + } + + if (!string.IsNullOrEmpty(BodyPath) && string.IsNullOrEmpty(HeaderPath)) { + return ValidationResult.Error($"A VH file is mandatory when providing a VB file"); + } + + if (!string.IsNullOrEmpty(BodyPath) && !File.Exists(BodyPath)) { + return ValidationResult.Error($"The input VB file '{BodyPath}' does NOT exists"); + } + + if (!string.IsNullOrEmpty(NamesPath) && !File.Exists(NamesPath)) { + return ValidationResult.Error($"The input names file '{NamesPath}' does NOT exists"); + } + + return base.Validate(); + } + } + + public override int Execute(CommandContext context, Settings settings) + { + AppLoggerFactory.MinimumLevel = settings.Verbosity; + logger = AppLoggerFactory.CreateLogger(); + + if (context.Remaining.Parsed.Any() || context.Remaining.Raw.Any()) { + logger.LogCritical( + "Unrecognized options: {Parsed}, {Raw}", + context.Remaining.Parsed.Select(x => x.Key), + context.Remaining.Raw); + return 2; + } + + using Node container = ReadContainer(settings); + logger.LogDebug("Found {Count} audios", container.Children.Count - 1); + + logger.LogInformation("Exporting content into folder: '{Path}'", Path.GetFullPath(settings.OutputPath)); + ExportHeader(container, settings.OutputPath); + ExportAudios(container, settings.OutputPath, settings.NamesPath); + return 0; + } + + private static void ExportHeader(Node container, string outputPath) + { + VabHeader header = container.Children["header"]!.GetFormatAs()!; + string yaml = new SerializerBuilder() + .WithAttributeOverride(x => x.WaveformSizes, new YamlIgnoreAttribute()) + .Build() + .Serialize(header); + + Directory.CreateDirectory(outputPath); + string fileOutputPath = Path.Combine(outputPath, "vab.yml"); + File.WriteAllText(fileOutputPath, yaml, Encoding.UTF8); + } + + private void ExportAudios(Node container, string outputPath, string? namesPath) + { + ContainerInfo? inputNames = null; + if (!string.IsNullOrEmpty(namesPath)) { + logger.LogInformation("Reading provided file names from: '{Path}'", Path.GetFullPath(namesPath)); + inputNames = ContainerInfo.FromYaml(namesPath); + } + + var audios = container.Children.Where(n => n.Name != "header").ToArray(); + if (inputNames is not null && inputNames.Files.Count != audios.Length) { + logger.LogError( + "Number of names {Actual} does NOT match audio count {Expected}", + inputNames.Files.Count, + audios.Length); + return; + } + + for (int i = 0; i < audios.Length; i++) { + string audioName = inputNames != null ? inputNames.Files[i].Path : GetAudioName(i, audios[i]); + if (audios.Any(n => n.Name == audioName)) { + logger.LogInformation("Skipping audio with duplicated name #{Index} ({Name})", i, audioName); + continue; + } + + audios[i].Name = audioName; + + string audioOutputPath = Path.Combine(outputPath, audioName); + audios[i].Stream!.WriteTo(audioOutputPath); + } + + if (inputNames is null) { + string fileOutputPath = Path.Combine(outputPath, "files.yml"); + ContainerInfo.Create(audios).WriteAsYaml(fileOutputPath); + } + } + + private static string GetAudioName(int index, Node audio) + { + audio.Stream!.Position = 0; + + ICRC crc = CRCFactory.Instance.Create(CRCConfig.CRC32); + IHashValue hash = crc.ComputeHash(audio.Stream); + return $"{index:D4}_{hash.AsHexString().ToUpperInvariant()}.vag"; + } + + private Node ReadContainer(Settings settings) + { + return string.IsNullOrEmpty(settings.VabPath) + ? ReadHeaderBodyFiles(settings.HeaderPath!, settings.BodyPath!, settings.SupportNonCompliant) + : ReadVabFile(settings.VabPath, settings.SupportNonCompliant); + } + + private Node ReadVabFile(string vabPath, bool supportNonCompliant) + { + logger.LogInformation("Reading VAB '{Path}'", Path.GetFullPath(vabPath)); + var converter = supportNonCompliant + ? new BinaryVab2Container(includePaddingTones: true, throwOnInvalid: false) + : new BinaryVab2Container(includePaddingTones: false, throwOnInvalid: true); + + return NodeFactory.FromFile(vabPath, FileOpenMode.Read) + .TransformWith(converter); + } + + private Node ReadHeaderBodyFiles(string headerPath, string bodyPath, bool supportNonCompliant) + { + logger.LogInformation("Reading VH '{Path}'", Path.GetFullPath(headerPath)); + var converter = supportNonCompliant + ? new Binary2VabHeader(includePaddingTones: true, throwOnInvalid: false) + : new Binary2VabHeader(includePaddingTones: false, throwOnInvalid: true); + + Node headerNode = NodeFactory.FromFile(headerPath, "header", FileOpenMode.Read) + .TransformWith(converter); + VabHeader header = headerNode.GetFormatAs()!; + + logger.LogInformation("Reading VB '{Path}'", Path.GetFullPath(bodyPath)); + Node container = NodeFactory.FromFile(bodyPath, FileOpenMode.Read) + .TransformWith(new BinaryVabBody2Container(header)); + + container.Add(headerNode); + + return container; + } +} diff --git a/src/Hinox.Utils/Audio/ImportSingleVabCommand.cs b/src/Hinox.Utils/Audio/ImportSingleVabCommand.cs new file mode 100644 index 0000000..4e9bfda --- /dev/null +++ b/src/Hinox.Utils/Audio/ImportSingleVabCommand.cs @@ -0,0 +1,258 @@ +namespace SceneGate.Hinox.Utils.Audio; + +using System; +using System.ComponentModel; +using System.Linq; +using System.Text; +using Microsoft.Extensions.Logging; +using SceneGate.Hinox.Audio; +using Spectre.Console; +using Spectre.Console.Cli; +using YamlDotNet.Serialization; +using Yarhl.FileSystem; +using Yarhl.IO; + +[Description("Import audio files into VAB or VH/VB format")] +internal class ImportSingleVabCommand : Command +{ + private ILogger logger = null!; + + public sealed class Settings : CommandSettings + { + [CommandOption("-f|--files")] + [Description("Path to the files.yml with the audio paths to import")] + public required string ContainerInfoPath { get; set; } + + [CommandOption("--header")] + [Description("Path to the vab.yml with the VAB header information")] + public required string VabHeader { get; set; } + + [CommandOption("--out-vab")] + [Description("Export content as VAB format into the provided path")] + public string? OutputVabPath { get; set; } + + [CommandOption("--out-vh")] + [Description("Export the header as VH format into the provided path")] + public string? OutputHeaderPath { get; set; } + + [CommandOption("--out-vb")] + [Description("Export the body container as VB format into the provided path")] + public string? OutputBodyPath { get; set; } + + [CommandOption("--autodetect-vag")] + [Description("If set, it tries to autodetect VAG headers in audio files")] + [DefaultValue(false)] + public bool AutoDetectVag { get; set; } + + [CommandOption("-v|--verbosity")] + [Description("Logging output verbosity")] + [DefaultValue(LogLevel.Warning)] + public LogLevel Verbosity { get; set; } + + public override ValidationResult Validate() + { + if (!File.Exists(ContainerInfoPath)) { + return ValidationResult.Error("Container info path is mandatory and must exists"); + } + + if (!File.Exists(VabHeader)) { + return ValidationResult.Error("VAB header path is mandatory and must exists"); + } + + if (!string.IsNullOrEmpty(OutputVabPath) && !string.IsNullOrEmpty(OutputHeaderPath)) { + return ValidationResult.Error("Specify either a VAB or VH/VB outputs, no both"); + } + + if (!string.IsNullOrEmpty(OutputHeaderPath) && string.IsNullOrEmpty(OutputBodyPath)) { + return ValidationResult.Error($"A VB output is mandatory when providing a VH output"); + } + + if (!string.IsNullOrEmpty(OutputBodyPath) && string.IsNullOrEmpty(OutputHeaderPath)) { + return ValidationResult.Error($"A VH output is mandatory when providing a VB output"); + } + + return base.Validate(); + } + } + + public override int Execute(CommandContext context, Settings settings) + { + AppLoggerFactory.MinimumLevel = settings.Verbosity; + logger = AppLoggerFactory.CreateLogger(); + + if (context.Remaining.Parsed.Any() || context.Remaining.Raw.Any()) { + logger.LogCritical( + "Unrecognized options: {Parsed}, {Raw}", + context.Remaining.Parsed.Select(x => x.Key), + context.Remaining.Raw); + return 2; + } + + using Node? container = ReadContainer(settings.ContainerInfoPath, settings.VabHeader, settings.AutoDetectVag); + if (container is null) { + return 1; + } + + if (!string.IsNullOrEmpty(settings.OutputVabPath)) { + ExportVab(container, settings.AutoDetectVag, settings.OutputVabPath); + } else { + ExportVhVb(container, settings.AutoDetectVag, settings.OutputHeaderPath!, settings.OutputBodyPath!); + } + + return 0; + } + + private void ExportVab(Node container, bool autodetect, string outputPath) + { + logger.LogInformation("Exporting as VAB format into '{Path}'", Path.GetFullPath(outputPath)); + container.TransformWith(new Container2BinaryVab(autodetect)) + .Stream!.WriteTo(outputPath); + } + + private void ExportVhVb(Node container, bool autodetect, string outVhPath, string outVbPath) + { + VabHeader header = container.Children["header"]!.GetFormatAs()!; + + var audios = new NodeContainerFormat(); + audios.Root.Add(container.Children.Where(n => n.Name != "header")); + + Container2BinaryVab.UpdateFileSizes(header, audios,autodetect); + + logger.LogInformation("Exporting header in VH format into '{Path}'", Path.GetFullPath(outVhPath)); + using BinaryFormat binaryHeader = new VabHeader2Binary().Convert(header); + binaryHeader.Stream!.WriteTo(outVhPath); + + logger.LogInformation("Exporting body in VB format into '{Path}'", Path.GetFullPath(outVbPath)); + using BinaryFormat binaryBody = new Container2BinaryVabBody(autodetect).Convert(audios); + binaryBody.Stream.WriteTo(outVbPath); + } + + private Node? ReadContainer(string infoPath, string headerPath, bool autodetect) + { + var container = NodeFactory.CreateContainer("vab"); + if (!AddHeader(headerPath, container)) { + return null; + } + + if (!AddAudios(infoPath, autodetect, container)) { + return null; + } + + return container; + } + + private bool AddHeader(string headerPath, Node container) + { + logger.LogInformation("Reading header from YML '{Path}'", Path.GetFullPath(headerPath)); + try { + string yaml = File.ReadAllText(headerPath, Encoding.UTF8); + VabHeader header = new DeserializerBuilder() + .Build() + .Deserialize(yaml); + + var headerNode = new Node("header", header); + container.Add(headerNode); + return true; + } catch (Exception ex) { + logger.LogError(ex, "Failed to read header YAML file"); + return false; + } + } + + private bool AddAudios(string infoPath, bool autodetect, Node container) + { + logger.LogInformation("Reading file info from YML '{Path}'", Path.GetFullPath(infoPath)); + string basePath = Path.GetDirectoryName(Path.GetFullPath(infoPath))!; + + ContainerInfo containerInfo; + try { + containerInfo = ContainerInfo.FromYaml(infoPath); + } catch (Exception ex) { + logger.LogError(ex, "Failed to read info YAML file"); + return false; + } + + if (containerInfo.Files.Count > VabHeader.MaximumWaveforms) { + logger.LogError( + "Maximum audio files is {Max} but info file contains {Actual}", + VabHeader.MaximumWaveforms, + containerInfo.Files.Count); + return false; + } + + logger.LogDebug("Found {Count} files", containerInfo.Files.Count); + + long totalLength = 0; + for (int i = 0; i < containerInfo.Files.Count; i++) { + Node audioNode = OpenAudio(i, containerInfo.Files[i], basePath, autodetect); + container.Add(audioNode); + + totalLength += audioNode.Stream!.Length; + } + + if (totalLength > VabHeader.MaximumTotalWaveformsSize) { + logger.LogError( + "Total audio length {Actual} is larger than supported by the format {Max}", + totalLength, + VabHeader.MaximumTotalWaveformsSize); + return false; + } + + LogLargerAudios(totalLength, container, containerInfo); + return true; + } + + private Node OpenAudio(int idx, ExportedFileInfo audioInfo, string basePath, bool autodetect) + { + string audioPath = Path.GetFullPath(audioInfo.Path, basePath); + if (!File.Exists(audioPath)) { + logger.LogError("Cannot find audio: '{Path}'", audioPath); + throw new FileNotFoundException("Audio file not found", audioPath); + } + + long audioOffset = audioInfo.Offset; + if (audioOffset == 0 && autodetect) { + using var tempVagStream = DataStreamFactory.FromFile(audioPath, FileOpenMode.Read); + long audioLength = VagFormatAnalyzer.GetChannelsLength(tempVagStream); + + audioOffset = tempVagStream.Length - audioLength; + if (audioOffset > 0) { + logger.LogDebug("'{Name}' detected as VAG with header", audioInfo.Path); + } + } + + using var fullData = DataStreamFactory.FromFile(audioPath, FileOpenMode.Read); // temp stream for slicing + var actualData = new BinaryFormat(fullData.Slice(audioOffset)); + + // Rename to ensure duplicated files are added as copies instead of replaced + var audioNode = new Node($"audio_{idx}", actualData); + return audioNode; + } + + private void LogLargerAudios(long totalVbLength, Node container, ContainerInfo containerInfo) + { + bool isVbLarger = containerInfo.OriginalLength > -1 + && totalVbLength > containerInfo.OriginalLength; + if (isVbLarger) { + logger.LogWarning( + "Total audio length {Actual} is larger than original size {Original}", + totalVbLength, + containerInfo.OriginalLength); + } + + for (int i = 0; i < containerInfo.Files.Count; i++) { + ExportedFileInfo audioInfo = containerInfo.Files[i]; + Node audioNode = container.Children[$"audio_{i}"]!; + + if (audioInfo.OriginalLength > -1 && audioNode.Stream!.Length > audioInfo.OriginalLength) { + LogLevel severity = isVbLarger ? LogLevel.Warning : LogLevel.Information; + logger.Log( + severity, + "Audio '{Path}' with file size {Actual} larger than original size {Original}", + audioInfo.Path, + audioNode.Stream!.Length, + audioInfo.OriginalLength); + } + } + } +} diff --git a/src/Hinox.Utils/Audio/TestVabCommand.cs b/src/Hinox.Utils/Audio/TestVabCommand.cs new file mode 100644 index 0000000..e4e2a76 --- /dev/null +++ b/src/Hinox.Utils/Audio/TestVabCommand.cs @@ -0,0 +1,267 @@ +namespace SceneGate.Hinox.Utils.Audio; + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using Microsoft.Extensions.Logging; +using SceneGate.Hinox.Audio; +using Spectre.Console; +using Spectre.Console.Cli; +using Spectre.Console.Rendering; +using Yarhl.FileSystem; +using Yarhl.IO; + +[Description("Test reading and writing VAB files")] +internal sealed class TestVabCommand : Command +{ + private ILogger logger = null!; + + public sealed class Settings : CommandSettings + { + [CommandArgument(0, "[PATH]")] + [Description("Path to the directory containing VAB or VH/VB files")] + public required string InputPath { get; set; } + + [CommandOption("-r|--recursive")] + [Description("Indicates whether to search in subdirectories recursively")] + public bool RecursiveSearch { get; set; } + } + + public override int Execute(CommandContext context, Settings settings) + { + logger = AppLoggerFactory.CreateLogger(); + + if (context.Remaining.Parsed.Any() || context.Remaining.Raw.Any()) { + logger.LogCritical( + "Unrecognized options: {Parsed}, {Raw}", + context.Remaining.Parsed.Select(x => x.Key), + context.Remaining.Raw); + return 2; + } + + var vabResults = VabSearchAndTest(settings); + var vhvbResults = VhVbSearchAndTest(settings); + + var combinedResults = vabResults.Concat(vhvbResults); + PrintResult(combinedResults); + + return 0; + } + + private static ReadOnlyCollection VabSearchAndTest(Settings settings) + { + List results = []; + + var searchOptions = settings.RecursiveSearch ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + var matchingFiles = Directory.EnumerateFiles(settings.InputPath, "*.vab", searchOptions).ToArray(); + + AnsiConsole.Progress().Start(x => { + var task = x.AddTask("Analyzing VAB files", maxValue: matchingFiles.Length); + + for (int i = 0; i < matchingFiles.Length; i++) { + var result = TestVab(matchingFiles[i]); + results.Add(result); + task.Increment(1); + } + }); + + return results.AsReadOnly(); + } + + private ReadOnlyCollection VhVbSearchAndTest(Settings settings) + { + List results = []; + + var searchOptions = settings.RecursiveSearch ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; + var matchingFiles = Directory.EnumerateFiles(settings.InputPath, "*.vh", searchOptions).ToArray(); + + AnsiConsole.Progress().Start(x => { + var task = x.AddTask("Analyzing VH/VB files", maxValue: matchingFiles.Length); + + foreach (string vhPath in matchingFiles) { + string vbPath = Path.ChangeExtension(vhPath, ".vb"); + if (!File.Exists(vbPath)) { + logger.LogDebug("VH file without matching VB {Path}", vhPath); + task.Increment(1); + continue; + } + + var result = TestVhVb(vhPath, vbPath); + results.AddRange(result); + task.Increment(1); + } + }); + + return results.AsReadOnly(); + } + + private static FormatTestResult TestVab(string inputVab) + { + using var binaryVab = new BinaryFormat(inputVab, FileOpenMode.Read); + + NodeContainerFormat container; + try { + container = new BinaryVab2Container(includePaddingTones: true, throwOnInvalid: false) + .Convert(binaryVab); + } catch (Exception ex) { + return new FormatTestResult(inputVab, "VAB", false, null, null, ex.Message); + } + + BinaryFormat generatedVab; + try { + generatedVab = new Container2BinaryVab(autodetectVag: false).Convert(container); + } catch (Exception ex) { + container.Dispose(); + return new FormatTestResult(inputVab, "VAB", true, false, null, ex.Message); + } + + bool isIdentical = generatedVab.Stream.Compare(binaryVab.Stream); + generatedVab.Dispose(); + + return new FormatTestResult(inputVab, "VAB", true, true, isIdentical, null); + } + + private static IEnumerable TestVhVb(string inputVh, string inputVb) + { + using var binaryVh = new BinaryFormat(inputVh, FileOpenMode.Read); + using var binaryVb = new BinaryFormat(inputVb, FileOpenMode.Read); + + VabHeader header; + try { + header = new Binary2VabHeader(includePaddingTones: true, throwOnInvalid: false) + .Convert(binaryVh); + } catch (Exception ex) { + return [new FormatTestResult(inputVh, "VH", false, null, null, ex.Message)]; + } + + NodeContainerFormat container; + try { + container = new BinaryVabBody2Container(header).Convert(binaryVb); + } catch (Exception ex) { + return [new FormatTestResult(inputVb, "VB", false, null, null, ex.Message)]; + } + + BinaryFormat generatedVh; + try { + generatedVh = new VabHeader2Binary().Convert(header); + } catch (Exception ex) { + container.Dispose(); + return [new FormatTestResult(inputVh, "VH", true, false, null, ex.Message)]; + } + + BinaryFormat generatedVb; + try { + generatedVb = new Container2BinaryVabBody(autodetectVag: false).Convert(container); + } catch (Exception ex) { + generatedVh.Dispose(); + container.Dispose(); + return [new FormatTestResult(inputVb, "VB", true, false, null, ex.Message)]; + } + + bool isVhIdentical = generatedVh.Stream.Compare(binaryVh.Stream); + generatedVh.Dispose(); + + bool isVbIdentical = generatedVb.Stream.Compare(binaryVb.Stream); + generatedVb.Dispose(); + + return [ + new FormatTestResult(inputVh, "VH", true, true, isVhIdentical, null), + new FormatTestResult(inputVb, "VB", true, true, isVbIdentical, null), + ]; + } + + private static void PrintResult(IEnumerable results) + { + static IRenderable RenderIsSucceed(bool? x) => + x switch { + null => new Text(string.Empty), + true => new Text("Success"), + false => new Markup("[red]Failure[/]"), + }; + + AnsiConsole.Write(new Rule("Results")); + + var table = new Table(); + table.AddColumns("Path", "Format", "Read", "Write", "Identical", "Error"); + + var readResults = new TestTotalResult(); + var writeResults = new TestTotalResult(); + var identicalResults = new TestTotalResult(); + foreach (var result in results) { + readResults.AddResult(result.ReadSucceed); + writeResults.AddResult(result.WriteSucceed); + identicalResults.AddResult(result.Identical); + + table.AddRow( + new TextPath(result.Path), + new Text(result.Format), + RenderIsSucceed(result.ReadSucceed), + RenderIsSucceed(result.WriteSucceed), + RenderIsSucceed(result.Identical), + new Text(result.ErrorMessage ?? string.Empty)); + } + + AnsiConsole.Write(table); + + var totalTable = new Table(); + totalTable.AddColumns("Operation", "Total", "Successful", "Failed", "Indeterminate"); + totalTable.AddRow( + "Read", + readResults.Total.ToString(), + readResults.GetSuccessfulRate(), + readResults.GetFailedRate(), + readResults.Indeterminate.ToString()); + totalTable.AddRow( + "Write", + writeResults.Total.ToString(), + writeResults.GetSuccessfulRate(), + writeResults.GetFailedRate(), + writeResults.Indeterminate.ToString()); + totalTable.AddRow( + "Identical", + identicalResults.Total.ToString(), + identicalResults.GetSuccessfulRate(), + identicalResults.GetFailedRate(), + identicalResults.Indeterminate.ToString()); + AnsiConsole.Write(totalTable); + } + + private sealed record FormatTestResult( + string Path, + string Format, + bool ReadSucceed, + bool? WriteSucceed, + bool? Identical, + string? ErrorMessage); + + private sealed class TestTotalResult + { + public int Total { get; private set; } + + public int Successful { get; private set; } + + public int Failed { get; private set; } + + public int Indeterminate { get; private set; } + + public string GetSuccessfulRate() => $"{Successful} ({Successful / (Total - Indeterminate):P1})"; + + public string GetFailedRate() => $"{Failed} ({Failed / (Total - Indeterminate):P1})"; + + public void AddResult(bool? result) + { + Total++; + if (result.HasValue) { + if (result.Value) { + Successful++; + } else { + Failed++; + } + } else { + Indeterminate++; + } + } + } +} diff --git a/src/Hinox.Utils/ContainerInfo.cs b/src/Hinox.Utils/ContainerInfo.cs new file mode 100644 index 0000000..02345e8 --- /dev/null +++ b/src/Hinox.Utils/ContainerInfo.cs @@ -0,0 +1,45 @@ +namespace SceneGate.Hinox.Utils; + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using YamlDotNet.Serialization; +using Yarhl.FileSystem; + +internal record ContainerInfo +{ + public long OriginalLength { get; init; } = -1; + + public Collection Files { get; init; } = []; + + public static ContainerInfo Create(IEnumerable nodes) + { + var infos = nodes + .Where(n => n.Stream is not null) + .Select(n => new ExportedFileInfo(n.Name, 0, n.Stream!.Length)) + .ToList(); + return new ContainerInfo { + OriginalLength = infos.Sum(x => x.OriginalLength), + Files = new Collection(infos), + }; + } + + public static ContainerInfo FromYaml(string inputPath) + { + string yaml = File.ReadAllText(inputPath, Encoding.UTF8); + return new DeserializerBuilder() + .Build() + .Deserialize(yaml); + } + + public void WriteAsYaml(string outputPath) + { + string yaml = new SerializerBuilder() + .WithAttributeOverride(x => x.Offset, new YamlIgnoreAttribute()) + .Build() + .Serialize(this); + + File.WriteAllText(outputPath, yaml, Encoding.UTF8); + } +} diff --git a/src/Hinox.Utils/ExportedFileInfo.cs b/src/Hinox.Utils/ExportedFileInfo.cs new file mode 100644 index 0000000..2ff99e6 --- /dev/null +++ b/src/Hinox.Utils/ExportedFileInfo.cs @@ -0,0 +1,9 @@ +namespace SceneGate.Hinox.Utils; + +internal record ExportedFileInfo(string Path, long Offset, long OriginalLength) +{ + public ExportedFileInfo() + : this(string.Empty, 0, -1) + { + } +} diff --git a/src/Hinox.Utils/Hinox.Utils.csproj b/src/Hinox.Utils/Hinox.Utils.csproj index 8643961..5df6544 100644 --- a/src/Hinox.Utils/Hinox.Utils.csproj +++ b/src/Hinox.Utils/Hinox.Utils.csproj @@ -1,7 +1,8 @@ - + HinoxUtils + Common utilities for PSX (PS1) console file formats supported by Hinox. Exe true @@ -23,6 +24,16 @@ + + + + + + + + + + diff --git a/src/Hinox.Utils/Program.cs b/src/Hinox.Utils/Program.cs index 53519fb..3fb1dcb 100644 --- a/src/Hinox.Utils/Program.cs +++ b/src/Hinox.Utils/Program.cs @@ -1,2 +1,30 @@ -string consoleVersion = typeof(Program).Assembly.GetName()?.Version?.ToString() ?? "0.0.1"; -Console.WriteLine($"Console version: {consoleVersion}"); +using NLog; +using SceneGate.Hinox.Utils.Audio; +using Spectre.Console; +using Spectre.Console.Cli; + +var app = new CommandApp(); +app.Configure(static configurator => { + configurator.AddBranch("audio", static audio => { + audio.SetDescription("Audio file formats"); + + audio.AddBranch("vab", static vab => { + vab.SetDescription("VAB and VH/VB audio format"); + vab.AddCommand("export"); + vab.AddCommand("import"); + vab.AddCommand("test"); + }); + }); +}); + +int result = await app.RunAsync(args); +LogManager.Shutdown(); + +AnsiConsole.WriteLine(); +if (result == 0) { + AnsiConsole.MarkupLineInterpolated($"[bold green]Success![/]"); +} else { + AnsiConsole.MarkupLineInterpolated($"[bold red]Failure...[/] Error code: {result}"); +} + +return result; diff --git a/src/Hinox.sln b/src/Hinox.sln index 78b538c..d948a21 100644 --- a/src/Hinox.sln +++ b/src/Hinox.sln @@ -1,14 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35707.178 MinimumVisualStudioVersion = 15.0.26124.0 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hinox", "Hinox\Hinox.csproj", "{07E6EBB9-380D-4813-AFCD-E5856501929A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hinox.Utils", "Hinox.Utils/Hinox.Utils.csproj", "{CB7B12D4-90B6-4564-8ECC-B6954E61A11F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hinox.Utils", "Hinox.Utils\Hinox.Utils.csproj", "{CB7B12D4-90B6-4564-8ECC-B6954E61A11F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hinox.Tests", "Hinox.Tests\Hinox.Tests.csproj", "{276997DA-06FC-4C8A-AA82-92C3373C69A3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{75ACF78F-608B-404E-BFF5-06CAB0B08A03}" + ProjectSection(SolutionItems) = preProject + ..\.editorconfig = ..\.editorconfig + ..\.gitattributes = ..\.gitattributes + ..\.gitignore = ..\.gitignore + ..\.github\workflows\build.yml = ..\.github\workflows\build.yml + Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props + ..\README.md = ..\README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -18,9 +29,6 @@ Global Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {07E6EBB9-380D-4813-AFCD-E5856501929A}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -59,4 +67,10 @@ Global {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|x86.ActiveCfg = Release|Any CPU {276997DA-06FC-4C8A-AA82-92C3373C69A3}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7BFDC55B-ED8A-4208-8657-00EA19C88F13} + EndGlobalSection EndGlobal diff --git a/src/Hinox/Audio/Binary2VabHeader.cs b/src/Hinox/Audio/Binary2VabHeader.cs new file mode 100644 index 0000000..8159edb --- /dev/null +++ b/src/Hinox/Audio/Binary2VabHeader.cs @@ -0,0 +1,260 @@ +namespace SceneGate.Hinox.Audio; + +using System; +using System.Linq; +using Yarhl.FileFormat; +using Yarhl.IO; + +/// +/// Converter for reading VAB header (VH) from its standard binary format. +/// +public class Binary2VabHeader : IConverter +{ + private static readonly int[] supportedVersions = [5, 6, 7]; + + /// + /// Initializes a new instance of the class. + /// + public Binary2VabHeader() + { + IncludePaddingEntries = false; + ThrowOnInvalidData = true; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// Value that indicates whether to include empty programs and tones. + /// + /// + /// Value indicating whether to throw exceptions on unexpected data. + /// + public Binary2VabHeader(bool includePaddingTones, bool throwOnInvalid) + { + IncludePaddingEntries = includePaddingTones; + ThrowOnInvalidData = throwOnInvalid; + } + + /// + /// Gets or sets a value indicating whether to include empty programs and + /// tones without a valid waveform links. + /// + /// + /// Setting to true allows to recreate the original header even when it + /// doesn't follow standard rules, but the exported content would be more + /// verbosed. + /// + public bool IncludePaddingEntries { get; set; } + + /// + /// Gets or sets a value indicating whether to throw exceptions if the read + /// data contains unexpected information that doesn't match the specs. + /// + /// + /// Some games didn't generate full complaint files but valid enough to work. + /// + public bool ThrowOnInvalidData { get; set; } + + /// + public VabHeader Convert(IBinary source) + { + ArgumentNullException.ThrowIfNull(source); + + source.Stream.Position = 0; + var reader = new DataReader(source.Stream) { + Endianness = EndiannessMode.LittleEndian, + }; + + var header = new VabHeader(); + SectionsInfo sectionsInfo = ReadHeader(reader, header); + + ReadProgramsWithAttributes(reader, header, sectionsInfo); + + reader.Stream.Position = VabHeader.TonesAttributesOffset + + (VabHeader.TonesSectionSizePerProgram * sectionsInfo.ProgramCount); + ReadWaveformSizes(reader, header, sectionsInfo.WaveformCount); + + if (ThrowOnInvalidData) { + ValidateFormat(header, sectionsInfo); + } + + return header; + } + + private static SectionsInfo ReadHeader(DataReader reader, VabHeader header) + { + string fileId = reader.ReadString(4); + if (fileId != VabHeader.FormatId) { + throw new FormatException($"Invalid format ID '{fileId}'"); + } + + header.Version = reader.ReadInt32(); + if (!supportedVersions.Contains(header.Version)) { + throw new NotSupportedException($"Unsupported format version 0x{header.Version:X}"); + } + + header.VabId = reader.ReadInt32(); + int fullSize = reader.ReadInt32(); + header.Reserved0 = reader.ReadInt16(); + + int programCount = reader.ReadUInt16(); + int toneCount = reader.ReadUInt16(); + int waveformCount = reader.ReadUInt16(); + + header.MasterVolume = reader.ReadByte(); + header.MasterPan = reader.ReadByte(); + header.BankAttribute1 = reader.ReadByte(); + header.BankAttribute2 = reader.ReadByte(); + header.Reserved1 = reader.ReadInt32(); + + return new SectionsInfo(fullSize, programCount, toneCount, waveformCount); + } + + private void ReadProgramsWithAttributes(DataReader reader, VabHeader header, SectionsInfo sectionsInfo) + { + int programIdx = -1; + int readPrograms = 0; + int validProgramsCount = 0; + int programCount = IncludePaddingEntries + ? VabHeader.MaximumPrograms + : sectionsInfo.ProgramCount; + while (readPrograms < programCount) { + programIdx++; + + int relativeOffset = programIdx * VabHeader.ProgramAttributesSize; + reader.Stream.Position = VabHeader.HeaderSize + relativeOffset; + + var program = ReadProgramAttributes(reader, out int toneCount); + program.Index = programIdx; + header.ProgramsAttributes.Add(program); + + // Between programs, some info are empty and doesn't count toward + // count in header. But added as their attributes are not constant + // so it can generate an identical file later. + if (toneCount == 0) { + if (IncludePaddingEntries) { + readPrograms++; + } + + continue; + } + + int toneRelativeOffset = VabHeader.TonesSectionSizePerProgram * validProgramsCount; + reader.Stream.Position = VabHeader.TonesAttributesOffset + toneRelativeOffset; + + int readTones = 0; + int readValidTones = 0; + int tonesToRead = IncludePaddingEntries ? VabHeader.MaximumTones : toneCount; + while (readTones < tonesToRead) { + // NOTE: A program has always 16 tones but the remaining ones will be empty + VabToneAttributes tone = ReadToneAttributes(reader); + tone.IsValid = readValidTones < toneCount && tone.WaveformIndex >= 0; + + program.TonesAttributes.Add(tone); + + // Similar to programs, some files may have empty tones before + // the ones that count. We add them as their info is not constant. + if (tone.IsValid || IncludePaddingEntries) { + readTones++; + } + + if (tone.IsValid) { + readValidTones++; + } + } + + readPrograms++; + validProgramsCount++; + } + } + + private static VabProgramAttributes ReadProgramAttributes(DataReader reader, out int toneCount) + { + var program = new VabProgramAttributes(); + + toneCount = reader.ReadByte(); + program.MasterVolume = reader.ReadByte(); + program.Priority = reader.ReadByte(); + program.Mode = reader.ReadByte(); + program.MasterPanning = reader.ReadByte(); + program.Reserved0 = reader.ReadByte(); + program.Attributes = reader.ReadInt16(); + program.Reserved1 = reader.ReadInt32(); + program.Reserved2 = reader.ReadInt32(); + + return program; + } + + private static VabToneAttributes ReadToneAttributes(DataReader reader) + { + var tone = new VabToneAttributes(); + + tone.Priority = reader.ReadByte(); + tone.Mode = reader.ReadByte(); + tone.Volume = reader.ReadByte(); + tone.Panning = reader.ReadByte(); + tone.Centre = reader.ReadByte(); + tone.Fine = reader.ReadByte(); + tone.Minimum = reader.ReadByte(); + tone.Maximum = reader.ReadByte(); + tone.VibrationWidth = reader.ReadByte(); + tone.VibrationTime = reader.ReadByte(); + tone.PortamentoWidth = reader.ReadByte(); + tone.PortamentoTime = reader.ReadByte(); + tone.PitchBendMinimum = reader.ReadByte(); + tone.PitchBendMaximum = reader.ReadByte(); + tone.Reserved0 = reader.ReadByte(); + tone.Reserved1 = reader.ReadByte(); + tone.EnvelopeSettings1 = reader.ReadInt16(); + tone.EnvelopeSettings2 = reader.ReadInt16(); + tone.ProgramIndex = reader.ReadInt16(); + tone.WaveformIndex = (short)(reader.ReadInt16() - 1); // 1-based index + tone.Reserved2 = reader.ReadInt64(); + + return tone; + } + + private static void ReadWaveformSizes(DataReader reader, VabHeader header, int count) + { + reader.ReadUInt16(); // skip fist always 0 (because 1-based indexes) + for (int i = 0; i < count; i++) { + int audioSize = reader.ReadUInt16() << 3; + header.WaveformSizes.Add(audioSize); + } + } + + private static void ValidateFormat(VabHeader format, SectionsInfo sectionsInfo) + { + int totalTones = 0; + foreach (VabProgramAttributes program in format.ProgramsAttributes) { + + for (int toneIdx = 0; toneIdx < program.TonesAttributes.Count; toneIdx++) { + VabToneAttributes tone = program.TonesAttributes[toneIdx]; + totalTones++; + + if (tone.ProgramIndex != program.Index) { + throw new FormatException( + $"Unxpected program index in tone #{program.Index}/{toneIdx} -> {tone.ProgramIndex}"); + } + + if (tone.WaveformIndex < -1 || tone.WaveformIndex >= sectionsInfo.WaveformCount) { + throw new FormatException($"Unexpected waveform index in tone #{program.Index}/{toneIdx}"); + } + } + } + + int actualSize = format.GetVabSize(); + if (actualSize != sectionsInfo.FullSize) { + throw new FormatException( + $"Unexpected VAB size. " + + $"Expected: {actualSize}. Header: {sectionsInfo.FullSize}"); + } + } + + private sealed record SectionsInfo( + int FullSize, + int ProgramCount, + int TotalToneCount, + int WaveformCount); +} diff --git a/src/Hinox/Audio/BinaryVab2Container.cs b/src/Hinox/Audio/BinaryVab2Container.cs new file mode 100644 index 0000000..d551fa4 --- /dev/null +++ b/src/Hinox/Audio/BinaryVab2Container.cs @@ -0,0 +1,80 @@ +namespace SceneGate.Hinox.Audio; + +using System; +using Yarhl.FileFormat; +using Yarhl.FileSystem; +using Yarhl.IO; + +/// +/// Converter for reading a VAB from its standard binary format into +/// a container with the header and audios nodes. +/// +/// +/// The container contains a node 'header' with the VH content in +/// format. +/// +public class BinaryVab2Container : IConverter +{ + /// + /// Initializes a new instance of the class. + /// + public BinaryVab2Container() + { + IncludePaddingTones = false; + ThrowOnInvalidData = true; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// Value that indicates whether to include empty tones. + /// + /// + /// Value indicating whether to throw exceptions on unexpected data. + /// + public BinaryVab2Container(bool includePaddingTones, bool throwOnInvalid) + { + IncludePaddingTones = includePaddingTones; + ThrowOnInvalidData = throwOnInvalid; + } + + /// + /// Gets or sets a value indicating whether to include empty tones without + /// a valid waveform links. + /// + /// + /// Setting to true allows to recreate the original header even when it + /// doesn't follow standard rules, but the exported content would be more + /// verbosed. + /// + public bool IncludePaddingTones { get; set; } + + /// + /// Gets or sets a value indicating whether to throw exceptions if the read + /// data contains unexpected information that doesn't match the specs. + /// + /// + /// Some games didn't generate full complaint files but valid enough to work. + /// + public bool ThrowOnInvalidData { get; set; } + + /// + public NodeContainerFormat Convert(IBinary source) + { + ArgumentNullException.ThrowIfNull(source); + + using var binaryHeader = new BinaryFormat(source.Stream, 0, source.Stream.Length); + VabHeader header = new Binary2VabHeader(IncludePaddingTones, ThrowOnInvalidData) + .Convert(binaryHeader); + + int vbOffset = header.GetHeaderSize(); + long vbLength = source.Stream.Length - vbOffset; + using var binaryBody = new BinaryFormat(source.Stream, vbOffset, vbLength); + NodeContainerFormat container = new BinaryVabBody2Container(header).Convert(binaryBody); + + container.Root.Add(new Node("header", header)); + + return container; + } +} diff --git a/src/Hinox/Audio/BinaryVabBody2Container.cs b/src/Hinox/Audio/BinaryVabBody2Container.cs new file mode 100644 index 0000000..a1588e4 --- /dev/null +++ b/src/Hinox/Audio/BinaryVabBody2Container.cs @@ -0,0 +1,45 @@ +namespace SceneGate.Hinox.Audio; + +using System; +using Yarhl.FileFormat; +using Yarhl.FileSystem; +using Yarhl.IO; + +/// +/// Unpack the binary body of a VAB container (.VB) containing waveforms. +/// It requires the VAB header. +/// +public class BinaryVabBody2Container : IConverter +{ + private readonly VabHeader header; + + /// + /// Initializes a new instance of the class. + /// + /// Header of the matching VAB body. + public BinaryVabBody2Container(VabHeader header) + { + ArgumentNullException.ThrowIfNull(header); + this.header = header; + } + + /// + public NodeContainerFormat Convert(IBinary source) + { + ArgumentNullException.ThrowIfNull(source); + + var container = new NodeContainerFormat(); + + long currentOffset = 0; + for (int i = 0; i < header.WaveformSizes.Count; i++) { + int fileSize = header.WaveformSizes[i]; + var waveformData = new BinaryFormat(source.Stream, currentOffset, fileSize); + var waveformNode = new Node($"audio{i:D4}", waveformData); + container.Root.Add(waveformNode); + + currentOffset += fileSize; + } + + return container; + } +} diff --git a/src/Hinox/Audio/Container2BinaryVab.cs b/src/Hinox/Audio/Container2BinaryVab.cs new file mode 100644 index 0000000..bc31a49 --- /dev/null +++ b/src/Hinox/Audio/Container2BinaryVab.cs @@ -0,0 +1,96 @@ +namespace SceneGate.Hinox.Audio; + +using System; +using System.Linq; +using Yarhl.FileFormat; +using Yarhl.FileSystem; +using Yarhl.IO; + +/// +/// Converter for writing a VAB format from a node container. +/// +public class Container2BinaryVab : IConverter +{ + private readonly bool autodetectVag; + + /// + /// Initializes a new instance of the class + /// without VAG autodetection. + /// + public Container2BinaryVab() + { + autodetectVag = false; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// Indicates whether to autodetect and remove VAG header in audio files. + /// + public Container2BinaryVab(bool autodetectVag) + { + this.autodetectVag = autodetectVag; + } + + /// + public BinaryFormat Convert(NodeContainerFormat source) + { + ArgumentNullException.ThrowIfNull(source); + + // Update wave sizes before writing anything + VabHeader header = GetHeader(source); + UpdateFileSizes(header, source, autodetectVag); + + var vabBinary = new BinaryFormat(); + + using var vhBinary = new VabHeader2Binary().Convert(header); + vhBinary.Stream.WriteTo(vabBinary.Stream); + + using var vbBinary = new Container2BinaryVabBody(autodetectVag).Convert(source); + vbBinary.Stream.WriteTo(vabBinary.Stream); + + return vabBinary; + } + + /// + /// Update the waveform sizes of a VAB header from the audios of a container. + /// + /// The VH format to update. + /// The container with audios. + /// Value indicating whether to autodetect and remove VAG header. + /// + /// The nodes in the container must be binary or VabHeader (ignored). + /// + public static void UpdateFileSizes(VabHeader header, NodeContainerFormat source, bool autodetectVag) + { + header.WaveformSizes.Clear(); + foreach (Node child in source.Root.Children) { + if (child.Format is VabHeader) { + continue; + } + + if (child.Format is not IBinary binChild) { + throw new FormatException($"Invalid format for child: '{child.Path}'"); + } + + long childLength = autodetectVag + ? VagFormatAnalyzer.GetChannelsLength(binChild.Stream) + : binChild.Stream.Length; + header.WaveformSizes.Add((int)childLength); + } + } + + private static VabHeader GetHeader(NodeContainerFormat source) + { + VabHeader? header = source.Root.Children + .Select(n => n.Format) + .OfType() + .FirstOrDefault(); + if (header is null) { + throw new FormatException("Cannot find header node"); + } + + return header; + } +} diff --git a/src/Hinox/Audio/Container2BinaryVabBody.cs b/src/Hinox/Audio/Container2BinaryVabBody.cs new file mode 100644 index 0000000..4f774f2 --- /dev/null +++ b/src/Hinox/Audio/Container2BinaryVabBody.cs @@ -0,0 +1,72 @@ +namespace SceneGate.Hinox.Audio; + +using System; +using Yarhl.FileFormat; +using Yarhl.FileSystem; +using Yarhl.IO; + +/// +/// Converter for writing VAB body (VB) from a container into its standard binary format. +/// +public class Container2BinaryVabBody : IConverter +{ + private readonly bool autodetectVag; + + /// + /// Initializes a new instance of the class + /// without VAG autodetection. + /// + public Container2BinaryVabBody() + { + autodetectVag = false; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// Indicates whether to autodetect and remove VAG header in audio files. + /// + public Container2BinaryVabBody(bool autodetectVag) + { + this.autodetectVag = autodetectVag; + } + + /// + public BinaryFormat Convert(NodeContainerFormat source) + { + ArgumentNullException.ThrowIfNull(source); + + var binary = new BinaryFormat(); + + int count = 0; + foreach (Node child in source.Root.Children) { + if (child.Format is VabHeader) { + continue; + } + + if (child.Format is not IBinary binChild) { + throw new FormatException($"Invalid format for child: '{child.Path}'"); + } + + count++; + if (count > VabHeader.MaximumWaveforms) { + throw new FormatException("Reached maximum number of audio files"); + } + + if (!autodetectVag) { + binChild.Stream.WriteTo(binary.Stream); + } else { + long channelsLength = VagFormatAnalyzer.GetChannelsLength(binChild.Stream); + long dataOffset = binChild.Stream.Length - channelsLength; + binChild.Stream.WriteSegmentTo(dataOffset, binary.Stream); + } + } + + if (binary.Stream.Length > VabHeader.MaximumTotalWaveformsSize) { + throw new FormatException("Total audio length is larger than maximum supported"); + } + + return binary; + } +} diff --git a/src/Hinox/Audio/VabHeader.cs b/src/Hinox/Audio/VabHeader.cs new file mode 100644 index 0000000..0b4a69c --- /dev/null +++ b/src/Hinox/Audio/VabHeader.cs @@ -0,0 +1,115 @@ +namespace SceneGate.Hinox.Audio; + +using System.Collections.ObjectModel; +using Yarhl.FileFormat; + +/// +/// Represents the header of a VAB file format (.VAB), also found as separate +/// files with .VH extension. +/// +public class VabHeader : IFormat +{ + internal const int HeaderSize = 0x20; + + internal const int ProgramAttributesSize = 0x10; + internal const int MaximumPrograms = 0x80; + internal const int ProgramsSectionSize = MaximumPrograms * ProgramAttributesSize; + + internal const int ToneAttributesSize = 0x20; + internal const int MaximumTones = 0x10; + internal const int TonesSectionSizePerProgram = MaximumTones * ToneAttributesSize; + internal const int TonesAttributesOffset = HeaderSize + ProgramsSectionSize; + + internal const int WaveformsSizeSectionSize = 0x200; + + /// + /// Gets the ID or magic stamp of the binary format. + /// + /// VABp as little-endian. + public static string FormatId => "pBAV"; + + /// + /// Gets the maximum number of waveforms in the container. + /// + public static int MaximumWaveforms => 254; + + /// + /// Gets the maximum allowed total length of all the waveforms in the container. + /// This is the sum of all the waveforms sizes as they would be on memory. + /// + /// This is driven by a hardware limit of 512KB in the SPU RAM. + public static int MaximumTotalWaveformsSize => 0x7E000; + + /// + /// Gets or sets the version of the format. + /// + public int Version { get; set; } + + /// + /// Gets or sets the ID of the VAB file. + /// + public int VabId { get; set; } + + /// + /// Gets or sets a reserved field at position 0x10. + /// + public short Reserved0 { get; set; } + + /// + /// Gets or sets the master volume of the VAB audios. + /// + public byte MasterVolume { get; set; } + + /// + /// Gets or sets the master pan of the VAB audios. + /// + public byte MasterPan { get; set; } + + /// + /// Gets or sets the first user-defined bank attributes. + /// + public byte BankAttribute1 { get; set; } + + /// + /// Gets or sets the second user-defined bank attributes. + /// + public byte BankAttribute2 { get; set; } + + /// + /// Gets or sets a reserved field at position 0x1C. + /// + public int Reserved1 { get; set; } + + /// + /// Gets the collection of programs attributes with their tones attributes. + /// + public Collection ProgramsAttributes { get; init; } = []; + + /// + /// Gets the collection of file length of the waveform audios in the container. + /// + public Collection WaveformSizes { get; } = []; + + /// + /// Gets the size of the VH header format. + /// + /// + public int GetHeaderSize() + { + int validPrograms = ProgramsAttributes.Count(p => p.TonesAttributes.Count > 0); + return HeaderSize + + ProgramsSectionSize + + (TonesSectionSizePerProgram * validPrograms) + + WaveformsSizeSectionSize; + } + + /// + /// Gets the full size of the VAB file (header and body). + /// + /// The full size of the VAB format. + public int GetVabSize() + { + int bodySize = WaveformSizes.Sum(); + return GetHeaderSize() + bodySize; + } +} diff --git a/src/Hinox/Audio/VabHeader2Binary.cs b/src/Hinox/Audio/VabHeader2Binary.cs new file mode 100644 index 0000000..871f23d --- /dev/null +++ b/src/Hinox/Audio/VabHeader2Binary.cs @@ -0,0 +1,209 @@ +namespace SceneGate.Hinox.Audio; + +using System; +using System.Diagnostics.CodeAnalysis; +using Yarhl.FileFormat; +using Yarhl.IO; + +/// +/// Converter for writing VAB header (VH) into its standard binary format. +/// +public class VabHeader2Binary : IConverter +{ + private static readonly int[] supportedVersions = [5, 6, 7]; + + /// + public BinaryFormat Convert(VabHeader source) + { + ArgumentNullException.ThrowIfNull(source); + + var binary = new BinaryFormat(); + var writer = new DataWriter(binary.Stream) { + Endianness = EndiannessMode.LittleEndian, + }; + + if (!supportedVersions.Contains(source.Version)) { + throw new NotSupportedException("Unsupported VH version"); + } + + WriteHeader(writer, source); + WriteProgramsAttributes(writer, source); + WriteTonesAttributes(writer, source); + WriteWaveformSizes(writer, source); + + return binary; + } + + private static void WriteHeader(DataWriter writer, VabHeader format) + { + int programCount = format.ProgramsAttributes.Count(p => p.TonesAttributes.Count > 0); + int toneCount = format.ProgramsAttributes.Sum(p => + p.TonesAttributes.Count(t => t.IsValid)); + int waveformsCount = format.WaveformSizes.Count; + + writer.Write(VabHeader.FormatId, nullTerminator: false); + writer.Write(format.Version); + writer.Write(format.VabId); + writer.Write(format.GetVabSize()); + writer.Write(format.Reserved0); + writer.Write((ushort)programCount); + writer.Write((ushort)toneCount); + writer.Write((ushort)waveformsCount); + writer.Write(format.MasterVolume); + writer.Write(format.MasterPan); + writer.Write(format.BankAttribute1); + writer.Write(format.BankAttribute2); + writer.Write(format.Reserved1); + } + + private static void WriteProgramsAttributes(DataWriter writer, VabHeader format) + { + if (format.ProgramsAttributes.Count > 0 && format.ProgramsAttributes[0].Index != 0) { + throw new FormatException("First program must have index 0"); + } + + foreach (VabProgramAttributes program in format.ProgramsAttributes) { + WriteProgramAttributes(writer, program); + } + + VabProgramAttributes lastProgram = format.ProgramsAttributes.Count == 0 + ? new VabProgramAttributes() // constructor sets default properties + : format.ProgramsAttributes[^1]; + + int finalEmptyCount = VabHeader.MaximumPrograms - (lastProgram.Index + 1); + for (int m = 0; m < finalEmptyCount; m++) { + WriteEmptyProgramAttributes(writer, format.Version, lastProgram); + } + } + + private static void WriteProgramAttributes(DataWriter writer, VabProgramAttributes program) + { + int tonesCount = program.TonesAttributes.Count(t => t.IsValid); + writer.Write((byte)tonesCount); + writer.Write(program.MasterVolume); + writer.Write(program.Priority); + writer.Write(program.Mode); + writer.Write(program.MasterPanning); + writer.Write(program.Reserved0); + writer.Write(program.Attributes); + writer.Write(program.Reserved1); + writer.Write(program.Reserved2); + } + + private static void WriteEmptyProgramAttributes(DataWriter writer, int version, VabProgramAttributes reference) + { + bool cleanMasterValues = version >= 6; + + writer.Write((byte)0); + writer.Write(cleanMasterValues ? (byte)0 : reference.MasterVolume); + writer.Write(reference.Priority); + writer.Write(reference.Mode); + writer.Write(cleanMasterValues ? (byte)0 : reference.MasterPanning); + writer.Write(reference.Reserved0); + writer.Write(reference.Attributes); + writer.Write(reference.Reserved1); + writer.Write(reference.Reserved2); + } + + [SuppressMessage("", "S3267:Loops should be simplified with \"LINQ\" expressions", Justification = "Readability")] + private static void WriteTonesAttributes(DataWriter writer, VabHeader format) + { + foreach (VabProgramAttributes program in format.ProgramsAttributes) { + if (program.TonesAttributes.Count == 0) { + continue; + } + + int writtenTones = 0; + foreach (VabToneAttributes tone in program.TonesAttributes) { + WriteToneAttributes(writer, tone); + writtenTones++; + } + + int finalEmptyCount = VabHeader.MaximumTones - writtenTones; + for (int t = 0; t < finalEmptyCount; t++) { + WriteEmptyToneAttributes(writer, format.Version, program.TonesAttributes[^1]); + } + } + } + + private static void WriteToneAttributes(DataWriter writer, VabToneAttributes tone) + { + writer.Write(tone.Priority); + writer.Write(tone.Mode); + writer.Write(tone.Volume); + writer.Write(tone.Panning); + writer.Write(tone.Centre); + writer.Write(tone.Fine); + writer.Write(tone.Minimum); + writer.Write(tone.Maximum); + writer.Write(tone.VibrationWidth); + writer.Write(tone.VibrationTime); + writer.Write(tone.PortamentoWidth); + writer.Write(tone.PortamentoTime); + writer.Write(tone.PitchBendMinimum); + writer.Write(tone.PitchBendMaximum); + writer.Write(tone.Reserved0); + writer.Write(tone.Reserved1); + writer.Write(tone.EnvelopeSettings1); + writer.Write(tone.EnvelopeSettings2); + writer.Write(tone.ProgramIndex); + writer.Write((ushort)(tone.WaveformIndex + 1)); + writer.Write(tone.Reserved2); + } + + private static void WriteEmptyToneAttributes(DataWriter writer, int version, VabToneAttributes reference) + { + bool cleanAttributes = version >= 6; + if (cleanAttributes) { + writer.WriteTimes(0, 14); + } else { + writer.Write(reference.Priority); + writer.Write(reference.Mode); + writer.Write(reference.Volume); + writer.Write(reference.Panning); + writer.Write(reference.Centre); + writer.Write(reference.Fine); + writer.Write((byte)0); // min + writer.Write((byte)0); // max + writer.Write(reference.VibrationWidth); + writer.Write(reference.VibrationTime); + writer.Write(reference.PortamentoWidth); + writer.Write(reference.PortamentoTime); + writer.Write(reference.PitchBendMinimum); + writer.Write(reference.PitchBendMaximum); + } + + writer.Write(reference.Reserved0); + writer.Write(reference.Reserved1); + + if (version <= 5) { + writer.Write(reference.EnvelopeSettings1); + writer.Write(reference.EnvelopeSettings2); + } else if (version == 6) { + writer.Write((uint)0); + } else if (version >= 7) { + writer.Write((ushort)0x80FF); + writer.Write((ushort)0x5FC0); + } + + writer.Write(reference.ProgramIndex); + + bool cleanWaveformIndex = version >= 6; + writer.Write(cleanWaveformIndex ? (ushort)0 : (ushort)(reference.WaveformIndex + 1)); + + writer.Write(reference.Reserved2); + } + + private static void WriteWaveformSizes(DataWriter writer, VabHeader format) + { + writer.Write((ushort)0); + foreach (int waveformSize in format.WaveformSizes) { + ushort encoded = (ushort)(waveformSize >> 3); + writer.Write(encoded); + } + + int currentSize = (format.WaveformSizes.Count + 1) * 2; + int padding = VabHeader.WaveformsSizeSectionSize - currentSize; + writer.WriteTimes(0, padding); + } +} diff --git a/src/Hinox/Audio/VabProgramAttributes.cs b/src/Hinox/Audio/VabProgramAttributes.cs new file mode 100644 index 0000000..2c56a38 --- /dev/null +++ b/src/Hinox/Audio/VabProgramAttributes.cs @@ -0,0 +1,59 @@ +namespace SceneGate.Hinox.Audio; + +using System.Collections.ObjectModel; + +/// +/// Represents the attributes of a VAB program. +/// +public class VabProgramAttributes +{ + /// + /// Gets or sets the index of the program in the VAB format. + /// + public int Index { get; set; } = -1; + + /// + /// Gets or sets the master volume of the tones in the program. + /// + public byte MasterVolume { get; set; } + + /// + /// Gets or sets the priority of the tones. + /// + public byte Priority { get; set; } + + /// + /// Gets or sets the mode. + /// + public byte Mode { get; set; } = 0xE0; + + /// + /// Gets or sets the master panning. + /// + public byte MasterPanning { get; set; } + + /// + /// Gets or sets a reserved field at position 0x5. + /// + public byte Reserved0 { get; set; } + + /// + /// Gets or sets additional attributes. + /// + public short Attributes { get; set; } + + /// + /// Gets or sets a reserved field at position 0x8. + /// + public int Reserved1 { get; set; } = -1; + + /// + /// Gets or sets a reserved field at position 0xC. + /// + public int Reserved2 { get; set; } = -1; + + /// + /// Gets the collection of tones attributes in the program. + /// + public Collection TonesAttributes { get; init; } = []; +} diff --git a/src/Hinox/Audio/VabToneAttributes.cs b/src/Hinox/Audio/VabToneAttributes.cs new file mode 100644 index 0000000..58b1309 --- /dev/null +++ b/src/Hinox/Audio/VabToneAttributes.cs @@ -0,0 +1,125 @@ +namespace SceneGate.Hinox.Audio; + +/// +/// Represents the attributes of tones for a program in a VAB audio container. +/// +public class VabToneAttributes +{ + /// + /// Gets or sets a value indicating whether this tone contains valid info. + /// + /// + /// This field is used to distinguished tone attributes written in VAB + /// header for padding. They don't point to a waveform. It allows to + /// recreate an identical VH to the original even when the format doesn't + /// follow the specification well. + /// + public bool IsValid { get; set; } = false; + + /// + /// Gets or sets the priority. + /// + public byte Priority { get; set; } + + /// + /// Gets or sets the mode. + /// + /// 0: normal, 4: reverberation. + public byte Mode { get; set; } + + /// + /// Gets or sets the tone volume. + /// + public byte Volume { get; set; } + + /// + /// Gets or sets the tone panning. + /// + public byte Panning { get; set; } + + /// + /// Gets or sets the centre note (in semitone units). + /// + public byte Centre {get; set; } + + /// + /// Gets or sets the centre note fine tuning for pitch correction. + /// + public byte Fine { get; set; } + + /// + /// Gets or sets the note minimum value. + /// + public byte Minimum { get; set; } + + /// + /// Gets or sets the note maximum value. + /// + public byte Maximum { get; set; } + + /// + /// Gets or sets the vibration width. + /// + public byte VibrationWidth { get; set; } + + /// + /// Gets or sets the vibration duration. + /// + public byte VibrationTime { get; set; } + + /// + /// Gets or sets the portamento width. + /// + public byte PortamentoWidth { get; set; } + + /// + /// Gets or sets the portamento duration. + /// + public byte PortamentoTime { get; set; } + + /// + /// Gets or sets the minimum pitch bend. + /// + public byte PitchBendMinimum { get; set; } + + /// + /// Gets or sets the maximum pitch bend. + /// + public byte PitchBendMaximum { get; set; } + + /// + /// Gets or sets a reserved field at position 0xE. + /// + public byte Reserved0 { get; set; } + + /// + /// Gets or sets a reserved field at position 0xF. + /// + public byte Reserved1 { get; set; } + + /// + /// Gets or sets the envelope settings for attack and decay. + /// + public short EnvelopeSettings1 { get; set; } + + /// + /// Gets or sets the envelope settings for release and sustain. + /// + public short EnvelopeSettings2 { get; set; } + + /// + /// Gets or sets the 0-based index of the program of the tone + /// in the serialized binary format. + /// + public short ProgramIndex { get; set; } + + /// + /// Gets or sets the 0-based index of the waveform (VAG) audio. + /// + public short WaveformIndex { get; set; } + + /// + /// Gets or sets 4 16-bits values of reserved fields at position 0x18. + /// + public long Reserved2 { get; set; } +} diff --git a/src/Hinox/Audio/VagFormatAnalyzer.cs b/src/Hinox/Audio/VagFormatAnalyzer.cs new file mode 100644 index 0000000..57d9f4b --- /dev/null +++ b/src/Hinox/Audio/VagFormatAnalyzer.cs @@ -0,0 +1,84 @@ +namespace SceneGate.Hinox.Audio; + +using Yarhl.IO; + +/// +/// Analyzer of binary data with potential VAG format content. +/// +/// Only standard PSX VAG format (VAGp) supported. +public static class VagFormatAnalyzer +{ + private const string VagpFormatId = "VAGp"; + private const int VagDataOffset = 0x30; + + /// + /// Get the length of the waveform data without header. + /// + /// Waveform stream. + /// Length of the audio channels without header. + /// + /// It will attempt to detect if it's a VAG (valid, with format ID in the header) + /// and if it's the case, it will skip its header. This assummes is either VAG or raw data. + /// + public static long GetChannelsLength(Stream waveform) + { + return IsVagFormat(waveform) + ? waveform.Length - VagDataOffset + : waveform.Length; + } + + /// + /// Determine if the binary data represents a full VAG format. + /// + /// Binary stream to analyze. + /// Value indicating whether the binary stream represents a VAG format with header. + public static bool IsVagFormat(Stream binary) + { + if (binary.Length < VagDataOffset) { + return false; + } + + binary.Position = 0; + var reader = new DataReader(binary) { + Endianness = EndiannessMode.BigEndian, + }; + + // Standard case for PSX + string formatId = reader.ReadString(4); + if (formatId == VagpFormatId) { + return true; + } + + return IsVagEditVagFormat(binary); + } + + private static bool IsVagEditVagFormat(Stream binary) + { + binary.Position = 0; + var reader = new DataReader(binary) { + Endianness = EndiannessMode.BigEndian, + }; + + // VAGEdit seems to generate valid VAG files without header + // First, to avoid false positives validate empty format ID and version + if (reader.ReadUInt64() != 0x00) { + return false; + } + + // Channel size must be set but could be empty for null raw files or empty VAG files. + // But sample rate shouldn't be 0 + reader.Stream.Position = 0x10; + uint sampleRate = reader.ReadUInt32(); + if (sampleRate == 0 || sampleRate > 96000) { // I really doubt it would be higher than 22k + return false; + } + + // Let's try to autodetect by checking the theorical channel size field + // This assumes MONO only. Stereo formats ARE NOT supported yet. + reader.Stream.Position = 0x0C; + uint channelSize = reader.ReadUInt32(); + uint expectedTotalLength = channelSize + VagDataOffset; + + return expectedTotalLength == binary.Length; + } +} diff --git a/src/Hinox/Hinox.csproj b/src/Hinox/Hinox.csproj index 2adfb26..16a01f5 100644 --- a/src/Hinox/Hinox.csproj +++ b/src/Hinox/Hinox.csproj @@ -1,4 +1,4 @@ - + SceneGate.Hinox @@ -17,4 +17,8 @@ + + + +