All existing tests pass

This commit is contained in:
Jamie Hardt
2023-11-06 16:24:01 -08:00
parent 16d2609558
commit 77517db653
2 changed files with 29 additions and 15 deletions

View File

@@ -11,8 +11,8 @@ from dataclasses import dataclass
import encodings
from .riff_parser import ChunkDescriptor
from struct import unpack, unpack_from, calcsize
from typing import Optional, NamedTuple, List
from struct import unpack, calcsize
from typing import Optional, NamedTuple, List, Dict, Any
#: Country Codes used in the RIFF standard to resolve locale. These codes
#: appear in CSET and LTXT metadata.
@@ -113,8 +113,8 @@ class CueEntry(NamedTuple):
@classmethod
def read(cls, data: bytes) -> 'CueEntry':
assert len(data) == calcsize(cls.Format), \
"cue data size incorrect, expected {calcsize(cls.Format)} found {len(cues_data)}"
assert len(data) == cls.format_size(), \
f"cue data size incorrect, expected {calcsize(cls.Format)} found {len(data)}"
parsed = unpack(cls.Format, data)
@@ -178,12 +178,13 @@ class WavCuesReader:
if cues is not None:
cues_data = cues.read_data(f)
assert len(cues_data) >= 4, "cue metadata too short"
cues_count = unpack("<I", cues_data)
offset = calcsize("<I")
for _ in cues_count:
cue_bytes = cues_data[offset: CueEntry.format_size() ]
cues_count = unpack("<I", cues_data[0:offset])
for _ in range(cues_count[0]):
cue_bytes = cues_data[offset: offset + CueEntry.format_size()]
cue_list.append(CueEntry.read(cue_bytes))
offset += CueEntry.format_size()
label_list = []
for labl in labls:
@@ -202,6 +203,12 @@ class WavCuesReader:
return WavCuesReader(cues=cue_list, labels=label_list,
ranges=range_list)
def to_dict(self) -> Dict[str, Any]:
return dict(cues=[c.__dict__ for c in self.cues],
labels=[l.__dict__ for l in self.labels],
ranges=[r.__dict__ for r in self.ranges])

View File

@@ -73,6 +73,9 @@ class WavInfoReader:
#: RIFF INFO metadata.
self.info :Optional[WavInfoChunkReader]= None
#: RIFF CUE, LABL and LTXT metadata.
self.cues :Optional[WavCuesReader] = None
if hasattr(path, 'read'):
self.get_wav_info(path)
self.url = 'about:blank'
@@ -102,7 +105,7 @@ class WavInfoReader:
self.adm = self._get_adm(wavfile)
self.info = self._get_info(wavfile, encoding=self.info_encoding)
self.dolby = self._get_dbmd(wavfile)
# self.cue = self._get_cue(wavfile)
self.cues = self._get_cue(wavfile)
self.data = self._describe_data()
def _find_chunk_data(self, ident, from_stream, default_none=False) -> Optional[bytes]:
@@ -188,15 +191,19 @@ class WavInfoReader:
return WavIXMLFormat(ixml_data.rstrip(b'\0')) if ixml_data else None
def _get_cue(self, f):
cue = next((cue_chunk for cue_chunk in self.main_list if cue_chunk.ident == b'cue '), None)
cue = next((cue_chunk for cue_chunk in self.main_list if \
type(cue_chunk) is ChunkDescriptor and \
cue_chunk.ident == b'cue '), None)
adtl = self._find_list_chunk(b'adtl')
labls = []
ltxts = []
if adtl is not None:
labls = [child.read_data(f) for child in adtl.children if child.ident == b'labl']
ltxts = [child.read_data(f) for child in adtl.children if child.ident == b'ltxt']
labls = [child for child in adtl.children if child.ident == b'labl']
ltxts = [child for child in adtl.children if child.ident == b'ltxt']
return WavCuesReader.merge(f, cue, labls, ltxts)
return WavCuesReader.merge(f, cue, labls, ltxts,
fallback_encoding=self.info_encoding)
def walk(self) -> Generator[str,str,Any]: #FIXME: this should probably be named "iter()"
"""
@@ -204,10 +211,10 @@ class WavInfoReader:
:yields: tuples of the *scope*, *key*, and *value* of
each metadatum. The *scope* value will be one of
"fmt", "data", "ixml", "bext", "info", "dolby", "cue" or "adm".
"fmt", "data", "ixml", "bext", "info", "dolby", "cues" or "adm".
"""
scopes = ('fmt', 'data', 'ixml', 'bext', 'info', 'adm', 'dolby')
scopes = ('fmt', 'data', 'ixml', 'bext', 'info', 'adm', 'cues', 'dolby')
for scope in scopes:
if scope in ['fmt', 'data']: