Skip to content

Instantly share code, notes, and snippets.

@alphaKAI
Created June 17, 2016 13:33
Show Gist options
  • Save alphaKAI/9c886bdedea4d1a1a8763d1d8b4c6cde to your computer and use it in GitHub Desktop.
Save alphaKAI/9c886bdedea4d1a1a8763d1d8b4c6cde to your computer and use it in GitHub Desktop.
Handling WAVE format in D Raw. This program works as $ ffmpeg -i filename -f s16le -ac 2 -acodec pcm_s16le -ar 44100 filename.pcm
import std.stdio;
struct ChunkHead {
char[4] id;
uint size;
}
struct RiffChunk {
ChunkHead head;
char[4] format;
}
struct WaveFileFormat {
ushort audioFormat,
channels;
uint samplePerSecond,
bytesPerSecond;
ushort blockAlign,
bitsPerSample;
}
struct WaveFormatChunk {
ChunkHead chunk;
WaveFileFormat format;
}
auto min(M, N)(M m, N n) {
return m > n ? n : m;
}
//This program works as $ ffmpeg -i filename -f s16le -ac 2 -acodec pcm_s16le -ar 44100 filename.pcm
void main() {
string filename = "filename.wav";
auto file = File(filename, "rb");
ubyte[] buf;
buf.length = file.size;
file.rawRead(buf);
size_t b = 0,
e = RiffChunk.sizeof;
RiffChunk* riff = cast(RiffChunk*)buf[b..e];
WaveFileFormat* format;
ubyte[] pcm;
if(riff.head.id != "RIFF") {
writeln("Invalid WAV format was given");
return;
}
if (riff.format != "WAVE") {
writeln("Invalid RIFF chunk format. Given file is not WAVE");
return;
}
ChunkHead* chunk;
b = e;
while (b < buf.length) {
e = b + ChunkHead.sizeof;
chunk = cast(ChunkHead*)buf[b..e];
if (chunk.size < 0) {
writeln("ERROR! Invalid chunk size");
return;
}
b = e;
if (chunk.id == "fmt ") {
e = b + min(chunk.size, WaveFormatChunk.sizeof);
format = cast(WaveFileFormat*)buf[b..e];
b = e;
} else if (chunk.id == "data") {
pcm.length = chunk.size;
e = b + chunk.size;
pcm = buf[b..e];
b = e;
} else {//skip others chunks
b = e + chunk.size;
}
}
writeln("FORMAT INFORMATIONS");
writeln("audioFormat: ", format.audioFormat);
writeln("channels: ", format.channels);
writeln("samplePerSecond: ", format.samplePerSecond);
writeln("bytesPerSecond: ", format.bytesPerSecond);
writeln("blockAlign: ", format.blockAlign);
writeln("bitsPerSample: ", format.bitsPerSample);
//Save raw PCM data to filename.pcm
File(filename ~ ".pcm", "wb").rawWrite(pcm);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment