diff --git a/Audio Tone Generator.sln b/Audio Tone Generator.sln
new file mode 100644
index 0000000..c63e487
--- /dev/null
+++ b/Audio Tone Generator.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31717.71
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio Tone Generator", "Audio Tone Generator\Audio Tone Generator.csproj", "{AA736F2B-391A-45E4-A290-D9869BFBA63F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {AA736F2B-391A-45E4-A290-D9869BFBA63F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AA736F2B-391A-45E4-A290-D9869BFBA63F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA736F2B-391A-45E4-A290-D9869BFBA63F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AA736F2B-391A-45E4-A290-D9869BFBA63F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {50848817-EF8E-4E27-93AB-F590C14556E4}
+ EndGlobalSection
+EndGlobal
diff --git a/Audio Tone Generator/App.config b/Audio Tone Generator/App.config
new file mode 100644
index 0000000..731f6de
--- /dev/null
+++ b/Audio Tone Generator/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Audio Tone Generator/Audio Tone Generator.csproj b/Audio Tone Generator/Audio Tone Generator.csproj
new file mode 100644
index 0000000..40a9bfa
--- /dev/null
+++ b/Audio Tone Generator/Audio Tone Generator.csproj
@@ -0,0 +1,52 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {AA736F2B-391A-45E4-A290-D9869BFBA63F}
+ Exe
+ AudioToneGenerator
+ AudioToneGenerator
+ v4.6.1
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Audio Tone Generator/Program.cs b/Audio Tone Generator/Program.cs
new file mode 100644
index 0000000..6750e52
--- /dev/null
+++ b/Audio Tone Generator/Program.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace AudioToneGenerator
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ FileStream fs = new FileStream("F:\\testFile.wav", FileMode.Create);
+ Stream s = GenerateWaveFormStream(50, 4800000);
+ s.CopyTo(fs);
+ fs.Flush();
+ fs.Close();
+ Console.WriteLine("Complete");
+
+ Console.ReadLine();
+ }
+ ///
+ /// Internal class that adds in simple write buffer support
+ ///
+ internal class MemoryStream_Mod : MemoryStream
+ {
+ public void Write(byte[] buffer)
+ {
+ Write(buffer, 0, buffer.Length);
+ }
+ }
+
+ static internal byte[] GetBytes(int i)
+ {
+ byte[] bytes = BitConverter.GetBytes(i);
+ if (!BitConverter.IsLittleEndian)
+ {
+ // We need data in little-endian format; so reverse the array
+ Array.Reverse(bytes);
+ }
+ return bytes;
+ }
+
+ static internal byte[] GetBytes(uint i)
+ {
+ byte[] bytes = BitConverter.GetBytes(i);
+ if (!BitConverter.IsLittleEndian)
+ {
+ // We need data in little-endian format; so reverse the array
+ Array.Reverse(bytes);
+ }
+ return bytes;
+ }
+ static internal byte[] GetBytes(short i)
+ {
+ byte[] bytes = BitConverter.GetBytes(i);
+ if (!BitConverter.IsLittleEndian)
+ {
+ Array.Reverse(bytes);
+ }
+ return bytes;
+ }
+
+ static internal byte[] GetBytes(Int24 i)
+ {
+ byte[] bytes = BitConverter.GetBytes(i); // final irrelevant byte is 0; create a new array and ignore
+ byte[] tripleBytes;
+ if (BitConverter.IsLittleEndian)
+ {
+ // Little-endian, so use the first three bytes
+ tripleBytes = new byte[] { bytes[0], bytes[1], bytes[2] };
+ }
+ else
+ {
+ // Big-endian, so use the last three, beginning from the end
+ tripleBytes = new byte[] { bytes[3], bytes[2], bytes[1] };
+ }
+ return tripleBytes;
+ }
+ ///
+ /// Non-standard 24-bit integer. Uses the system's endianness (underlying implementation is Int32)
+ ///
+ internal readonly struct Int24
+ {
+ private readonly int m_value;
+
+ public const int MaxValue = 0x7FFFFF;
+ public const int MinValue = -0x800000;
+
+ public bool Equals(Int24 obj)
+ {
+ return m_value == obj.m_value;
+ }
+
+ public Int24(int i)
+ {
+ if (i > MaxValue || i < MinValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(i), i.ToString());
+ }
+ m_value = i;
+ }
+
+ public static explicit operator Int24(int i) => new Int24(i);
+ public static implicit operator int(Int24 i) => i.m_value;
+
+ public override string ToString() => m_value.ToString();
+ }
+
+ ///
+ /// Non-standard unsigned 24-bit integer. Uses the system's endianness (underlying implementation is Int32)
+ ///
+ internal readonly struct UInt24
+ {
+ private readonly int m_value;
+
+ public const int MaxValue = 0xFFFFFF;
+ public const int MinValue = 0x0;
+
+ public bool Equals(UInt24 obj)
+ {
+ return m_value == obj.m_value;
+ }
+
+ public UInt24(int i)
+ {
+ if (i > MaxValue || i < MinValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(i), i.ToString());
+ }
+ m_value = i;
+ }
+
+ public static explicit operator UInt24(int i) => new UInt24(i);
+ public static implicit operator int(UInt24 i) => i.m_value;
+
+ public override string ToString() => m_value.ToString();
+ }
+
+ public static Stream GenerateWaveFormStream(int frequency, uint numberOfSamples, int sampleRate=48000, short numChannels=1, short bitsPerSample=24)
+ {
+ // Create a variant of the memory stream which allows shorthand writing
+ MemoryStream_Mod ms = new MemoryStream_Mod();
+ // Create the file header
+ ms.Write(Encoding.ASCII.GetBytes("RIFF"));
+ ms.Write(GetBytes(0)); // File size in bytes
+ ms.Write(Encoding.ASCII.GetBytes("WAVEfmt ")); // File type and format chunk
+ ms.Write(GetBytes((int)ms.Length)); // Length of currently written bytes
+ ms.Write(GetBytes((short)1)); // short; little-endian = 1 [= PCM data]
+ ms.Write(GetBytes(numChannels)); // Number of channels
+ ms.Write(GetBytes(sampleRate)); // Sample Frequency
+ ms.Write(GetBytes((sampleRate * numChannels * bitsPerSample) / 8)); // Effective byte rate (num channels * sample rate * bitrate) / 8
+ ms.Write(GetBytes((short)((bitsPerSample * numChannels)/8))); // Block align
+ ms.Write(GetBytes(bitsPerSample));
+ // Data block
+ ms.Write(Encoding.ASCII.GetBytes("data"));
+ ms.Write(GetBytes((uint)(numberOfSamples * numChannels * bitsPerSample) / 8));
+ // Actual sound data
+ // Frequency == C->H->C->L->C oscillations per second; so angular velocity is 2 x Pi x frequency
+ // Sample rate = number of times/second we sample that value
+ // Therefore, if the sample was 1-i per second, 20 Hz would be (20 * 360)i
+ UInt24[] channelData = new UInt24[numChannels];
+ double angularVelocity = 2 * Math.PI * frequency;
+ double timeBetweenSamples = 1 / (double)sampleRate;
+ double samplesAngular = angularVelocity / sampleRate;
+
+ double normalisedFrequency = frequency / timeBetweenSamples;
+ for (uint i = 0; i < numberOfSamples; i++)
+ {
+ for (int n = 0; n < numChannels; n++)
+ {
+ double curr = Math.Sin(samplesAngular * i);
+ ms.Write(GetBytes((Int24)(((Int24.MaxValue-1) / 2) * curr)));
+ }
+ }
+ ms.Position = 4;
+ ms.Write(GetBytes((int)ms.Length));
+ ms.Position = 0; // Return the stream position to the beginning
+ return ms;
+ }
+ }
+}
diff --git a/Audio Tone Generator/Properties/AssemblyInfo.cs b/Audio Tone Generator/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6c88936
--- /dev/null
+++ b/Audio Tone Generator/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Audio Tone Generator")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Audio Tone Generator")]
+[assembly: AssemblyCopyright("Copyright © Brychan Dempsey 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("aa736f2b-391a-45e4-a290-d9869bfba63f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]