You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
1.7 KiB

from __future__ import annotations
import enum
from sx import Generic, Struct, parse
_Chunk = Generic('Chunk')
class FormatCompression(enum.Enum):
Unknown = 0
PCM = 1
ALaw = 6
MuLaw = 7
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)
if __name__ == '__main__':
import sys
print(parse(Chunk, open(sys.argv[1], 'rb')))