mirror of
https://github.com/Gericom/EveryFileExplorer.git
synced 2025-06-18 17:05:33 -04:00
U8 Support, Split ADPCM encoder and decoder, more
Added more names to the sarc hashtable. Fixed firefox bug (was related to using HWND_BROADCAST) More bugfixes
This commit is contained in:
parent
8e64576958
commit
4193ebe25b
26
EveryFileExplorer/Form1.Designer.cs
generated
26
EveryFileExplorer/Form1.Designer.cs
generated
@ -52,6 +52,8 @@
|
||||
this.menuItem6 = new System.Windows.Forms.MenuItem();
|
||||
this.menuTools = new System.Windows.Forms.MenuItem();
|
||||
this.menuCompression = new System.Windows.Forms.MenuItem();
|
||||
this.menuItem9 = new System.Windows.Forms.MenuItem();
|
||||
this.menuEFECmd = new System.Windows.Forms.MenuItem();
|
||||
this.menuItem2 = new System.Windows.Forms.MenuItem();
|
||||
this.menuItemOptions = new System.Windows.Forms.MenuItem();
|
||||
this.menuWindow = new System.Windows.Forms.MenuItem();
|
||||
@ -70,8 +72,6 @@
|
||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||
this.treeView1 = new System.Windows.Forms.TreeView();
|
||||
this.splitter1 = new System.Windows.Forms.Splitter();
|
||||
this.menuEFECmd = new System.Windows.Forms.MenuItem();
|
||||
this.menuItem9 = new System.Windows.Forms.MenuItem();
|
||||
this.panel1.SuspendLayout();
|
||||
this.toolStrip1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
@ -240,6 +240,17 @@
|
||||
this.menuCompression.Index = 0;
|
||||
this.menuCompression.Text = "Compression";
|
||||
//
|
||||
// menuItem9
|
||||
//
|
||||
this.menuItem9.Index = 1;
|
||||
this.menuItem9.Text = "-";
|
||||
//
|
||||
// menuEFECmd
|
||||
//
|
||||
this.menuEFECmd.Index = 2;
|
||||
this.menuEFECmd.Text = "EFE Command Prompt";
|
||||
this.menuEFECmd.Click += new System.EventHandler(this.menuItem1_Click_1);
|
||||
//
|
||||
// menuItem2
|
||||
//
|
||||
this.menuItem2.Index = 3;
|
||||
@ -385,17 +396,6 @@
|
||||
this.splitter1.TabStop = false;
|
||||
this.splitter1.Visible = false;
|
||||
//
|
||||
// menuEFECmd
|
||||
//
|
||||
this.menuEFECmd.Index = 2;
|
||||
this.menuEFECmd.Text = "EFE Command Prompt";
|
||||
this.menuEFECmd.Click += new System.EventHandler(this.menuItem1_Click_1);
|
||||
//
|
||||
// menuItem9
|
||||
//
|
||||
this.menuItem9.Index = 1;
|
||||
this.menuItem9.Text = "-";
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
|
@ -57,7 +57,10 @@ namespace EveryFileExplorer
|
||||
{
|
||||
String arg0 = "";
|
||||
if (Arguments.Length > 0) arg0 = Arguments[0];
|
||||
Win32Util.SendString((IntPtr)Win32Util.HWND_BROADCAST, arg0);
|
||||
foreach (var p in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
|
||||
{
|
||||
if (p != System.Diagnostics.Process.GetCurrentProcess()) Win32Util.SendString(/*(IntPtr)Win32Util.HWND_BROADCAST*/p.MainWindowHandle, arg0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,12 +54,19 @@
|
||||
<DependentUpon>Resource.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="TPL.cs" />
|
||||
<Compile Include="U8.cs" />
|
||||
<Compile Include="UI\BTIViewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="UI\BTIViewer.Designer.cs">
|
||||
<DependentUpon>BTIViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\U8Viewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="UI\U8Viewer.Designer.cs">
|
||||
<DependentUpon>U8Viewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="UI\TPLViewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@ -87,6 +94,9 @@
|
||||
<EmbeddedResource Include="UI\BTIViewer.resx">
|
||||
<DependentUpon>BTIViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="UI\U8Viewer.resx">
|
||||
<DependentUpon>U8Viewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="UI\TPLViewer.resx">
|
||||
<DependentUpon>TPLViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
145
GCNWii/U8.cs
Normal file
145
GCNWii/U8.cs
Normal file
@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibEveryFileExplorer.IO.Serialization;
|
||||
using LibEveryFileExplorer.IO;
|
||||
using System.IO;
|
||||
using LibEveryFileExplorer.Files;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using LibEveryFileExplorer.Files.SimpleFileSystem;
|
||||
using GCNWii.UI;
|
||||
|
||||
namespace GCNWii
|
||||
{
|
||||
public class U8 : FileFormat<U8.U8Identifier>, IViewable
|
||||
{
|
||||
public U8(byte[] Data)
|
||||
{
|
||||
EndianBinaryReaderEx er = new EndianBinaryReaderEx(new MemoryStream(Data), Endianness.BigEndian);
|
||||
try
|
||||
{
|
||||
Header = new U8Header(er);
|
||||
er.BaseStream.Position = Header.FileSystemTableOffset;
|
||||
FileSystemTableEntry root = new FileSystemTableEntry(er);
|
||||
FileSystemTable = new FileSystemTableEntry[root.DataLength];
|
||||
FileSystemTable[0] = root;
|
||||
for (int i = 1; i < root.DataLength; i++) FileSystemTable[i] = new FileSystemTableEntry(er);
|
||||
FileNameTable = new Dictionary<uint,string>();
|
||||
uint offs = 0;
|
||||
for (int i = 0; i < root.DataLength; i++)
|
||||
{
|
||||
String s = er.ReadStringNT(Encoding.ASCII);
|
||||
FileNameTable.Add(offs, s);
|
||||
offs += (uint)s.Length + 1;
|
||||
}
|
||||
er.BaseStream.Position = Header.FileDataOffset;
|
||||
this.Data = er.ReadBytes((int)(er.BaseStream.Length - Header.FileDataOffset));
|
||||
}
|
||||
finally
|
||||
{
|
||||
er.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public Form GetDialog()
|
||||
{
|
||||
return new U8Viewer(this);
|
||||
}
|
||||
|
||||
public U8Header Header;
|
||||
public class U8Header
|
||||
{
|
||||
public U8Header(EndianBinaryReaderEx er)
|
||||
{
|
||||
er.ReadObject(this);
|
||||
}
|
||||
[BinaryByteArraySignature(0x55, 0xAA, 0x38, 0x2D)]
|
||||
[BinaryFixedSize(4)]
|
||||
public byte[] Signature;
|
||||
public UInt32 FileSystemTableOffset;
|
||||
public UInt32 FileSystemTableLength;
|
||||
public UInt32 FileDataOffset;
|
||||
[BinaryFixedSize(16)]
|
||||
public Byte[] Padding;
|
||||
}
|
||||
|
||||
public FileSystemTableEntry[] FileSystemTable;
|
||||
public class FileSystemTableEntry
|
||||
{
|
||||
public FileSystemTableEntry(EndianBinaryReader er)
|
||||
{
|
||||
NameOffset = er.ReadUInt32();
|
||||
IsFolder = (NameOffset >> 24) == 1;
|
||||
NameOffset &= 0xFFFFFF;
|
||||
DataOffset = er.ReadUInt32();
|
||||
DataLength = er.ReadUInt32();
|
||||
}
|
||||
public UInt32 NameOffset;
|
||||
public Boolean IsFolder;
|
||||
public UInt32 DataOffset;//Parent Entry Index if folder
|
||||
public UInt32 DataLength;//Nr Files if folder
|
||||
}
|
||||
public Dictionary<UInt32, String> FileNameTable;
|
||||
|
||||
public byte[] Data;
|
||||
|
||||
public SFSDirectory ToFileSystem()
|
||||
{
|
||||
SFSDirectory[] dirs = new SFSDirectory[FileSystemTable.Length];
|
||||
dirs[1] = new SFSDirectory("/", true);
|
||||
var curdir = dirs[1];
|
||||
for (int i = 2; i < FileSystemTable.Length; i++)
|
||||
{
|
||||
if (FileSystemTable[i].IsFolder)
|
||||
{
|
||||
var folder = new SFSDirectory(FileNameTable[FileSystemTable[i].NameOffset], false);
|
||||
dirs[i] = folder;
|
||||
folder.Parent = dirs[FileSystemTable[i].DataOffset];
|
||||
dirs[FileSystemTable[i].DataOffset].SubDirectories.Add(folder);
|
||||
curdir = folder;
|
||||
}
|
||||
else
|
||||
{
|
||||
var file = new SFSFile(-1, FileNameTable[FileSystemTable[i].NameOffset], curdir);
|
||||
byte[] data = new byte[FileSystemTable[i].DataLength];
|
||||
Array.Copy(Data, FileSystemTable[i].DataOffset - Header.FileDataOffset, data, 0, FileSystemTable[i].DataLength);
|
||||
file.Data = data;
|
||||
curdir.Files.Add(file);
|
||||
}
|
||||
}
|
||||
return dirs[1];
|
||||
}
|
||||
|
||||
public class U8Identifier : FileFormatIdentifier
|
||||
{
|
||||
public override string GetCategory()
|
||||
{
|
||||
return Category_Archives;
|
||||
}
|
||||
|
||||
public override string GetFileDescription()
|
||||
{
|
||||
return "U8 Archive";
|
||||
}
|
||||
|
||||
public override string GetFileFilter()
|
||||
{
|
||||
return "U8 Archive (*.arc, *.szs)|*.arc;*.szs";
|
||||
}
|
||||
|
||||
public override Bitmap GetIcon()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override FormatMatch IsFormat(EFEFile File)
|
||||
{
|
||||
if (File.Data.Length > 4 && File.Data[0] == 0x55 && File.Data[1] == 0xAA && File.Data[2] == 0x38 && File.Data[3] == 0x2D) return FormatMatch.Content;
|
||||
return FormatMatch.No;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
151
GCNWii/UI/U8Viewer.Designer.cs
generated
Normal file
151
GCNWii/UI/U8Viewer.Designer.cs
generated
Normal file
@ -0,0 +1,151 @@
|
||||
namespace GCNWii.UI
|
||||
{
|
||||
partial class U8Viewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(U8Viewer));
|
||||
this.mainMenu1 = new LibEveryFileExplorer.UI.MainMenu(this.components);
|
||||
this.menuItem1 = new System.Windows.Forms.MenuItem();
|
||||
this.menuExport = new System.Windows.Forms.MenuItem();
|
||||
this.menuItem2 = new System.Windows.Forms.MenuItem();
|
||||
this.menuItem3 = new System.Windows.Forms.MenuItem();
|
||||
this.menuExportDir = new System.Windows.Forms.MenuItem();
|
||||
this.fileBrowser1 = new LibEveryFileExplorer.UI.FileBrowser();
|
||||
this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
|
||||
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
|
||||
this.menuItem4 = new System.Windows.Forms.MenuItem();
|
||||
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// mainMenu1
|
||||
//
|
||||
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuItem1,
|
||||
this.menuItem2});
|
||||
//
|
||||
// menuItem1
|
||||
//
|
||||
this.menuItem1.Index = 0;
|
||||
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuExport});
|
||||
this.menuItem1.MergeOrder = 1;
|
||||
this.menuItem1.MergeType = System.Windows.Forms.MenuMerge.MergeItems;
|
||||
this.menuItem1.Text = "Edit";
|
||||
//
|
||||
// menuExport
|
||||
//
|
||||
this.menuExport.Enabled = false;
|
||||
this.menuExport.Index = 0;
|
||||
this.menuExport.Text = "Export...";
|
||||
this.menuExport.Click += new System.EventHandler(this.OnExport);
|
||||
//
|
||||
// menuItem2
|
||||
//
|
||||
this.menuItem2.Index = 1;
|
||||
this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuItem3,
|
||||
this.menuExportDir});
|
||||
this.menuItem2.MergeOrder = 3;
|
||||
this.menuItem2.MergeType = System.Windows.Forms.MenuMerge.MergeItems;
|
||||
this.menuItem2.Text = "Tools";
|
||||
//
|
||||
// menuItem3
|
||||
//
|
||||
this.menuItem3.Index = 0;
|
||||
this.menuItem3.Text = "-";
|
||||
//
|
||||
// menuExportDir
|
||||
//
|
||||
this.menuExportDir.Index = 1;
|
||||
this.menuExportDir.Text = "Export Directory Content...";
|
||||
this.menuExportDir.Click += new System.EventHandler(this.menuExportDir_Click);
|
||||
//
|
||||
// fileBrowser1
|
||||
//
|
||||
this.fileBrowser1.DeleteEnabled = true;
|
||||
this.fileBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.fileBrowser1.Location = new System.Drawing.Point(0, 0);
|
||||
this.fileBrowser1.Name = "fileBrowser1";
|
||||
this.fileBrowser1.RenameEnabled = true;
|
||||
this.fileBrowser1.ShowAddDirectoryButton = false;
|
||||
this.fileBrowser1.ShowAddFileButton = false;
|
||||
this.fileBrowser1.ShowDeleteButton = false;
|
||||
this.fileBrowser1.ShowRenameButton = false;
|
||||
this.fileBrowser1.Size = new System.Drawing.Size(652, 338);
|
||||
this.fileBrowser1.TabIndex = 0;
|
||||
this.fileBrowser1.OnDirectoryChanged += new LibEveryFileExplorer.UI.FileBrowser.OnDirectoryChangedEventHandler(this.fileBrowser1_OnDirectoryChanged);
|
||||
this.fileBrowser1.OnFileActivated += new LibEveryFileExplorer.UI.FileBrowser.OnFileActivatedEventHandler(this.fileBrowser1_OnFileActivated);
|
||||
this.fileBrowser1.OnSelectionChanged += new System.EventHandler(this.fileBrowser1_OnSelectionChanged);
|
||||
this.fileBrowser1.OnRightClick += new LibEveryFileExplorer.UI.FileBrowser.OnRightClickEventHandler(this.fileBrowser1_OnRightClick);
|
||||
//
|
||||
// contextMenu1
|
||||
//
|
||||
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||
this.menuItem4});
|
||||
//
|
||||
// menuItem4
|
||||
//
|
||||
this.menuItem4.Index = 0;
|
||||
this.menuItem4.Text = "Export...";
|
||||
this.menuItem4.Click += new System.EventHandler(this.OnExport);
|
||||
//
|
||||
// folderBrowserDialog1
|
||||
//
|
||||
this.folderBrowserDialog1.Description = "Select the directory to export the content of current directory to.";
|
||||
//
|
||||
// DARCViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(652, 338);
|
||||
this.Controls.Add(this.fileBrowser1);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Menu = this.mainMenu1;
|
||||
this.Name = "DARCViewer";
|
||||
this.Text = "DARC Viewer";
|
||||
this.Load += new System.EventHandler(this.SARCViewer_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private LibEveryFileExplorer.UI.MainMenu mainMenu1;
|
||||
private System.Windows.Forms.MenuItem menuItem1;
|
||||
private System.Windows.Forms.MenuItem menuItem2;
|
||||
private LibEveryFileExplorer.UI.FileBrowser fileBrowser1;
|
||||
private System.Windows.Forms.MenuItem menuExport;
|
||||
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
|
||||
private System.Windows.Forms.ContextMenu contextMenu1;
|
||||
private System.Windows.Forms.MenuItem menuItem4;
|
||||
private System.Windows.Forms.MenuItem menuItem3;
|
||||
private System.Windows.Forms.MenuItem menuExportDir;
|
||||
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
|
||||
}
|
||||
}
|
85
GCNWii/UI/U8Viewer.cs
Normal file
85
GCNWii/UI/U8Viewer.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using LibEveryFileExplorer.Files.SimpleFileSystem;
|
||||
using LibEveryFileExplorer.Files;
|
||||
using LibEveryFileExplorer;
|
||||
|
||||
namespace GCNWii.UI
|
||||
{
|
||||
public partial class U8Viewer : Form
|
||||
{
|
||||
U8 Archive;
|
||||
SFSDirectory Root;
|
||||
public U8Viewer(U8 Archive)
|
||||
{
|
||||
Root = Archive.ToFileSystem();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void SARCViewer_Load(object sender, EventArgs e)
|
||||
{
|
||||
fileBrowser1.UpdateDirectories(Root.GetTreeNodes());
|
||||
}
|
||||
|
||||
private void fileBrowser1_OnDirectoryChanged(string Path)
|
||||
{
|
||||
var d = Root.GetDirectoryByPath(Path);
|
||||
fileBrowser1.UpdateContent(d.GetContent());
|
||||
}
|
||||
|
||||
private void fileBrowser1_OnFileActivated(string Path)
|
||||
{
|
||||
var s = Root.GetFileByPath(Path);
|
||||
EveryFileExplorerUtil.OpenFile(new EFESFSFile(s), ((ViewableFile)Tag).File);
|
||||
}
|
||||
|
||||
private void OnExport(object sender, EventArgs e)
|
||||
{
|
||||
var file = Root.GetFileByPath(fileBrowser1.SelectedPath);
|
||||
if (file == null) return;
|
||||
saveFileDialog1.Filter = System.IO.Path.GetExtension(fileBrowser1.SelectedPath).Replace(".", "").ToUpper() + " Files (*" + System.IO.Path.GetExtension(fileBrowser1.SelectedPath).ToLower() + ")|*" + System.IO.Path.GetExtension(fileBrowser1.SelectedPath).ToLower() + "|All Files (*.*)|*.*";
|
||||
saveFileDialog1.FileName = System.IO.Path.GetFileName(fileBrowser1.SelectedPath);
|
||||
if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
|
||||
&& saveFileDialog1.FileName.Length > 0)
|
||||
{
|
||||
System.IO.File.Create(saveFileDialog1.FileName).Close();
|
||||
System.IO.File.WriteAllBytes(saveFileDialog1.FileName, file.Data);
|
||||
}
|
||||
}
|
||||
|
||||
private void fileBrowser1_OnSelectionChanged(object sender, EventArgs e)
|
||||
{
|
||||
menuExport.Enabled = !(fileBrowser1.SelectedPath == fileBrowser1.SelectedFolderPath);
|
||||
}
|
||||
|
||||
private void fileBrowser1_OnRightClick(Point Location)
|
||||
{
|
||||
var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedPath);
|
||||
if (dir != null)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//var file = Root.GetFileByPath(fileBrowser1.SelectedPath);
|
||||
contextMenu1.Show(fileBrowser1, Location);
|
||||
}
|
||||
}
|
||||
|
||||
private void menuExportDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
var dir = Root.GetDirectoryByPath(fileBrowser1.SelectedFolderPath);
|
||||
if (folderBrowserDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK
|
||||
&& folderBrowserDialog1.SelectedPath.Length > 0)
|
||||
{
|
||||
dir.Export(folderBrowserDialog1.SelectedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
157
GCNWii/UI/U8Viewer.resx
Normal file
157
GCNWii/UI/U8Viewer.resx
Normal file
@ -0,0 +1,157 @@
|
||||
<?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="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>134, 17</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>270, 17</value>
|
||||
</metadata>
|
||||
<metadata name="folderBrowserDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>400, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAADwAAABcAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAA
|
||||
ABoAAAAXAAAADwAAAB4BM2aeAUSHxQFEh8UBRIfFAUSHxQFEh8UBRIfFAUSHxQFEh8UBRIfFAUSHxQFE
|
||||
h8UBRIfFATNmngAAAB4AAAAAAUqUuHuu4P96rd//eq3f/3qt3/96rd//eq3f/3qt3/96rd//eq3f/3qt
|
||||
3/96rd//e67g/wFKlLgAAAAAAAAAAAJRoKuBtOT/fbDh/32w4f99sOH/fbDh/2yf0P9ajb//Wo2//1qN
|
||||
v/9ajb//Wo2//3Cj0/8CUaCrAAAAAAAAAAACVKSmiLvq/4K15f+CteX/grXl/4K15f9jlsf/4uLR/+Li
|
||||
0f/i4tH/4uLR/+Li0f9pnMv/AlSkpgAAAAAAAAAAA1aoo4/C7v+Huun/h7rp/4e66f+Huun/cKPT/+zs
|
||||
2/+6uqn/0NC//83NvP/s7Nv/eKvY/wNWqKMAAAAAAAAAAANYrJ+WyfL/jL/s/4y/7P+Mv+z/RHeq/0J1
|
||||
qP/19eT/9fXk//X15P/19eT/9fXk/4i75f8DWKyfAAAAAAAAAAADWrCbm872/5HE8P+RxPD/kcTw/1WI
|
||||
u/9Uh7r//8tD//zFPf/4vTX/87Ut//CuJv+WyfL/A1qwmwAAAAAAAAAAA1uzmJ/S+f+VyPP/lcjz/5XI
|
||||
8/9ViLv/VYi7/1WIu/9NgLP/lcjz/5XI8/+VyPP/n9L5/wNbs5gAAAAAAAAAAANdtpWn2/79qt3//6rd
|
||||
//+q3f//d6rd/3eq3f93qt3/ZpnM/6rd//+q3f//qt3//6fb/v0DXbaVAAAAAAAAAAAEX7lta6bf4ICz
|
||||
5v+As+b/gLPm/06BtP9OgbT/ToG0/0h7rv+As+b/gLPm/4Cz5v9rpt/gBF+5bQAAAAAAAAAABGC8R02U
|
||||
2cSJvO//iLvu/4i77v9BdKf/QXSn/0F0p/8+caT/iLvu/4i77v+JvO//TZTZxARgvEcAAAAAAAAAAARh
|
||||
viMqfMylibzv/4i77v+Iu+7/NWib/zVom/81aJv/NWib/4i77v+Iu+7/ibzv/yp8zKUEYb4jAAAAAAAA
|
||||
AAAEYr8EBGLAaARiwIsEYsCLBGLAiwBAgMwAQIDMAECAzABAgMwEYsCLBGLAiwRiwIsEYsBoBGK/BAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA//8AAAAAAAAAAAAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
|
||||
AACAAQAA//8AAA==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
@ -41,7 +41,7 @@ namespace LegoPirates.UI
|
||||
//TODO: Calculate timing based on fps
|
||||
if ((Video.Header.Flags & 4) == 4)
|
||||
{
|
||||
AudioConverter = new ADPCM();
|
||||
AudioConverter = new IMAADPCMDecoder();
|
||||
AudioBuffer = new NAudio.Wave.BufferedWaveProvider(new NAudio.Wave.WaveFormat((int)Video.Header.AudioRate, 16, 1));
|
||||
AudioBuffer.DiscardOnBufferOverflow = true;
|
||||
AudioBuffer.BufferLength = 8192 * 16;
|
||||
@ -72,7 +72,7 @@ namespace LegoPirates.UI
|
||||
backgroundWorker1.RunWorkerAsync();
|
||||
}
|
||||
|
||||
ADPCM AudioConverter = null;
|
||||
IMAADPCMDecoder AudioConverter = null;
|
||||
|
||||
int aa = 0;
|
||||
int bb = 0;
|
||||
|
@ -238,7 +238,7 @@ namespace LibEveryFileExplorer.IO
|
||||
byte[] bsig = GetAttributeValue<byte[]>(f, typeof(BinaryByteArraySignatureAttribute), null);
|
||||
if (bsig != null && Result is byte[])
|
||||
{
|
||||
if (!bsig.Equals(Result)) throw new SignatureNotCorrectException("{ " + BitConverter.ToString((byte[])Result, 0, ((byte[])Result).Length).Replace("-", ", ") + " }", "{ " + BitConverter.ToString(bsig, 0, bsig.Length).Replace("-", ", ") + " }", BaseStream.Position - ((byte[])Result).Length);
|
||||
if (!bsig.SequenceEqual((byte[])Result)) throw new SignatureNotCorrectException("{ " + BitConverter.ToString((byte[])Result, 0, ((byte[])Result).Length).Replace("-", ", ") + " }", "{ " + BitConverter.ToString(bsig, 0, bsig.Length).Replace("-", ", ") + " }", BaseStream.Position - ((byte[])Result).Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Binary file not shown.
@ -78,7 +78,9 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resource.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SND\ADPCM.cs" />
|
||||
<Compile Include="SND\IMAADPCMDecoder.cs" />
|
||||
<Compile Include="SND\IMAADPCMConst.cs" />
|
||||
<Compile Include="SND\IMAADPCMEncoder.cs" />
|
||||
<Compile Include="UI\NDSProjectDialog.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
153
NDS/SND/ADPCM.cs
153
NDS/SND/ADPCM.cs
@ -1,153 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibEveryFileExplorer.IO;
|
||||
using LibEveryFileExplorer.Math;
|
||||
|
||||
namespace NDS.SND
|
||||
{
|
||||
public class ADPCM
|
||||
{
|
||||
private static int[] IndexTable =
|
||||
{
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
-1, -1, -1, -1, 2, 4, 6, 8
|
||||
};
|
||||
|
||||
private static int[] StepTable =
|
||||
{
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
16, 17, 19, 21, 23, 25, 28,
|
||||
31, 34, 37, 41, 45, 50, 55,
|
||||
60, 66, 73, 80, 88, 97, 107,
|
||||
118, 130, 143, 157, 173, 190, 209,
|
||||
230, 253, 279, 307, 337, 371, 408,
|
||||
449, 494, 544, 598, 658, 724, 796,
|
||||
876, 963, 1060, 1166, 1282, 1411, 1552,
|
||||
1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,
|
||||
4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
|
||||
9493, 10442, 11487, 12635, 13899, 15289, 16818,
|
||||
18500, 20350, 22385, 24623, 27086, 29794, 32767
|
||||
};
|
||||
|
||||
private bool IsInit = false;
|
||||
private int Last;
|
||||
private int Index;
|
||||
|
||||
public ADPCM() { }
|
||||
|
||||
public Int16[] GetWaveData(byte[] Data, int Offset, int Length)
|
||||
{
|
||||
List<Int16> DataOut = new List<short>();
|
||||
if (!IsInit)
|
||||
{
|
||||
Last = IOUtil.ReadS16LE(Data, Offset);
|
||||
Index = IOUtil.ReadS16LE(Data, Offset + 2) & 0x7F;
|
||||
Offset += 4;
|
||||
Length -= 4;
|
||||
DataOut.Add((short)Last);
|
||||
IsInit = true;
|
||||
}
|
||||
int end = Offset + Length;
|
||||
while (Offset < end)
|
||||
{
|
||||
byte sampd = Data[Offset++];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
int val = (sampd >> (i * 4)) & 0xF;
|
||||
|
||||
int diff =
|
||||
StepTable[Index] / 8 +
|
||||
StepTable[Index] / 4 * ((val >> 0) & 1) +
|
||||
StepTable[Index] / 2 * ((val >> 1) & 1) +
|
||||
StepTable[Index] * ((val >> 2) & 1);
|
||||
|
||||
int samp = Last + diff * ((((val >> 3) & 1) == 1) ? -1 : 1);
|
||||
Last = (short)MathUtil.Clamp(samp, short.MinValue, short.MaxValue);
|
||||
Index = (short)MathUtil.Clamp(Index + IndexTable[val & 7], 0, 88);
|
||||
DataOut.Add((short)Last);
|
||||
}
|
||||
}
|
||||
return DataOut.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] Encode(Int16[] WaveData)
|
||||
{
|
||||
int Last = WaveData[0];
|
||||
int Index = GetBestTableIndex((WaveData[1] - WaveData[0]) * 8);
|
||||
int HeaderIndex = Index;
|
||||
byte[] Nibbles = new byte[WaveData.Length - 1];//nibbles, lets merge it afterwards
|
||||
for (int i = 1; i < WaveData.Length; i++)
|
||||
{
|
||||
int val = GetBestConfig(Index, WaveData[i] - Last);
|
||||
Nibbles[i - 1] = (byte)val;
|
||||
|
||||
int diff =
|
||||
StepTable[Index] / 8 +
|
||||
StepTable[Index] / 4 * ((val >> 0) & 1) +
|
||||
StepTable[Index] / 2 * ((val >> 1) & 1) +
|
||||
StepTable[Index] * ((val >> 2) & 1);
|
||||
|
||||
int samp = Last + diff * ((((val >> 3) & 1) == 1) ? -1 : 1);
|
||||
Last = (short)MathUtil.Clamp(samp, short.MinValue, short.MaxValue);
|
||||
Index = (short)MathUtil.Clamp(Index + IndexTable[val & 7], 0, 88);
|
||||
}
|
||||
byte[] Result = new byte[WaveData.Length / 2 + 4];
|
||||
IOUtil.WriteS16LE(Result, 0, WaveData[0]);
|
||||
IOUtil.WriteS16LE(Result, 2, (short)HeaderIndex);
|
||||
for (int i = 0; i < Nibbles.Length; i += 2)
|
||||
{
|
||||
if (i == Nibbles.Length - 1)
|
||||
{
|
||||
Result[i / 2 + 4] = (byte)(Nibbles[i]);//(Nibbles[i + 1] << 4));
|
||||
}
|
||||
else Result[i / 2 + 4] = (byte)(Nibbles[i] | (Nibbles[i + 1] << 4));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
private static int GetBestTableIndex(int Diff)
|
||||
{
|
||||
int LowestDiff = int.MaxValue;
|
||||
int LowestIdx = -1;
|
||||
for (int i = 0; i < StepTable.Length; i++)
|
||||
{
|
||||
int diff2 = Math.Abs(Math.Abs(Diff) - StepTable[i]);
|
||||
if (diff2 < LowestDiff)
|
||||
{
|
||||
LowestDiff = diff2;
|
||||
LowestIdx = i;
|
||||
}
|
||||
}
|
||||
return LowestIdx;
|
||||
}
|
||||
|
||||
private static int GetBestConfig(int Index, int Diff)
|
||||
{
|
||||
int Result = 0;
|
||||
if (Diff < 0) Result |= 1 << 3;
|
||||
Diff = Math.Abs(Diff);
|
||||
int DiffNew = StepTable[Index] / 8;
|
||||
|
||||
if (Math.Abs(DiffNew - Diff) >= StepTable[Index])
|
||||
{
|
||||
Result |= 1 << 2;
|
||||
DiffNew += StepTable[Index];
|
||||
}
|
||||
|
||||
if (Math.Abs(DiffNew - Diff) >= StepTable[Index] / 2)
|
||||
{
|
||||
Result |= 1 << 1;
|
||||
DiffNew += StepTable[Index] / 2;
|
||||
}
|
||||
|
||||
if (Math.Abs(DiffNew - Diff) >= StepTable[Index] / 4)
|
||||
{
|
||||
Result |= 1;
|
||||
DiffNew += StepTable[Index] / 4;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
}
|
32
NDS/SND/IMAADPCMConst.cs
Normal file
32
NDS/SND/IMAADPCMConst.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NDS.SND
|
||||
{
|
||||
public class IMAADPCMConst
|
||||
{
|
||||
public static readonly int[] IndexTable =
|
||||
{
|
||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||
-1, -1, -1, -1, 2, 4, 6, 8
|
||||
};
|
||||
|
||||
public static readonly int[] StepTable =
|
||||
{
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
16, 17, 19, 21, 23, 25, 28,
|
||||
31, 34, 37, 41, 45, 50, 55,
|
||||
60, 66, 73, 80, 88, 97, 107,
|
||||
118, 130, 143, 157, 173, 190, 209,
|
||||
230, 253, 279, 307, 337, 371, 408,
|
||||
449, 494, 544, 598, 658, 724, 796,
|
||||
876, 963, 1060, 1166, 1282, 1411, 1552,
|
||||
1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026,
|
||||
4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
|
||||
9493, 10442, 11487, 12635, 13899, 15289, 16818,
|
||||
18500, 20350, 22385, 24623, 27086, 29794, 32767
|
||||
};
|
||||
}
|
||||
}
|
53
NDS/SND/IMAADPCMDecoder.cs
Normal file
53
NDS/SND/IMAADPCMDecoder.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibEveryFileExplorer.IO;
|
||||
using LibEveryFileExplorer.Math;
|
||||
|
||||
namespace NDS.SND
|
||||
{
|
||||
public class IMAADPCMDecoder
|
||||
{
|
||||
private bool IsInit = false;
|
||||
private int Last;
|
||||
private int Index;
|
||||
|
||||
public IMAADPCMDecoder() { }
|
||||
|
||||
public Int16[] GetWaveData(byte[] Data, int Offset, int Length)
|
||||
{
|
||||
List<Int16> DataOut = new List<short>();
|
||||
if (!IsInit)
|
||||
{
|
||||
Last = IOUtil.ReadS16LE(Data, Offset);
|
||||
Index = IOUtil.ReadS16LE(Data, Offset + 2) & 0x7F;
|
||||
Offset += 4;
|
||||
Length -= 4;
|
||||
DataOut.Add((short)Last);
|
||||
IsInit = true;
|
||||
}
|
||||
int end = Offset + Length;
|
||||
while (Offset < end)
|
||||
{
|
||||
byte sampd = Data[Offset++];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
int val = (sampd >> (i * 4)) & 0xF;
|
||||
|
||||
int diff =
|
||||
IMAADPCMConst.StepTable[Index] / 8 +
|
||||
IMAADPCMConst.StepTable[Index] / 4 * ((val >> 0) & 1) +
|
||||
IMAADPCMConst.StepTable[Index] / 2 * ((val >> 1) & 1) +
|
||||
IMAADPCMConst.StepTable[Index] * ((val >> 2) & 1);
|
||||
|
||||
int samp = Last + diff * ((((val >> 3) & 1) == 1) ? -1 : 1);
|
||||
Last = (short)MathUtil.Clamp(samp, short.MinValue, short.MaxValue);
|
||||
Index = (short)MathUtil.Clamp(Index + IMAADPCMConst.IndexTable[val & 7], 0, 88);
|
||||
DataOut.Add((short)Last);
|
||||
}
|
||||
}
|
||||
return DataOut.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
103
NDS/SND/IMAADPCMEncoder.cs
Normal file
103
NDS/SND/IMAADPCMEncoder.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using LibEveryFileExplorer.IO;
|
||||
using LibEveryFileExplorer.Math;
|
||||
|
||||
namespace NDS.SND
|
||||
{
|
||||
public class IMAADPCMEncoder
|
||||
{
|
||||
public IMAADPCMEncoder() { }
|
||||
|
||||
private bool IsInit = false;
|
||||
private int Last;
|
||||
private int Index;
|
||||
|
||||
public byte[] Encode(Int16[] WaveData)
|
||||
{
|
||||
List<byte> Result = new List<byte>();
|
||||
int Offset = 0;
|
||||
if (!IsInit)
|
||||
{
|
||||
Last = WaveData[0];
|
||||
Index = GetBestTableIndex((WaveData[1] - WaveData[0]) * 8);
|
||||
byte[] Header = new byte[4];
|
||||
IOUtil.WriteS16LE(Header, 0, WaveData[0]);
|
||||
IOUtil.WriteS16LE(Header, 2, (short)Index);
|
||||
Result.AddRange(Header);
|
||||
Offset++;
|
||||
IsInit = true;
|
||||
}
|
||||
byte[] Nibbles = new byte[WaveData.Length - Offset];//nibbles, lets merge it afterwards
|
||||
for (int i = Offset; i < WaveData.Length; i++)
|
||||
{
|
||||
int val = GetBestConfig(Index, WaveData[i] - Last);
|
||||
Nibbles[i - Offset] = (byte)val;
|
||||
|
||||
int diff =
|
||||
IMAADPCMConst.StepTable[Index] / 8 +
|
||||
IMAADPCMConst.StepTable[Index] / 4 * ((val >> 0) & 1) +
|
||||
IMAADPCMConst.StepTable[Index] / 2 * ((val >> 1) & 1) +
|
||||
IMAADPCMConst.StepTable[Index] * ((val >> 2) & 1);
|
||||
|
||||
int samp = Last + diff * ((((val >> 3) & 1) == 1) ? -1 : 1);
|
||||
Last = (short)MathUtil.Clamp(samp, short.MinValue, short.MaxValue);
|
||||
Index = (short)MathUtil.Clamp(Index + IMAADPCMConst.IndexTable[val & 7], 0, 88);
|
||||
}
|
||||
for (int i = 0; i < Nibbles.Length; i += 2)
|
||||
{
|
||||
if (i == Nibbles.Length - 1)
|
||||
{
|
||||
Result.Add((byte)(Nibbles[i]));
|
||||
}
|
||||
else Result.Add((byte)(Nibbles[i] | (Nibbles[i + 1] << 4)));
|
||||
}
|
||||
return Result.ToArray();
|
||||
}
|
||||
|
||||
private int GetBestTableIndex(int Diff)
|
||||
{
|
||||
int LowestDiff = int.MaxValue;
|
||||
int LowestIdx = -1;
|
||||
for (int i = 0; i < IMAADPCMConst.StepTable.Length; i++)
|
||||
{
|
||||
int diff2 = Math.Abs(Math.Abs(Diff) - IMAADPCMConst.StepTable[i]);
|
||||
if (diff2 < LowestDiff)
|
||||
{
|
||||
LowestDiff = diff2;
|
||||
LowestIdx = i;
|
||||
}
|
||||
}
|
||||
return LowestIdx;
|
||||
}
|
||||
|
||||
private int GetBestConfig(int Index, int Diff)
|
||||
{
|
||||
int Result = 0;
|
||||
if (Diff < 0) Result |= 1 << 3;
|
||||
Diff = Math.Abs(Diff);
|
||||
int DiffNew = IMAADPCMConst.StepTable[Index] / 8;
|
||||
|
||||
if (Math.Abs(DiffNew - Diff) >= IMAADPCMConst.StepTable[Index])
|
||||
{
|
||||
Result |= 1 << 2;
|
||||
DiffNew += IMAADPCMConst.StepTable[Index];
|
||||
}
|
||||
|
||||
if (Math.Abs(DiffNew - Diff) >= IMAADPCMConst.StepTable[Index] / 2)
|
||||
{
|
||||
Result |= 1 << 1;
|
||||
DiffNew += IMAADPCMConst.StepTable[Index] / 2;
|
||||
}
|
||||
|
||||
if (Math.Abs(DiffNew - Diff) >= IMAADPCMConst.StepTable[Index] / 4)
|
||||
{
|
||||
Result |= 1;
|
||||
DiffNew += IMAADPCMConst.StepTable[Index] / 4;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user