77 lines
1.7 KiB
Python
77 lines
1.7 KiB
Python
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')))
|