diff --git a/DotNetCTFDumper/DotNetCTFDumper.csproj b/DotNetCTFDumper/DotNetCTFDumper.csproj
index 42c12a0..1de74f2 100644
--- a/DotNetCTFDumper/DotNetCTFDumper.csproj
+++ b/DotNetCTFDumper/DotNetCTFDumper.csproj
@@ -229,6 +229,7 @@
+
diff --git a/DotNetCTFDumper/GUI/MainForm.Designer.cs b/DotNetCTFDumper/GUI/MainForm.Designer.cs
index 58e4c82..44c8dbe 100644
--- a/DotNetCTFDumper/GUI/MainForm.Designer.cs
+++ b/DotNetCTFDumper/GUI/MainForm.Designer.cs
@@ -68,11 +68,14 @@
this.plusCharBtn = new System.Windows.Forms.Button();
this.hexBox1 = new Be.Windows.Forms.HexBox();
this.charBox = new System.Windows.Forms.TextBox();
- this.advDumpTab = new System.Windows.Forms.TabPage();
- this.advancedInfoLabel = new System.Windows.Forms.Label();
- this.advancedPlayAnimation = new System.Windows.Forms.Button();
- this.advancedPictureBox = new System.Windows.Forms.PictureBox();
- this.advancedTreeView = new System.Windows.Forms.TreeView();
+ this.imgViewerTab = new System.Windows.Forms.TabPage();
+ this.imageViewerInfo = new System.Windows.Forms.Label();
+ this.imageViewerPlayAnim = new System.Windows.Forms.Button();
+ this.imageViewPictureBox = new System.Windows.Forms.PictureBox();
+ this.imagesTreeView = new System.Windows.Forms.TreeView();
+ this.soundViewTab = new System.Windows.Forms.TabPage();
+ this.soundList = new System.Windows.Forms.TreeView();
+ this.playSoundBtn = new System.Windows.Forms.Button();
this.pluginTab = new System.Windows.Forms.TabPage();
this.pluginLogBox = new System.Windows.Forms.TextBox();
this.activatePluginBtn = new System.Windows.Forms.Button();
@@ -84,8 +87,9 @@
this.mfaTab.SuspendLayout();
this.packDataTab.SuspendLayout();
this.cryptKeyTab.SuspendLayout();
- this.advDumpTab.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize) (this.advancedPictureBox)).BeginInit();
+ this.imgViewerTab.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize) (this.imageViewPictureBox)).BeginInit();
+ this.soundViewTab.SuspendLayout();
this.pluginTab.SuspendLayout();
this.SuspendLayout();
//
@@ -386,7 +390,8 @@
this.tabControl1.Controls.Add(this.mfaTab);
this.tabControl1.Controls.Add(this.packDataTab);
this.tabControl1.Controls.Add(this.cryptKeyTab);
- this.tabControl1.Controls.Add(this.advDumpTab);
+ this.tabControl1.Controls.Add(this.imgViewerTab);
+ this.tabControl1.Controls.Add(this.soundViewTab);
this.tabControl1.Controls.Add(this.pluginTab);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (204)));
@@ -590,61 +595,91 @@
this.charBox.Text = "54";
this.charBox.TextChanged += new System.EventHandler(this.charBox_TextChanged);
//
- // advDumpTab
- //
- this.advDumpTab.BackColor = System.Drawing.Color.DimGray;
- this.advDumpTab.Controls.Add(this.advancedInfoLabel);
- this.advDumpTab.Controls.Add(this.advancedPlayAnimation);
- this.advDumpTab.Controls.Add(this.advancedPictureBox);
- this.advDumpTab.Controls.Add(this.advancedTreeView);
- this.advDumpTab.ForeColor = System.Drawing.Color.FromArgb(((int) (((byte) (255)))), ((int) (((byte) (128)))), ((int) (((byte) (0)))));
- this.advDumpTab.Location = new System.Drawing.Point(4, 24);
- this.advDumpTab.Name = "advDumpTab";
- this.advDumpTab.Padding = new System.Windows.Forms.Padding(3);
- this.advDumpTab.Size = new System.Drawing.Size(935, 479);
- this.advDumpTab.TabIndex = 1;
- this.advDumpTab.Text = "Advanced";
- //
- // advancedInfoLabel
- //
- this.advancedInfoLabel.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.advancedInfoLabel.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64)))));
- this.advancedInfoLabel.Location = new System.Drawing.Point(777, 3);
- this.advancedInfoLabel.Name = "advancedInfoLabel";
- this.advancedInfoLabel.Size = new System.Drawing.Size(155, 63);
- this.advancedInfoLabel.TabIndex = 3;
- this.advancedInfoLabel.Text = "DEBUG";
- //
- // advancedPlayAnimation
- //
- this.advancedPlayAnimation.Dock = System.Windows.Forms.DockStyle.Bottom;
- this.advancedPlayAnimation.Location = new System.Drawing.Point(170, 441);
- this.advancedPlayAnimation.Name = "advancedPlayAnimation";
- this.advancedPlayAnimation.Size = new System.Drawing.Size(762, 35);
- this.advancedPlayAnimation.TabIndex = 2;
- this.advancedPlayAnimation.Text = "Play Animation";
- this.advancedPlayAnimation.UseVisualStyleBackColor = true;
- this.advancedPlayAnimation.Click += new System.EventHandler(this.advancedPlayAnimation_Click);
- //
- // advancedPictureBox
- //
- this.advancedPictureBox.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64)))));
- this.advancedPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
- this.advancedPictureBox.Location = new System.Drawing.Point(170, 3);
- this.advancedPictureBox.Name = "advancedPictureBox";
- this.advancedPictureBox.Size = new System.Drawing.Size(762, 473);
- this.advancedPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
- this.advancedPictureBox.TabIndex = 1;
- this.advancedPictureBox.TabStop = false;
- //
- // advancedTreeView
- //
- this.advancedTreeView.Dock = System.Windows.Forms.DockStyle.Left;
- this.advancedTreeView.Location = new System.Drawing.Point(3, 3);
- this.advancedTreeView.Name = "advancedTreeView";
- this.advancedTreeView.Size = new System.Drawing.Size(167, 473);
- this.advancedTreeView.TabIndex = 0;
- this.advancedTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.advancedTreeView_AfterSelect);
+ // imgViewerTab
+ //
+ this.imgViewerTab.BackColor = System.Drawing.Color.DimGray;
+ this.imgViewerTab.Controls.Add(this.imageViewerInfo);
+ this.imgViewerTab.Controls.Add(this.imageViewerPlayAnim);
+ this.imgViewerTab.Controls.Add(this.imageViewPictureBox);
+ this.imgViewerTab.Controls.Add(this.imagesTreeView);
+ this.imgViewerTab.ForeColor = System.Drawing.Color.FromArgb(((int) (((byte) (255)))), ((int) (((byte) (128)))), ((int) (((byte) (0)))));
+ this.imgViewerTab.Location = new System.Drawing.Point(4, 24);
+ this.imgViewerTab.Name = "imgViewerTab";
+ this.imgViewerTab.Padding = new System.Windows.Forms.Padding(3);
+ this.imgViewerTab.Size = new System.Drawing.Size(935, 479);
+ this.imgViewerTab.TabIndex = 1;
+ this.imgViewerTab.Text = "Images";
+ //
+ // imageViewerInfo
+ //
+ this.imageViewerInfo.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.imageViewerInfo.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64)))));
+ this.imageViewerInfo.Location = new System.Drawing.Point(777, 3);
+ this.imageViewerInfo.Name = "imageViewerInfo";
+ this.imageViewerInfo.Size = new System.Drawing.Size(155, 63);
+ this.imageViewerInfo.TabIndex = 3;
+ this.imageViewerInfo.Text = "DEBUG";
+ //
+ // imageViewerPlayAnim
+ //
+ this.imageViewerPlayAnim.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.imageViewerPlayAnim.Location = new System.Drawing.Point(170, 441);
+ this.imageViewerPlayAnim.Name = "imageViewerPlayAnim";
+ this.imageViewerPlayAnim.Size = new System.Drawing.Size(762, 35);
+ this.imageViewerPlayAnim.TabIndex = 2;
+ this.imageViewerPlayAnim.Text = "Play Animation";
+ this.imageViewerPlayAnim.UseVisualStyleBackColor = true;
+ this.imageViewerPlayAnim.Click += new System.EventHandler(this.advancedPlayAnimation_Click);
+ //
+ // imageViewPictureBox
+ //
+ this.imageViewPictureBox.BackColor = System.Drawing.Color.FromArgb(((int) (((byte) (64)))), ((int) (((byte) (64)))), ((int) (((byte) (64)))));
+ this.imageViewPictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.imageViewPictureBox.Location = new System.Drawing.Point(170, 3);
+ this.imageViewPictureBox.Name = "imageViewPictureBox";
+ this.imageViewPictureBox.Size = new System.Drawing.Size(762, 473);
+ this.imageViewPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
+ this.imageViewPictureBox.TabIndex = 1;
+ this.imageViewPictureBox.TabStop = false;
+ //
+ // imagesTreeView
+ //
+ this.imagesTreeView.Dock = System.Windows.Forms.DockStyle.Left;
+ this.imagesTreeView.Location = new System.Drawing.Point(3, 3);
+ this.imagesTreeView.Name = "imagesTreeView";
+ this.imagesTreeView.Size = new System.Drawing.Size(167, 473);
+ this.imagesTreeView.TabIndex = 0;
+ this.imagesTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.advancedTreeView_AfterSelect);
+ //
+ // soundViewTab
+ //
+ this.soundViewTab.BackColor = System.Drawing.Color.Black;
+ this.soundViewTab.Controls.Add(this.soundList);
+ this.soundViewTab.Controls.Add(this.playSoundBtn);
+ this.soundViewTab.Location = new System.Drawing.Point(4, 24);
+ this.soundViewTab.Name = "soundViewTab";
+ this.soundViewTab.Size = new System.Drawing.Size(935, 479);
+ this.soundViewTab.TabIndex = 6;
+ this.soundViewTab.Text = "Sounds";
+ //
+ // soundList
+ //
+ this.soundList.Dock = System.Windows.Forms.DockStyle.Left;
+ this.soundList.Location = new System.Drawing.Point(0, 0);
+ this.soundList.Name = "soundList";
+ this.soundList.Size = new System.Drawing.Size(203, 479);
+ this.soundList.TabIndex = 1;
+ this.soundList.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.soundList_AfterSelect);
+ //
+ // playSoundBtn
+ //
+ this.playSoundBtn.Location = new System.Drawing.Point(209, 3);
+ this.playSoundBtn.Name = "playSoundBtn";
+ this.playSoundBtn.Size = new System.Drawing.Size(113, 50);
+ this.playSoundBtn.TabIndex = 0;
+ this.playSoundBtn.Text = "Play Sound";
+ this.playSoundBtn.UseVisualStyleBackColor = true;
+ this.playSoundBtn.Click += new System.EventHandler(this.playSoundBtn_Click);
//
// pluginTab
//
@@ -717,16 +752,26 @@
this.packDataTab.ResumeLayout(false);
this.cryptKeyTab.ResumeLayout(false);
this.cryptKeyTab.PerformLayout();
- this.advDumpTab.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize) (this.advancedPictureBox)).EndInit();
+ this.imgViewerTab.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize) (this.imageViewPictureBox)).EndInit();
+ this.soundViewTab.ResumeLayout(false);
this.pluginTab.ResumeLayout(false);
this.pluginTab.PerformLayout();
this.ResumeLayout(false);
}
- private System.Windows.Forms.Label advancedInfoLabel;
+ private System.Windows.Forms.TreeView soundList;
- private System.Windows.Forms.Button advancedPlayAnimation;
+ private System.Windows.Forms.Button playSoundBtn;
+
+ private System.Windows.Forms.TabPage soundViewTab;
+
+ private System.Windows.Forms.TreeView imagesTreeView;
+ private System.Windows.Forms.Button imageViewerPlayAnim;
+ private System.Windows.Forms.PictureBox imageViewPictureBox;
+ private System.Windows.Forms.TabPage imgViewerTab;
+
+ private System.Windows.Forms.Label imageViewerInfo;
public System.Windows.Forms.TextBox pluginLogBox;
@@ -735,10 +780,6 @@
private System.Windows.Forms.TabPage pluginTab;
- private System.Windows.Forms.PictureBox advancedPictureBox;
-
- private System.Windows.Forms.TreeView advancedTreeView;
-
private System.Windows.Forms.Button dumpAllPackButton;
private System.Windows.Forms.Button dumpPackButton;
private System.Windows.Forms.SaveFileDialog packDataDialog;
@@ -746,7 +787,6 @@
private System.Windows.Forms.Label infoLabel;
- private System.Windows.Forms.TabPage advDumpTab;
private System.Windows.Forms.TabPage mainTab;
private System.Windows.Forms.TabPage mfaTab;
private System.Windows.Forms.TabPage packDataTab;
diff --git a/DotNetCTFDumper/GUI/MainForm.cs b/DotNetCTFDumper/GUI/MainForm.cs
index b35e725..91ca13d 100644
--- a/DotNetCTFDumper/GUI/MainForm.cs
+++ b/DotNetCTFDumper/GUI/MainForm.cs
@@ -5,6 +5,7 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Media;
using System.Threading;
using System.Windows.Forms;
using Be.Windows.Forms;
@@ -105,6 +106,7 @@ namespace DotNetCTFDumper.GUI
if (e.TabPage != mainTab)
e.Cancel = true;
}
+ _soundPlayer.Stop();
}
@@ -290,7 +292,8 @@ namespace DotNetCTFDumper.GUI
Loaded = true;
InitKeyTab();
InitPackDataTab();
- InitAdvancedDump();
+ InitImages();
+ InitSounds();
InitPlugins();
var toLog = "";
toLog += $"Title:{Exe.Instance.GameData.Name}\n";
@@ -604,7 +607,7 @@ namespace DotNetCTFDumper.GUI
- public void InitAdvancedDump()
+ public void InitImages()
{
var bank = Exe.Instance.GameData.GameChunks.GetChunk();
var items = bank.Images.ToList();
@@ -612,7 +615,7 @@ namespace DotNetCTFDumper.GUI
foreach (Frame frame in Exe.Instance.GameData.Frames)
{
var frameNode = new ChunkNode(frame.Name, frame);
- advancedTreeView.Nodes.Add(frameNode);
+ imagesTreeView.Nodes.Add(frameNode);
if (frame.Objects != null)
{
foreach (ObjectInstance objInst in frame.Objects.Items)
@@ -630,40 +633,72 @@ namespace DotNetCTFDumper.GUI
objInstNode.Nodes.Add(animNode);
foreach (var dir in pair.Value.DirectionDict)
{
- for (int a = 0; a < dir.Value.Frames.Count; a++)
+ if (pair.Value.DirectionDict.Count > 1)
{
- var animFrame = dir.Value.Frames[a];
- bank.Images.TryGetValue(animFrame, out var img);
- var animFrameNode = new ChunkNode(a.ToString(), img);
- animNode.Nodes.Add(animFrameNode);
+ var dirNode = new ChunkNode($"Direction {pair.Key}",pair.Value);
+ animNode.Nodes.Add(dirNode);
+ for (int a = 0; a < dir.Value.Frames.Count; a++)
+ {
+
+ var animFrame = dir.Value.Frames[a];
+ bank.Images.TryGetValue(animFrame, out var img);
+ if (img != null)
+ {
+ var animFrameNode = new ChunkNode(a.ToString(), img);
+ dirNode.Nodes.Add(animFrameNode);
+ }
+
+ }
}
+ else
+ {
+ for (int a = 0; a < dir.Value.Frames.Count; a++)
+ {
+
+ var animFrame = dir.Value.Frames[a];
+ bank.Images.TryGetValue(animFrame, out var img);
+ if (img != null)
+ {
+ var animFrameNode = new ChunkNode(a.ToString(), img);
+ animNode.Nodes.Add(animFrameNode);
+ }
+
+ }
+ }
+
}
}
}
}
else if (loader is Backdrop backdrop)
{
- var backdropNode = new ChunkNode("Image", bank.Images[backdrop.Image]);
- objInstNode.Nodes.Add(backdropNode);
+ bank.Images.TryGetValue(backdrop.Image,out var img);
+ if (img != null)
+ {
+ var backdropNode = new ChunkNode("Image", img);
+ objInstNode.Nodes.Add(backdropNode);
+ }
}
}
}
}
}
- private bool breakAnim;
- private bool isAnimRunning;
+ private bool _breakAnim;
+ private bool _isAnimRunning;
+ private SoundPlayer _soundPlayer;
+
private void advancedPlayAnimation_Click(object sender, EventArgs e)
{
- if (((ChunkNode) advancedTreeView.SelectedNode).loader is Animation anim)
+ if (((ChunkNode) imagesTreeView.SelectedNode).loader is Animation anim)
{
- if (isAnimRunning)
+ if (_isAnimRunning)
{
- breakAnim = true;
+ _breakAnim = true;
}
else
{
- isAnimRunning = true;
+ _isAnimRunning = true;
var animThread = new Thread(PlayAnimation);
List frames = new List();
foreach (var dir in anim.DirectionDict)
@@ -673,6 +708,28 @@ namespace DotNetCTFDumper.GUI
frames.Add(Exe.Instance.GameData.GameChunks.GetChunk().Images[frame].Bitmap);
}
animThread.Start(new Tuple,AnimationDirection>(frames,dir.Value));
+ break;
+ }
+ }
+ }
+ else if (((ChunkNode) imagesTreeView.SelectedNode).loader is AnimationDirection dir)
+ {
+ if (_isAnimRunning)
+ {
+ _breakAnim = true;
+ }
+ else
+ {
+ _isAnimRunning = true;
+ var animThread = new Thread(PlayAnimation);
+ List frames = new List();
+ foreach (var frame in dir.Frames)
+ {
+
+ frames.Add(Exe.Instance.GameData.GameChunks.GetChunk().Images[frame].Bitmap);
+
+ animThread.Start(new Tuple,AnimationDirection>(frames,dir));
+ break;
}
}
@@ -692,11 +749,11 @@ namespace DotNetCTFDumper.GUI
{
foreach (Bitmap frame in frames)
{
- advancedPictureBox.Image = frame;
- advancedInfoLabel.Text = $"Current frame: {frames.IndexOf(frame)}\nAnimation Speed: {fps}";
+ imageViewPictureBox.Image = frame;
+ imageViewerInfo.Text = $"Current frame: {frames.IndexOf(frame)}\nAnimation Speed: {fps}";
Thread.Sleep((int) (delay*1500));
}
- isAnimRunning = false;
+ _isAnimRunning = false;
Thread.CurrentThread.Abort();
}
else
@@ -704,15 +761,15 @@ namespace DotNetCTFDumper.GUI
while (true)
{
var frame = frames[i];
- advancedPictureBox.Image = frame;
- advancedInfoLabel.Text = $"Current frame: {i.ToString()}\nAnimation Speed: {fps}";
+ imageViewPictureBox.Image = frame;
+ imageViewerInfo.Text = $"Current frame: {i.ToString()}\nAnimation Speed: {fps}";
Thread.Sleep((int) (delay*1500));
i++;
if (i == frames.Count) i = 0;
- if (breakAnim)
+ if (_breakAnim)
{
- isAnimRunning = false;
- breakAnim = false;
+ _isAnimRunning = false;
+ _breakAnim = false;
Thread.CurrentThread.Abort();
break;
@@ -722,7 +779,7 @@ namespace DotNetCTFDumper.GUI
}
}
- //Limited
+
}
@@ -733,7 +790,7 @@ namespace DotNetCTFDumper.GUI
if (((ChunkNode) node).loader is ImageItem)
{
var img = ((ImageItem) ((ChunkNode) node).loader);
- advancedPictureBox.Image = img.Bitmap;
+ imageViewPictureBox.Image = img.Bitmap;
}
}
@@ -756,7 +813,39 @@ namespace DotNetCTFDumper.GUI
PluginAPI.PluginAPI.ActivatePlugin(PluginAPI.PluginAPI.Plugins[pluginsList.SelectedIndex]);
}
-
+ public void SoundTest()
+ {
+
+ }
+
+ public void InitSounds()
+ {
+ var bank = Exe.Instance.GameData.GameChunks.GetChunk();
+ foreach (SoundItem soundItem in bank.Items)
+ {
+ soundList.Nodes.Add(new ChunkNode(soundItem.Name,soundItem));
+ }
+ _soundPlayer = new SoundPlayer(new MemoryStream(Exe.Instance.GameData.GameChunks.GetChunk().Items[0].Data));
+
+ }
+
+
+
+ private void playSoundBtn_Click(object sender, EventArgs e)
+ {
+ _soundPlayer.Stream = new MemoryStream(Exe.Instance.GameData.GameChunks.GetChunk().Items[soundList.SelectedNode.Index].Data);
+ _soundPlayer.Play();
+
+
+
+
+
+ }
+
+ private void soundList_AfterSelect(object sender, TreeViewEventArgs e)
+ {
+
+ }
}
}
diff --git a/DotNetCTFDumper/MMFParser/EXE/Loaders/Banks/SoundBank.cs b/DotNetCTFDumper/MMFParser/EXE/Loaders/Banks/SoundBank.cs
index 5af39cd..d06bcd2 100644
--- a/DotNetCTFDumper/MMFParser/EXE/Loaders/Banks/SoundBank.cs
+++ b/DotNetCTFDumper/MMFParser/EXE/Loaders/Banks/SoundBank.cs
@@ -44,7 +44,7 @@ namespace DotNetCTFDumper.MMFParser.EXE.Loaders.Banks
Items = new List();
NumOfItems = Reader.ReadInt32();
Logger.Log("Found " + NumOfItems + " sounds");
- if (!Settings.DumpSounds) return;
+ //if (!Settings.DumpSounds) return;
for (int i = 0; i < NumOfItems; i++)
{
diff --git a/DotNetCTFDumper/Utils/WAVReading.cs b/DotNetCTFDumper/Utils/WAVReading.cs
new file mode 100644
index 0000000..7f21a0e
--- /dev/null
+++ b/DotNetCTFDumper/Utils/WAVReading.cs
@@ -0,0 +1,175 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Diagnostics;
+
+namespace DotNetCTFDumper.Utils
+{
+ class WavFile
+ {
+ public int samplesPerSecond { get; set; }
+ public int samplesTotalCount { get; set; }
+ public string wavFilename { get; private set; }
+ public byte[] metaData { get; set; }
+
+
+ public WavFile(string filename)
+ {
+ samplesTotalCount = samplesPerSecond = -1;
+ wavFilename = filename;
+ metaData = null;
+ }
+
+
+ ///
+ /// Reading all samples of a 16-bit stereo wav file into arrays.
+ ///
+
+ public bool readData(ref double[] L, ref double[] R)
+ {
+ try
+ {
+ BinaryReader reader = new BinaryReader(File.Open(wavFilename, FileMode.Open));
+
+ // header (8 + 4 bytes):
+
+ byte[] riffId = reader.ReadBytes(4); // "RIFF"
+ int fileSize = reader.ReadInt32(); // size of entire file
+ byte[] typeId = reader.ReadBytes(4); // "WAVE"
+
+ if (Encoding.ASCII.GetString(typeId) != "WAVE") return false;
+
+ // chunk 1 (8 + 16 or 18 bytes):
+
+ byte[] fmtId = reader.ReadBytes(4); // "fmt "
+ int fmtSize = reader.ReadInt32(); // size of chunk in bytes
+ int fmtCode = reader.ReadInt16(); // 1 - for PCM
+ int channels = reader.ReadInt16(); // 1 - mono, 2 - stereo
+ int sampleRate = reader.ReadInt32(); // sample rate per second
+ int byteRate = reader.ReadInt32(); // bytes per second
+ int dataAlign = reader.ReadInt16(); // data align
+ int bitDepth = reader.ReadInt16(); // 8, 16, 24, 32, 64 bits
+
+ if (fmtCode != 1) return false; // not PCM
+ if (channels != 2) return false; // only Stereo files in this version
+ if (bitDepth != 16) return false; // only 16-bit in this version
+
+ if (fmtSize == 18) // fmt chunk can be 16 or 18 bytes
+ {
+ int fmtExtraSize = reader.ReadInt16(); // read extra bytes size
+ reader.ReadBytes(fmtExtraSize); // skip over "INFO" chunk
+ }
+
+ // chunk 2 (8 bytes):
+
+ byte[] dataId = reader.ReadBytes(4); // "data"
+ int dataSize = reader.ReadInt32(); // size of audio data
+
+ Debug.Assert(Encoding.ASCII.GetString(dataId) == "data", "Data chunk not found!");
+
+ samplesPerSecond = sampleRate; // sample rate (usually 44100)
+ samplesTotalCount = dataSize / (bitDepth / 8); // total samples count in audio data
+
+ // audio data:
+
+ L = R = new double[samplesTotalCount / 2];
+
+ for (int i = 0, s = 0; i < samplesTotalCount; i += 2)
+ {
+ L[s] = Convert.ToDouble(reader.ReadInt16());
+ R[s] = Convert.ToDouble(reader.ReadInt16());
+ s++;
+ }
+
+ // metadata:
+
+ long moreBytes = reader.BaseStream.Length - reader.BaseStream.Position;
+
+ if (moreBytes > 0)
+ {
+ metaData = reader.ReadBytes((int)moreBytes);
+ }
+
+ reader.Close();
+ }
+ catch
+ {
+ Debug.Fail("Failed to read file.");
+ return false;
+ }
+
+ return true;
+ }
+
+
+ ///
+ /// Writing all 16-bit stereo samples from arrays into wav file.
+ ///
+
+ public bool writeData(double[] L, double[] R)
+ {
+ Debug.Assert((samplesTotalCount != -1) && (samplesPerSecond != -1),
+ "No sample count or sample rate info!");
+
+ try
+ {
+ BinaryWriter writer = new BinaryWriter(File.Create(wavFilename));
+
+ int fileSize = 44 + samplesTotalCount * 2;
+
+ if (metaData != null)
+ {
+ fileSize += metaData.Length;
+ }
+
+ // header:
+
+ writer.Write(Encoding.ASCII.GetBytes("RIFF")); // "RIFF"
+ writer.Write((Int32)fileSize); // size of entire file with 16-bit data
+ writer.Write(Encoding.ASCII.GetBytes("WAVE")); // "WAVE"
+
+ // chunk 1:
+
+ writer.Write(Encoding.ASCII.GetBytes("fmt ")); // "fmt "
+ writer.Write((Int32)16); // size of chunk in bytes
+ writer.Write((Int16)1); // 1 - for PCM
+ writer.Write((Int16)2); // only Stereo files in this version
+ writer.Write((Int32)samplesPerSecond); // sample rate per second (usually 44100)
+ writer.Write((Int32)(4 * samplesPerSecond)); // bytes per second (usually 176400)
+ writer.Write((Int16)4); // data align 4 bytes (2 bytes sample stereo)
+ writer.Write((Int16)16); // only 16-bit in this version
+
+ // chunk 2:
+
+ writer.Write(Encoding.ASCII.GetBytes("data")); // "data"
+ writer.Write((Int32)(samplesTotalCount * 2)); // size of audio data 16-bit
+
+ // audio data:
+
+ for (int i = 0, s = 0; i < samplesTotalCount; i += 2)
+ {
+ writer.Write(Convert.ToInt16(L[s]));
+ writer.Write(Convert.ToInt16(R[s]));
+ s++;
+ }
+
+ // metadata:
+
+ if (metaData != null)
+ {
+ writer.Write(metaData);
+ }
+
+ writer.Flush();
+ writer.Close();
+ }
+ catch
+ {
+ Debug.Fail("Failed to write file.");
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file