Hey guys, I have been doing some experimenting with WAV files and I need to be able to play an WAV file from a stream. What I am going to be doing is opening a file, getting the raw data of the wav file. I do this by using this class provided by NightFox:
http://www.codeproject.com/KB/audio-video/CSharpWAVClassAndMixing.aspx
Then when I have the raw data, I extract it using the WAVFile's built in function GetNextSampleAs16Bit().
Here is the class that I have made:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Aurasen
{
class InternalWAVFile
{
private MemoryStream mMemoryStream;
private bool mStereo;
private int mSampleRateHz;
private short mBitsPerSample;
private int mDataSizeBytes;
public InternalWAVFile(short[] samples, bool pStereo, int pSampleRateHz, short pBitsPerSample)
{
if (mMemoryStream != null)
{
mMemoryStream.Close();
mMemoryStream.Dispose();
mMemoryStream = null;
}
mMemoryStream = new MemoryStream();
mStereo = pStereo;
mSampleRateHz = pSampleRateHz;
mBitsPerSample = pBitsPerSample;
Create();
foreach (short s in samples)
{
byte[] buffer = BitConverter.GetBytes(s);
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer);
AddSample_ByteArray(buffer);
}
mMemoryStream.Close();
}
public MemoryStream GetStream()
{
return mMemoryStream;
}
private void AddSample_ByteArray(byte[] pSample)
{
try
{
int numBytes = pSample.GetLength(0);
mMemoryStream.Write(pSample, 0, numBytes);
}
catch
{
}
}
private void Create()
{
try
{
byte mNumChannels = mStereo ? (byte)2 : (byte)1;
char[] mWAVHeader = new char[4];
char[] mRIFFType = new char[4];
"RIFF".CopyTo(0, mWAVHeader, 0, 4);
"WAVE".CopyTo(0, mRIFFType, 0, 4);
byte[] buffer = StrToByteArray("RIFF");
mMemoryStream.Write(buffer, 0, 4);
if (mWAVHeader == null)
mWAVHeader = new char[4];
"RIFF".CopyTo(0, mWAVHeader, 0, 4);
Array.Clear(buffer, 0, buffer.GetLength(0));
mMemoryStream.Write(buffer, 0, 4);
buffer = StrToByteArray("WAVE");
mMemoryStream.Write(buffer, 0, 4);
if (mRIFFType == null)
mRIFFType = new char[4];
"WAVE".CopyTo(0, mRIFFType, 0, 4);
buffer = StrToByteArray("fmt ");
mMemoryStream.Write(buffer, 0, 4);
Array.Clear(buffer, 0, buffer.GetLength(0));
buffer[0] = 16;
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer);
mMemoryStream.Write(buffer, 0, 4);
Array.Clear(buffer, 0, buffer.GetLength(0));
buffer[0] = 1;
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer, 0, 2);
mMemoryStream.Write(buffer, 0, 2);
Array.Clear(buffer, 0, buffer.GetLength(0));
buffer[0] = mNumChannels;
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer, 0, 2);
mMemoryStream.Write(buffer, 0, 2);
buffer = BitConverter.GetBytes(mSampleRateHz);
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer);
mMemoryStream.Write(buffer, 0, 4);
short bytesPerSample = 0;
if (mStereo)
bytesPerSample = (short)((mBitsPerSample / 8) * 2);
else
bytesPerSample = (short)(mBitsPerSample / 8);
int mBytesPerSec = mSampleRateHz * bytesPerSample;
buffer = BitConverter.GetBytes(mBytesPerSec);
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer);
mMemoryStream.Write(buffer, 0, 4);
byte[] buffer_2bytes = BitConverter.GetBytes(bytesPerSample);
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer_2bytes);
mMemoryStream.Write(buffer_2bytes, 0, 2);
buffer_2bytes = BitConverter.GetBytes(mBitsPerSample);
if (!BitConverter.IsLittleEndian)
Array.Reverse(buffer_2bytes);
mMemoryStream.Write(buffer_2bytes, 0, 2);
buffer = StrToByteArray("data");
mMemoryStream.Write(buffer, 0, 4);
Array.Clear(buffer, 0, buffer.GetLength(0));
mMemoryStream.Write(buffer, 0, 4);
mDataSizeBytes = 0;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static byte[] StrToByteArray(String pStr)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(pStr);
}
}
}
But for some reason when I used this function to play audio like this:
All it does is say the Header information is corrupted, even though I am using the same method of building a wav file content as the creator of the WAVFile class uses.
Does anyone have any suggestions?
class Program
{
static void Main(string[] args)
{
Console.WriteLine("hi");
WAVFile audioFile = new WAVFile();
string warning = audioFile.Open("11.wav", WAVFile.WAVFileMode.READ);
short[] audioSample = new short[audioFile.NumSamples];
if (warning == "")
{
for (int sampleNum = 0; sampleNum < audioFile.NumSamples; ++sampleNum)
{
audioSample[sampleNum] = audioFile.GetNextSampleAs16Bit();
}
}
InternalWAVFile iwf = new InternalWAVFile(audioSample, audioFile.IsStereo, audioFile.SampleRateHz, audioFile.BitsPerSample);
MemoryStream ms = iwf.GetStream();
if (null == ms)
Console.WriteLine("stream is null");
else
{
Console.WriteLine("Not null");
Audio a = new Audio();
Console.WriteLine("Going to play");
a.Play(ms, Microsoft.VisualBasic.AudioPlayMode.Background);
Console.WriteLine("Played");
}
}
}