|
-
March 21st, 2013, 01:37 PM
#4
Re: Problems writting WAV in C#
I got curious so I played around a bit with it and this is the result. C# isn't my first language but since I think this could be useful I post it anyway. i haven't tried adding several data blocks into the file but I hope you can make it into something useful anyway.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace WavMaker
{
class Program
{
class WavHeader
{
public WavHeader(uint subChunk1Size, uint subChunk2Size)
{
chunkId = 0x46464952; // "RIFF"
chunkSize = 4 + (8 + subChunk1Size) + (8 + subChunk2Size);
format = 0x45564157; // "WAVE"
}
public void Write(ref BinaryWriter w)
{
w.Write(chunkId);
w.Write(chunkSize);
w.Write(format);
}
uint chunkId; // BigEndian
uint chunkSize; // LittleEndian
uint format; // BigEndian
}
class FmtChunk
{
public FmtChunk(ushort numChannels_, uint sampleRate_, ushort bitsPerSample_)
{
subChunk1Id = 0x20746D66; // "RIFF"
subChunk1Size = 16; // PCM
audioFormat = 1;
numChannels = numChannels_;
sampleRate = sampleRate_;
byteRate = numChannels_ * sampleRate_ * bitsPerSample_ / 8;
blockAlign = (ushort)(numChannels_ * bitsPerSample_ / 8);
bitsPerSample = bitsPerSample_;
}
public void Write(ref BinaryWriter w)
{
w.Write(subChunk1Id);
w.Write(subChunk1Size);
w.Write(audioFormat);
w.Write(numChannels);
w.Write(sampleRate);
w.Write(byteRate);
w.Write(blockAlign);
w.Write(bitsPerSample);
}
public uint Size()
{
return subChunk1Size;
}
uint subChunk1Id; // BigEndian "fmt "
uint subChunk1Size; // LittleEndian
ushort audioFormat; // LittleEndian
ushort numChannels; // LittleEndian
uint sampleRate; // LittleEndian
uint byteRate; // LittleEndian
ushort blockAlign; // LittleEndian
ushort bitsPerSample; // LittleEndian
}
class DataHeader
{
public DataHeader(uint subChunk2Size_)
{
subChunk2Id = 0x61746164; // "data"
subChunk2Size = subChunk2Size_;
}
public void Write(ref BinaryWriter w)
{
w.Write(subChunk2Id);
w.Write(subChunk2Size);
}
uint subChunk2Id; // BigEndian
uint subChunk2Size; // LittleEndian
}
interface Wave
{
void Write(ref BinaryWriter w);
uint Size();
}
class Mono16Tone : Wave
{
public Mono16Tone(uint seconds, uint freq, uint sampleRate)
{
uint samples = seconds * sampleRate;
wave = new short[samples];
for (uint n = 0; n < samples; n++)
{
wave[n] = (short)(32767 * Math.Sin(freq * 2.0 * Math.PI * n / sampleRate));
}
}
void Wave.Write(ref BinaryWriter w)
{
foreach (short e in wave) w.Write(e);
}
uint Wave.Size()
{
return (uint)(sizeof(short) * wave.Length);
}
short[] wave;
}
class Mono16DualTones : Wave
{
public Mono16DualTones(uint seconds, uint freq1, uint freq2, uint sampleRate)
{
uint samples = seconds * sampleRate;
wave = new short[samples];
for (uint n = 0; n < samples; n++)
{
short value1 = (short)(32767 * Math.Sin(freq1 * 2.0 * Math.PI * n / sampleRate));
short value2 = (short)(32767 * Math.Sin(freq2 * 2.0 * Math.PI * n / sampleRate));
wave[n] = (short)((value1 + value2) / 2);
}
}
void Wave.Write(ref BinaryWriter w)
{
foreach (short e in wave) w.Write(e);
}
uint Wave.Size()
{
return (uint)(sizeof(short) * wave.Length);
}
short[] wave;
}
class Stereo16Tone : Wave
{
public Stereo16Tone(uint seconds, uint freq, uint sampleRate)
{
uint samples = seconds * sampleRate;
wave = new short[2 * samples];
for (uint n = 0; n < samples; n++)
{
short value = (short)(32767 * Math.Sin(freq * 2.0 * Math.PI * n / sampleRate));
wave[2 * n] = value;
wave[2 * n + 1] = value;
}
}
void Wave.Write(ref BinaryWriter w)
{
foreach (short e in wave) w.Write(e);
}
uint Wave.Size()
{
return (uint)(sizeof(short) * wave.Length);
}
short[] wave;
}
class Stereo16DualTones : Wave
{
public Stereo16DualTones(uint seconds, uint freq1, uint freq2, uint sampleRate)
{
uint samples = seconds * sampleRate;
wave = new short[2 * samples];
for (uint n = 0; n < samples; n++)
{
short value = (short)(32767 * Math.Sin(freq1 * 2.0 * Math.PI * n / sampleRate));
wave[2 * n] = value;
value = (short)(32767 * Math.Sin(freq2 * 2.0 * Math.PI * n / sampleRate));
wave[2 * n + 1] = value;
}
}
void Wave.Write(ref BinaryWriter w)
{
foreach (short e in wave) w.Write(e);
}
uint Wave.Size()
{
return (uint)(sizeof(short) * wave.Length);
}
short[] wave;
}
static void Main(string[] args)
{
uint seconds = 10;
uint freq = 440;
uint sampleRate = 8000;
ushort bitsPerSample = 16;
ushort numChannels = 1;
ushort tones = 2;
String fname = "";
Wave wave = null;
switch (numChannels)
{
case 1:
switch (tones)
{
case 1:
fname = "mono1.wav";
wave = new Mono16Tone(seconds, freq, sampleRate);
break;
case 2:
fname = "mono2.wav";
wave = new Mono16DualTones(seconds, freq, 2 * freq, sampleRate);
break;
}
break;
case 2:
switch (tones)
{
case 1:
fname = "stereo1.wav";
wave = new Stereo16Tone(seconds, freq, sampleRate);
break;
case 2:
fname = "stereo2.wav";
wave = new Stereo16DualTones(seconds, freq, 2 * freq, sampleRate);
break;
}
break;
}
DataHeader dataHeader = new DataHeader(wave.Size());
FmtChunk fmtChunk = new FmtChunk(numChannels, sampleRate, bitsPerSample);
WavHeader wavHeader = new WavHeader(fmtChunk.Size(), wave.Size());
FileStream f = new FileStream(fname, FileMode.Create, FileAccess.Write);
BinaryWriter w = new BinaryWriter(f);
wavHeader.Write(ref w);
fmtChunk.Write(ref w);
dataHeader.Write(ref w);
wave.Write(ref w);
f.Close();
}
}
}
Last edited by S_M_A; March 21st, 2013 at 03:24 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|