Add SoundPlayer

master
1987kostya 4 years ago
parent b93af88058
commit 209f39a62f

@ -229,6 +229,7 @@
<Compile Include="Utils\ImageDumper.cs" />
<Compile Include="Utils\ImageHelper.cs" />
<Compile Include="Utils\Logger.cs" />
<Compile Include="Utils\WAVReading.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />

@ -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;

@ -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<ImageBank>();
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)
@ -629,41 +632,73 @@ namespace DotNetCTFDumper.GUI
var animNode = new ChunkNode($"Animation {pair.Key}", pair.Value);
objInstNode.Nodes.Add(animNode);
foreach (var dir in pair.Value.DirectionDict)
{
if (pair.Value.DirectionDict.Count > 1)
{
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]);
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 SoundPlayer _soundPlayer;
private bool breakAnim;
private bool isAnimRunning;
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<Bitmap> frames = new List<Bitmap>();
foreach (var dir in anim.DirectionDict)
@ -673,6 +708,28 @@ namespace DotNetCTFDumper.GUI
frames.Add(Exe.Instance.GameData.GameChunks.GetChunk<ImageBank>().Images[frame].Bitmap);
}
animThread.Start(new Tuple<List<Bitmap>,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<Bitmap> frames = new List<Bitmap>();
foreach (var frame in dir.Frames)
{
frames.Add(Exe.Instance.GameData.GameChunks.GetChunk<ImageBank>().Images[frame].Bitmap);
animThread.Start(new Tuple<List<Bitmap>,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,8 +813,40 @@ namespace DotNetCTFDumper.GUI
PluginAPI.PluginAPI.ActivatePlugin(PluginAPI.PluginAPI.Plugins[pluginsList.SelectedIndex]);
}
public void SoundTest()
{
}
public void InitSounds()
{
var bank = Exe.Instance.GameData.GameChunks.GetChunk<SoundBank>();
foreach (SoundItem soundItem in bank.Items)
{
soundList.Nodes.Add(new ChunkNode(soundItem.Name,soundItem));
}
_soundPlayer = new SoundPlayer(new MemoryStream(Exe.Instance.GameData.GameChunks.GetChunk<SoundBank>().Items[0].Data));
}
private void playSoundBtn_Click(object sender, EventArgs e)
{
_soundPlayer.Stream = new MemoryStream(Exe.Instance.GameData.GameChunks.GetChunk<SoundBank>().Items[soundList.SelectedNode.Index].Data);
_soundPlayer.Play();
}
private void soundList_AfterSelect(object sender, TreeViewEventArgs e)
{
}
}
}

@ -44,7 +44,7 @@ namespace DotNetCTFDumper.MMFParser.EXE.Loaders.Banks
Items = new List<SoundItem>();
NumOfItems = Reader.ReadInt32();
Logger.Log("Found " + NumOfItems + " sounds");
if (!Settings.DumpSounds) return;
//if (!Settings.DumpSounds) return;
for (int i = 0; i < NumOfItems; i++)
{

@ -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;
}
/// <summary>
/// Reading all samples of a 16-bit stereo wav file into arrays.
/// </summary>
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;
}
/// <summary>
/// Writing all 16-bit stereo samples from arrays into wav file.
/// </summary>
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;
}
}
}
Loading…
Cancel
Save