diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2010-12-29 16:26:25 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2010-12-29 16:26:25 +0100 |
commit | d3148268857e01116d5d3c99ac0a43bc6a54b13c (patch) | |
tree | 6ae273025ef73942c0ac748e715a7f281a6af114 /samples/wave.lua | |
download | lspipat-d3148268857e01116d5d3c99ac0a43bc6a54b13c.tar.gz |
Diffstat (limited to 'samples/wave.lua')
-rwxr-xr-x | samples/wave.lua | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/samples/wave.lua b/samples/wave.lua new file mode 100755 index 0000000..9fd5adb --- /dev/null +++ b/samples/wave.lua @@ -0,0 +1,81 @@ +#!/usr/bin/lua + +require "lspipat" + +function uint(bytes, val) -- binary integer decoding + return Len(bytes) % function(bin) + bin = littleEndian and bin or bin:reverse() + + local n = 0 + local base = 1 + + for _, c in ipairs{bin:byte(1, bytes)} do + n = n + base * c + base = base * 256 + end + + val(n) + end +end + +function _uint(bytes, name) return uint(bytes, function(n) _G[name] = n end) end +function _uint16(name) return _uint(2, name) end +function _uint32(name) return _uint(4, name) end + +hnd = assert(io.open(arg[1])) + +file = hnd:read("*a") + +hnd:close() + +-- WAVE file "grammar" + +format = "fmt " + * _uint32 "FmtChunkSize" + * _Setcur "FmtStartPos" + * _uint16 "AudioFormat" + * _uint16 "NumChannels" + * _uint32 "SampleRate" + * _uint32 "ByteRate" + * _uint16 "BlockAlign" + * _uint16 "BitsPerSample" + * ( -function() return AudioFormat == 1 end + + _uint16 "ExtraParamSize" + * _Len "ExtraParamSize" ) + * Pos(function() return FmtStartPos + FmtChunkSize end) + * -function() return BitsPerSample % 8 == 0 and + BlockAlign == NumChannels * BitsPerSample/8 and + ByteRate == SampleRate * BlockAlign end + +data = "data" + * _uint32 "DataChunkSize" + * _Len "DataChunkSize" + +misc = Len(4) + * _uint32 "MiscChunkSize" + * _Len "MiscChunkSize" + +wave = (topattern("RIFF") + "RIFX") + % function(id) littleEndian = id == "RIFF" end + * _uint32 "ChunkSize" + * _Setcur "StartPos" + * "WAVE" + * Arbno(format + data + misc) + * Pos(function() return StartPos + ChunkSize end) + * -function() return DataChunkSize % BlockAlign == 0 end + * RPos(0) + +assert(file:smatch(wave, spipat.match_anchored), + arg[1].." is not a valid WAVE file!") + +print(string.format( +"%s\ +Format: %u\ +Channels: %u\ +Samplerate: %u Hz\ +Byterate: %u Hz\ +Bits/Sample: %u\ +Samples: %u", +arg[1], +AudioFormat, NumChannels, SampleRate, ByteRate, BitsPerSample, DataChunkSize / BlockAlign)) +print(os.date("Length:\t\t%T", DataChunkSize / ByteRate + 60*60*23)) |