Created
June 17, 2016 13:33
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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