Initial commit
This commit is contained in:
56
ackit/convert.py
Normal file
56
ackit/convert.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""WEM <-> Ogg Vorbis conversion using the game's codebook library."""
|
||||
from .codebooks import CodebookLibrary
|
||||
from .ogg import OggWriter
|
||||
from .wem import Wem
|
||||
from .wwvorbis import (W2V, transcode_setup, build_id_header, build_comment_header,
|
||||
ww_packet_to_vorbis)
|
||||
|
||||
_LIB = None
|
||||
|
||||
|
||||
def library() -> CodebookLibrary:
|
||||
global _LIB
|
||||
if _LIB is None:
|
||||
_LIB = CodebookLibrary()
|
||||
return _LIB
|
||||
|
||||
|
||||
def packet_samples(blockflags, bs0, bs1):
|
||||
"""Samples produced by each packet (Vorbis overlap-add rule)."""
|
||||
out = []
|
||||
prev = None
|
||||
for bf in blockflags:
|
||||
cur = bs1 if bf else bs0
|
||||
out.append(0 if prev is None else (prev // 4 + cur // 4))
|
||||
prev = cur
|
||||
return out
|
||||
|
||||
|
||||
def wem_to_ogg(wem: Wem):
|
||||
"""Returns (ogg_bytes, details dict)."""
|
||||
lib = library()
|
||||
v = wem.vorb
|
||||
setup, info = transcode_setup(wem.setup_packet(), W2V, wem.channels, lib)
|
||||
pkts, end = wem.audio_packets()
|
||||
out_pkts = []
|
||||
flags = []
|
||||
prev_bf = 0
|
||||
for i, (_, p) in enumerate(pkts):
|
||||
nxt = pkts[i + 1][1][0] if i + 1 < len(pkts) else None
|
||||
op, bf = ww_packet_to_vorbis(p, nxt, info, prev_bf, v["bs0_exp"] != v["bs1_exp"])
|
||||
out_pkts.append(op)
|
||||
flags.append(bf)
|
||||
prev_bf = bf
|
||||
bs0, bs1 = 1 << v["bs0_exp"], 1 << v["bs1_exp"]
|
||||
samples = packet_samples(flags, bs0, bs1)
|
||||
ow = OggWriter()
|
||||
ow.page([build_id_header(wem.channels, wem.rate, v["bs0_exp"], v["bs1_exp"])], 0, bos=True)
|
||||
ow.page([build_comment_header(), setup], 0)
|
||||
g = 0
|
||||
total = v["total_frames"]
|
||||
for i, op in enumerate(out_pkts):
|
||||
g += samples[i]
|
||||
last = i == len(out_pkts) - 1
|
||||
ow.page([op], min(g, total) if last else g, eos=last)
|
||||
return ow.bytes(), dict(info=info, flags=flags, samples=samples, packets=pkts, data_end=end,
|
||||
sum_samples=sum(samples))
|
||||
Reference in New Issue
Block a user