Updated some Voicebank and AudioCollection stuff

This commit is contained in:
Michael Becker 2014-08-05 16:03:53 -04:00
parent bf274e7a4e
commit d912947b11
9 changed files with 982 additions and 0 deletions

View File

@ -0,0 +1,152 @@
// one line to give the program's name and an idea of what it does.
// Copyright (C) yyyy name of author
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank;
using UniversalEditor.UserInterface;
using UniversalEditor.UserInterface.WindowsForms;
namespace UniversalEditor.Editors.Multimedia.Audio.Voicebank
{
// TODO: Create a file-format-independent explorer listview.
// The VoiceDatabaseEditor uses an Explorer listview interface. This means that
// PhonemeGroups are represented as folders, and Phonemes within those PhonemeGroups
// are represented as files. This makes it easy for a user to add/delete these kinds
// of items without having to learn complex interfaces.
// Where practical, I'd like to implement this interface in editors. If there is more
// than one editor that can be used to edit a particular type of file (for example,
// VoiceDatabaseProgrammerEditor and VoiceDatabaseExplorerEditor), the different
// editors will be listed when GetAvailableEditors (...) is called.
// For our test case (EDSEdit), these editors will be listed as tabs near the bottom
// of the screen. The upside to this model of course is that there will be a common
// editor for these types of files.
// The ExplorerEditorBase will expose a Folders collection and a Files collection.
// The ExplorerEditorBase will also have a built-in search box (which can be hidden
// if developing an app that has its own search methods) and a built-in search
// function Search(string text) (which can be used when developing aformentioned app)
// When user clicks on a folder (or a file), the ExplorerView will fire an ItemClick
// event (or for double-clicks, an ItemDoubleClick event) that the author of the Editor
// will handle by overriding the OnItemClick (or OnItemDoubleClick) event. The item
// that had been clicked will automatically go into the navigation stack (so a Back/Up
// button can be implemented without too much difficulty) and the author will be
// responsible for populating the next set of items in the hierarchy.
// Of course, the entire idea behind this is that EDS will become a drop-in replacement
// for any explorer on any system, and will be able to read and edit any files without
// difficulty.
/// <summary>
/// Description of VoiceDatabaseEditor.
/// </summary>
public partial class VoicebankEditor : Editor
{
public VoicebankEditor()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
base.SupportedObjectModels.Add(typeof(VoicebankObjectModel));
// Select "Explorer" view by default, it looks nice~
tabControl1.SelectedIndex = 1;
}
/*
public override bool NavigateImaginaryPath(string path)
{
if (base.ObjectModel is VoicebankObjectModel)
{
VoicebankObjectModel ddi = (base.ObjectModel as VoicebankObjectModel);
PhonemeGroup pg = ddi.PhonemeGroups[path];
if (pg != null)
{
lvGroups.Items[ddi.PhonemeGroups.IndexOf(pg)].Selected = true;
}
else
{
MessageBox.Show("Phoneme group " + path + " does not exist in this file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
return false;
}
*/
protected override void OnObjectModelChanged(EventArgs e)
{
base.OnObjectModelChanged(e);
if (base.ObjectModel is VoicebankObjectModel)
{
VoicebankObjectModel ddi = (base.ObjectModel as VoicebankObjectModel);
lvGroups.Items.Clear();
lvPhonemes.Items.Clear();
foreach(PhonemeGroup pg in ddi.PhonemeGroups)
{
ListViewItem lvi = new ListViewItem();
lvi.Text = pg.Title;
lvi.SubItems.Add(pg.Phonemes.Count.ToString());
// lvi.SubItems.Add(pg.Data1.ToString());
// lvi.SubItems.Add(pg.Data2.ToString());
lvGroups.Items.Add(lvi);
ListViewItem lvie = new ListViewItem();
lvie.Text = pg.Title;
lvie.SubItems.Add(pg.Phonemes.Count.ToString());
// lvie.SubItems.Add(pg.Data1.ToString());
// lvie.SubItems.Add(pg.Data2.ToString());
lvie.ImageKey = "folder_closed";
lvExplorer.Items.Add(lvie);
}
}
}
void lvGroups_SelectedIndexChanged(object sender, EventArgs e)
{
if (base.ObjectModel is VoicebankObjectModel)
{
VoicebankObjectModel ddi = (base.ObjectModel as VoicebankObjectModel);
lvPhonemes.Items.Clear();
if (lvGroups.SelectedIndices.Count == 1)
{
foreach (Phoneme p in ddi.PhonemeGroups[lvGroups.SelectedIndices[0]].Phonemes)
{
ListViewItem lvi = new ListViewItem();
lvi.Text = p.Title;
// lvi.SubItems.Add(p.Data.ToString());
lvPhonemes.Items.Add(lvi);
}
}
}
}
}
}

View File

@ -0,0 +1,286 @@
// one line to give the program's name and an idea of what it does.
// Copyright (C) yyyy name of author
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
namespace UniversalEditor.Editors.Multimedia.Audio.Voicebank
{
partial class VoicebankEditor
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the control.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VoiceDatabaseEditor));
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.button2 = new System.Windows.Forms.Button();
this.lvPhonemes = new System.Windows.Forms.ListView();
this.chPhonemeName = new System.Windows.Forms.ColumnHeader();
this.chPhonemeData = new System.Windows.Forms.ColumnHeader();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.button1 = new System.Windows.Forms.Button();
this.lvGroups = new System.Windows.Forms.ListView();
this.chPhonemeGroupName = new System.Windows.Forms.ColumnHeader();
this.chPhonemeGroupPhonemeCount = new System.Windows.Forms.ColumnHeader();
this.chPhonemeGroupData1 = new System.Windows.Forms.ColumnHeader();
this.chPhonemeGroupData2 = new System.Windows.Forms.ColumnHeader();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.lvExplorer = new System.Windows.Forms.ListView();
this.imlExplorerLargeIcons = new System.Windows.Forms.ImageList(this.components);
this.imlExplorerSmallIcons = new System.Windows.Forms.ImageList(this.components);
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.button2);
this.groupBox1.Controls.Add(this.lvPhonemes);
this.groupBox1.Location = new System.Drawing.Point(3, 123);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(400, 175);
this.groupBox1.TabIndex = 1;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Phoneme List";
//
// button2
//
this.button2.Location = new System.Drawing.Point(6, 19);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 0;
this.button2.Text = "button1";
this.button2.UseVisualStyleBackColor = true;
//
// lvPhonemes
//
this.lvPhonemes.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lvPhonemes.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.chPhonemeName,
this.chPhonemeData});
this.lvPhonemes.FullRowSelect = true;
this.lvPhonemes.GridLines = true;
this.lvPhonemes.HideSelection = false;
this.lvPhonemes.Location = new System.Drawing.Point(6, 48);
this.lvPhonemes.Name = "lvPhonemes";
this.lvPhonemes.Size = new System.Drawing.Size(388, 121);
this.lvPhonemes.TabIndex = 1;
this.lvPhonemes.UseCompatibleStateImageBehavior = false;
this.lvPhonemes.View = System.Windows.Forms.View.Details;
//
// chPhonemeName
//
this.chPhonemeName.Text = "Name";
this.chPhonemeName.Width = 285;
//
// chPhonemeData
//
this.chPhonemeData.Text = "Data";
this.chPhonemeData.Width = 94;
//
// groupBox2
//
this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox2.Controls.Add(this.button1);
this.groupBox2.Controls.Add(this.lvGroups);
this.groupBox2.Location = new System.Drawing.Point(3, 3);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(397, 114);
this.groupBox2.TabIndex = 0;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Phoneme Groups";
//
// button1
//
this.button1.Location = new System.Drawing.Point(6, 19);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
//
// lvGroups
//
this.lvGroups.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lvGroups.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.chPhonemeGroupName,
this.chPhonemeGroupPhonemeCount,
this.chPhonemeGroupData1,
this.chPhonemeGroupData2});
this.lvGroups.FullRowSelect = true;
this.lvGroups.GridLines = true;
this.lvGroups.HideSelection = false;
this.lvGroups.Location = new System.Drawing.Point(6, 48);
this.lvGroups.Name = "lvGroups";
this.lvGroups.Size = new System.Drawing.Size(385, 60);
this.lvGroups.TabIndex = 1;
this.lvGroups.UseCompatibleStateImageBehavior = false;
this.lvGroups.View = System.Windows.Forms.View.Details;
this.lvGroups.SelectedIndexChanged += new System.EventHandler(this.lvGroups_SelectedIndexChanged);
//
// chPhonemeGroupName
//
this.chPhonemeGroupName.Text = "Name";
this.chPhonemeGroupName.Width = 190;
//
// chPhonemeGroupPhonemeCount
//
this.chPhonemeGroupPhonemeCount.Text = "Phonemes";
this.chPhonemeGroupPhonemeCount.Width = 82;
//
// chPhonemeGroupData1
//
this.chPhonemeGroupData1.Text = "Data 1";
//
// chPhonemeGroupData2
//
this.chPhonemeGroupData2.Text = "Data 2";
//
// tabControl1
//
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(3, 3);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(414, 327);
this.tabControl1.TabIndex = 3;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.groupBox2);
this.tabPage1.Controls.Add(this.groupBox1);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(406, 301);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Programmer";
this.tabPage1.UseVisualStyleBackColor = true;
//
// tabPage2
//
this.tabPage2.Controls.Add(this.lvExplorer);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(406, 301);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Explorer";
this.tabPage2.UseVisualStyleBackColor = true;
//
// lvExplorer
//
this.lvExplorer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lvExplorer.FullRowSelect = true;
this.lvExplorer.GridLines = true;
this.lvExplorer.HideSelection = false;
this.lvExplorer.LargeImageList = this.imlExplorerLargeIcons;
this.lvExplorer.Location = new System.Drawing.Point(3, 3);
this.lvExplorer.Name = "lvExplorer";
this.lvExplorer.Size = new System.Drawing.Size(400, 295);
this.lvExplorer.SmallImageList = this.imlExplorerSmallIcons;
this.lvExplorer.TabIndex = 1;
this.lvExplorer.UseCompatibleStateImageBehavior = false;
//
// imlExplorerLargeIcons
//
this.imlExplorerLargeIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imlExplorerLargeIcons.ImageStream")));
this.imlExplorerLargeIcons.TransparentColor = System.Drawing.Color.Transparent;
this.imlExplorerLargeIcons.Images.SetKeyName(0, "folder_closed");
this.imlExplorerLargeIcons.Images.SetKeyName(1, "folder_open");
//
// imlExplorerSmallIcons
//
this.imlExplorerSmallIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imlExplorerSmallIcons.ImageStream")));
this.imlExplorerSmallIcons.TransparentColor = System.Drawing.Color.Transparent;
this.imlExplorerSmallIcons.Images.SetKeyName(0, "folder_closed");
this.imlExplorerSmallIcons.Images.SetKeyName(1, "folder_open");
//
// VoiceDatabaseEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tabControl1);
this.Name = "VoiceDatabaseEditor";
this.Size = new System.Drawing.Size(420, 333);
this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.ResumeLayout(false);
}
private System.Windows.Forms.ImageList imlExplorerSmallIcons;
private System.Windows.Forms.ImageList imlExplorerLargeIcons;
private System.Windows.Forms.ListView lvExplorer;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.ColumnHeader chPhonemeGroupData2;
private System.Windows.Forms.ColumnHeader chPhonemeGroupData1;
private System.Windows.Forms.ListView lvPhonemes;
private System.Windows.Forms.ColumnHeader chPhonemeGroupPhonemeCount;
private System.Windows.Forms.ColumnHeader chPhonemeGroupName;
private System.Windows.Forms.ColumnHeader chPhonemeData;
private System.Windows.Forms.ColumnHeader chPhonemeName;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.ListView lvGroups;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox1;
}
}

View File

@ -0,0 +1,273 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="imlExplorerLargeIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>9, 8</value>
</metadata>
<data name="imlExplorerLargeIcons.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACC
GAAAAk1TRnQBSQFMAgEBAgEAAQQBAAEEAQABIAEAASABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAGA
AwABIAMAAQEBAAEgBgABQP8A/wD/AP8A/wD/AKgAAwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
Af8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
Af8DAQH/AwEB/wMBAf8DAQH//wAJAAMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
Af8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
Af8DAQH/AwEB/wMBAf8DAQH/AwEB/xAAA4EB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
AoEB/wEBAoEB/wMBAf//AAEAA4EB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wMBAf8MAAOBAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBAoEB/wMBAf//AAEAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKBAf8DAQH/DAADgQH/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8BAQKBAf8DAQH//wABAAOBBf8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/AQECgQH/AwEB/wgAA4EB/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wMBAf8DAQH//wABAAOBBf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wgA
A4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A8AB/wMBAf8DAQH/
/wABAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
AQECgQH/AwEB/wgAA4EB/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A4EB/wMBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQECgQH/AwEB/wgAA4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/A4EB/wMBAf8DAQH//wABAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/AQECgQH/AwEB/wQAA4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wMBAf8BAQKBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wQAA4EB/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wMBAf8BAQKBAf8DAQH/
/wABAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
AQECgQH/AwEB/wQAA4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
A4EB/wMBAf8BAQKBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wQAA4EB/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A4EB/wMBAf8BAQKBAf8DAQH//wABAAOBBf8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/AQECgQH/AwEB/wOBAf8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8DAQH/A4EB/wEBAoEB/wMBAf//AAEA
A4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKB
Af8DAQH/A4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wMB
Af8DgQH/AQECgQH/AwEB//8AAQADgQX/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wEBAoEB/wMBAf8DgQH/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DgQH/AwEB/wEBA/8BAQKBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wOBAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wOBAf8DAQH/A8AB/wEBAoEB/wMBAf//AAEA
A4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8BAQKB
Af8DAQH/A4Fp/wMBAf8DgQH/AQED/wEBAoEB/wMBAf//AAEAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKBAf8DAQH/BAADgQH/A4EB/wPAAf8DwAH/
A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/
A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8BAQP/A8AB/wEBAoEB/wMBAf//AAEAA4EF/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8BAQKBAf8DAQH/
DAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wEBAoEB/wMBAf//AAEA
A4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKB
Af8DAQH/DAADgQX/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBAoEB/wMB
Af//AAEAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8BAQKBAf8DAQH/DAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wEB
AoEB/wMBAf//AAEAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQKBAf8DAQH/DAADgQX/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
AQED/wPAAf8BAQP/A8AB/wEBL/8DAQH//wAFAAOBdf8BAQKBAf8DAQH/DAADgQX/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8DgQH/A4EB/wOBAf8DgQH/
A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB//8ACQADgQH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/
A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DAQH/FAADgQX/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A4EB//8AOQADgQX/AQED/wPAAf8BAQP/A8AB/wEB
A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A4EB/1QAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/AQED/wPAAf8DgQH//wBBAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/A4EB/1wAA4El/wOBAf//AEkAA4El/wOBAf9kAAOBAf8DgQH/A4EB/wOBAf8DgQH/
A4EB/wOBAf8DgQH/A4EB//8AUQADgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf//AP8A
/wDPAAFCAU0BPgcAAT4DAAEoAwABgAMAASADAAEBAQABAQYAAQIWAAP/AQAI/wgACP8IAAj/CAAE/wHw
AgABAQgAAYACAAEBAeAPAAHgDwAB4A8AAcAPAAHADwABwA8AAcAPAAGADwABgA8AAYAPAAGAXwABgA8A
AeAPAAHgDwAB4A8AAeACAAEBDAAB4AIAAQMLAAEBAfABAAEfAf8IAAGAAQAC/wH4AQABPwH/CAABwAEB
Av8B/AEAAX8B/wgAAeABAwL/Af4BAAL/CAAB8AEHBv8IAAj/CAAL
</value>
</data>
<metadata name="imlExplorerSmallIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>162, 10</value>
</metadata>
<data name="imlExplorerSmallIcons.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADI
BQAAAk1TRnQBSQFMAgEBAgEAAQUBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABEAMAAQEBAAEgBgABEP8A/wAYAAMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
Af8DAQH/AwEB/wMBAf8DAQH/EAADAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/
AwEB/wMBAf8DAQH/gAADgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOB
Af8DgQH/A4EB/wMBAf8MAAOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
A4EB/wMBAf8DAQH/gAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
A/8DgQH/AwEB/wwAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wOBAf8DAQH/
AwEB/4AAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A4EB/wMB
Af8IAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AwEB/wOBAf8DAQH/
gAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DgQH/AwEB/wgA
A4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wOBAf8DAQH/A4EB/wMBAf+AAAOB
Bf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wOBAf8DAQH/BAADgQX/
A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wMBAf8DgQH/A4EB/wMBAf+AAAOB
Bf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wOBAf8DAQH/BAADgSn/
A4EB/wMBAf8DwAH/A4EB/wMBAf+AAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wOBAf8DAQH/BAADgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
A4EB/wOBAf8DgQH/AQED/wOBAf8DAQH/gAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
Af8BAQP/A8AB/wEBA/8DgQH/AwEB/wgAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AB/wEBA/8DwAH/A4EB/wMBAf+AAAOBMf8DgQH/AwEB/wgAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/
A8AV/wOBAf8DAQH/gAADgQH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wOBAf8DgQH/A4EB/wOB
Af8DgQH/A4EB/wwAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAX/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
iAADgQH/AQED/wPAAf8BAQP/A8AB/wEBA/8DgQH/KAADgRX/A4EB/6QAA4EB/wOBAf8DgQH/A4EB/wOB
Af8wAAOBAf8DgQH/A4EB/wOBAf8DgQH//wChAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEBAQABAQUA
AYAXAAP/AQAE/wQABP8EAAGAAQEB4AYAAQEBwAYAAQEBwAYAAQEBgAYAAQEBgAYAAQEHAAEBBwABAQcA
AQEBgAYAAQEBgAYAAQMBgAEBBAABgAH/AcABfwQAAcEB/wHgAf8EAAT/BAAL
</value>
</data>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>37</value>
</metadata>
</root>

View File

@ -0,0 +1,143 @@
// Universal Editor DataFormat for loading SPC2 synthesized audio files
// Copyright (C) 2014 Mike Becker's Software
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversalEditor.DataFormats.Multimedia.Audio.Synthesized.SPC;
using UniversalEditor.IO;
using UniversalEditor.ObjectModels.FileSystem;
using UniversalEditor.ObjectModels.Multimedia.AudioCollection.Synthesized;
namespace UniversalEditor.DataFormats.Multimedia.AudioCollection.Synthesized.SPC2
{
public class SPC2DataFormat : DataFormat
{
private static DataFormatReference _dfr = null;
public override DataFormatReference MakeReference()
{
if (_dfr == null)
{
_dfr = base.MakeReference();
_dfr.Capabilities.Add(typeof(SynthesizedAudioCollectionObjectModel), DataFormatCapabilities.All);
_dfr.ImportOptions.Add(new CustomOptionBoolean("UseID666TagInformationIfAvailable", "Use &ID666 tag information if available"));
_dfr.ExportOptions.Add(new CustomOptionBoolean("IncludeID666TagInformation", "Include &ID666 tag information in output file"));
_dfr.Filters.Add("K.Horton's KSPC/SPC2 audio file", new byte?[][] { new byte?[] { (byte)'K', (byte)'S', (byte)'P', (byte)'C', (byte)0x1A } }, new string[] { "*.kspc" });
_dfr.Sources.Add("http://blog.kevtris.org/blogfiles/spc2_file_specification_v1.txt");
}
return _dfr;
}
private bool mvarUseID666TagInformationIfAvailable = false;
public bool UseID666TagInformationIfAvailable { get { return mvarUseID666TagInformationIfAvailable; } set { mvarUseID666TagInformationIfAvailable = value; } }
protected override void LoadInternal(ref ObjectModel objectModel)
{
SynthesizedAudioCollectionObjectModel coll = (objectModel as SynthesizedAudioCollectionObjectModel);
if (coll == null) throw new ObjectModelNotSupportedException();
Reader reader = base.Accessor.Reader;
string signature = reader.ReadFixedLengthString(4);
byte x1A = reader.ReadByte();
if (signature != "KSPC" || x1A != 0x1A) throw new InvalidDataFormatException("File does not begin with 'KSPC', 0x1A");
byte versionMajor = reader.ReadByte();
byte versionMinor = reader.ReadByte();
ushort fileCount = reader.ReadUInt16();
byte[] expansion = reader.ReadBytes(7);
for (ushort i = 0; i < fileCount; i++)
{
// Each SPC data block has this format
for (int j = 0; j < 256; j++)
{
// Offsets for all 256, 256 byte blocks of data in RAM
ushort dataBlockRAMOffset = reader.ReadUInt16();
}
// DSP register data (as-is from .SPC)
byte[] dspRegisterData = reader.ReadBytes(128);
// IPL ROM (as-is from .SPC)
byte[] iplROM = reader.ReadBytes(64);
// PCL, PCH, A, X, Y, PSW, SP (as-is from .SPC)
byte registerPCL = reader.ReadByte();
byte registerPCH = reader.ReadByte();
byte registerA = reader.ReadByte();
byte registerX = reader.ReadByte();
byte registerY = reader.ReadByte();
byte registerPSW = reader.ReadByte();
byte registerSP = reader.ReadByte();
// channel enable bits, 1 per chan (0 = en, 1 = dis) (as-is)
byte channelEnableBits = reader.ReadByte();
// stored as four bytes, in mm/dd/yyyy as BCD, like so:
// 01h, 12h, 20h, 00h would be 01/12/2000
// 07h, 30h, 19h, 95h would be 07/30/1995
byte[] dateParts = reader.ReadBytes(4);
DateTime date = new DateTime
(
Int32.Parse(dateParts[2].ToString("X").PadLeft(2, '0') + dateParts[3].ToString("X").PadLeft(2, '0')),
Int32.Parse(dateParts[0].ToString("X").PadLeft(2, '0')),
Int32.Parse(dateParts[1].ToString("X").PadLeft(2, '0'))
);
// 1/64000th's to play before fadeout
uint fadeoutDelay = reader.ReadUInt32();
// 1/64000th's to fade to silence
uint fadeoutLength = reader.ReadUInt32();
// amplification value (10000h == 1.00)
uint iAmplificationValue = reader.ReadUInt32();
double amplificationValue = (double)iAmplificationValue * 0.00001;
SPC700Emulator emulator = (SPC700Emulator)reader.ReadByte();
byte ostDisk = reader.ReadByte();
byte ostTrackNumber = reader.ReadByte();
ushort copyrightYear = reader.ReadUInt16();
byte[] unused = reader.ReadBytes(34);
SynthesizedAudioCollectionTrack track = new SynthesizedAudioCollectionTrack();
track.SongTitle = reader.ReadFixedLengthString(32).TrimNull().Trim();
track.GameTitle = reader.ReadFixedLengthString(32).TrimNull().Trim();
track.ArtistName = reader.ReadFixedLengthString(32).TrimNull().Trim();
track.DumperName = reader.ReadFixedLengthString(32).TrimNull().Trim();
track.Comments = reader.ReadFixedLengthString(32).TrimNull().Trim();
track.AlbumTitle = reader.ReadFixedLengthString(32).TrimNull().Trim();
track.PublisherName = reader.ReadFixedLengthString(32).TrimNull().Trim();
track.OriginalFileName = reader.ReadFixedLengthString(28).TrimNull().Trim();
uint extendedDataBlockOffset = reader.ReadUInt32();
}
}
protected override void SaveInternal(ObjectModel objectModel)
{
SynthesizedAudioCollectionObjectModel coll = (objectModel as SynthesizedAudioCollectionObjectModel);
if (coll == null) throw new ObjectModelNotSupportedException();
Writer writer = base.Accessor.Writer;
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank
{
public class Phoneme
{
public class PhonemeCollection
: System.Collections.ObjectModel.Collection<Phoneme>
{
}
private string mvarTitle = String.Empty;
public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank
{
public class PhonemeGroup
{
public class PhonemeGroupCollection
: System.Collections.ObjectModel.Collection<PhonemeGroup>
{
}
private string mvarTitle = String.Empty;
public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
private Phoneme.PhonemeCollection mvarPhonemes = new Phoneme.PhonemeCollection();
public Phoneme.PhonemeCollection Phonemes { get { return mvarPhonemes; } }
}
}

View File

@ -38,6 +38,9 @@ namespace UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank
private string mvarID = string.Empty;
public string ID { get { return mvarID; } set { mvarID = value; } }
private PhonemeGroup.PhonemeGroupCollection mvarPhonemeGroups = new PhonemeGroup.PhonemeGroupCollection();
public PhonemeGroup.PhonemeGroupCollection PhonemeGroups { get { return mvarPhonemeGroups; } }
private VoicebankSynthesisParameters mvarSynthesisParameters = new VoicebankSynthesisParameters();
public VoicebankSynthesisParameters SynthesisParameters { get { return mvarSynthesisParameters; } }

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized;
namespace UniversalEditor.ObjectModels.Multimedia.AudioCollection.Synthesized
{
public class SynthesizedAudioCollectionObjectModel : ObjectModel
{
private static ObjectModelReference _omr = null;
public override ObjectModelReference MakeReference()
{
if (_omr == null)
{
_omr = base.MakeReference();
_omr.Title = "Synthesized audio collection";
}
return _omr;
}
private SynthesizedAudioCollectionTrack.SynthesizedAudioCollectionTrackCollection mvarTracks = new SynthesizedAudioCollectionTrack.SynthesizedAudioCollectionTrackCollection();
public SynthesizedAudioCollectionTrack.SynthesizedAudioCollectionTrackCollection Tracks { get { return mvarTracks; } }
public override void Clear()
{
mvarTracks.Clear();
}
public override void CopyTo(ObjectModel where)
{
SynthesizedAudioCollectionObjectModel clone = (where as SynthesizedAudioCollectionObjectModel);
foreach (SynthesizedAudioCollectionTrack track in mvarTracks)
{
clone.Tracks.Add(track.Clone() as SynthesizedAudioCollectionTrack);
}
}
}
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized;
namespace UniversalEditor.ObjectModels.Multimedia.AudioCollection.Synthesized
{
public class SynthesizedAudioCollectionTrack : ICloneable
{
public class SynthesizedAudioCollectionTrackCollection
: System.Collections.ObjectModel.Collection<SynthesizedAudioCollectionTrack>
{
}
private string mvarSongTitle = String.Empty;
public string SongTitle { get { return mvarSongTitle; } set { mvarSongTitle = value; } }
private string mvarGameTitle = String.Empty;
public string GameTitle { get { return mvarGameTitle; } set { mvarGameTitle = value; } }
private string mvarArtistName = String.Empty;
public string ArtistName { get { return mvarArtistName; } set { mvarArtistName = value; } }
private string mvarDumperName = String.Empty;
public string DumperName { get { return mvarDumperName; } set { mvarDumperName = value; } }
private string mvarComments = String.Empty;
public string Comments { get { return mvarComments; } set { mvarComments = value; } }
private string mvarAlbumTitle = String.Empty;
public string AlbumTitle { get { return mvarAlbumTitle; } set { mvarAlbumTitle = value; } }
private string mvarPublisherName = String.Empty;
public string PublisherName { get { return mvarPublisherName; } set { mvarPublisherName = value; } }
private string mvarOriginalFileName = String.Empty;
public string OriginalFileName { get { return mvarOriginalFileName; } set { mvarOriginalFileName = value; } }
private SynthesizedAudioObjectModel mvarObjectModel = null;
public SynthesizedAudioObjectModel ObjectModel { get { return mvarObjectModel; } }
}
}