diff --git a/examples/riff.py b/examples/riff.py new file mode 100644 index 0000000..6381e26 --- /dev/null +++ b/examples/riff.py @@ -0,0 +1,76 @@ +from __future__ import annotations +import enum +from sx import Generic, Struct, parse + + +_Chunk = Generic('Chunk') + +class FormatCompression(enum.Enum): + Unknown = 0 + PCM = 1 + MSADPCM = 2 + ALaw = 6 + MuLaw = 7 + IMAADPCM = 17 + G723ADPCM = 20 + GSM610 = 49 + G721ADPCM = 64 + MPEG = 80 + Experimental = 0xFFFF + +class FormatChunk(Struct, partial=True): + compression: Enum(FormatCompression, uint16le) + channel_count: uint16le + sample_rate: uint32le + bytes_per_sec: uint32le + alignment: uint16le + bits_per_sample: uint16le + extra_length: uint16le + extra: Data(self.extra_length) + +class FactChunk(Struct): + sample_count: uint32le + +class SampleLoop(Struct): + id: uint32le + type: uint32le + start: uint32le + end: uint32le + fraction: uint32le + count: uint32le + +class SampleChunk(Struct): + manufacturer: uint32le + product: uint32le + period: uint32le + unity_note: uint32le + pitch_fraction: uint32le + smtpe_format: uint32le + smpte_offset: uint32le + sample_loop_count: uint32le + padding_length: uint32le + sample_loops: Arr(SampleLoop, count=self.sample_loop_count) + +class DataChunk(Struct): + data: data + +class RIFFChunk(Struct): + type: Fixed(b'WAVE') + children: Arr(_Chunk) + +class Chunk(Struct): + type: Data(4) + length: uint32le + contents: Sized(Switch({ + b'fmt ': FormatChunk, + b'fact': FactChunk, + b'smpl': SampleChunk, + b'data': DataChunk, + b'RIFF': RIFFChunk, + }, fallback=DataChunk, selector=self.type), self.length) + +_Chunk.push(Chunk) + +if __name__ == '__main__': + import sys + print(parse(Chunk, open(sys.argv[1], 'rb')))