Skip to content

Commit

Permalink
All existing tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
iluvcapra committed Nov 7, 2023
1 parent 16d2609 commit 77517db
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 15 deletions.
23 changes: 15 additions & 8 deletions wavinfo/wave_cues_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
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.
Expand Down Expand Up @@ -113,8 +113,8 @@ def format_size(cls) -> int:

@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)

Expand Down Expand Up @@ -178,12 +178,13 @@ def merge(cls, f,
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:
Expand All @@ -202,6 +203,12 @@ def merge(cls, f,
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])





Expand Down
21 changes: 14 additions & 7 deletions wavinfo/wave_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def __init__(self, path, info_encoding='latin_1', bext_encoding='ascii'):
#: 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'
Expand Down Expand Up @@ -102,7 +105,7 @@ def get_wav_info(self, wavfile):
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]:
Expand Down Expand Up @@ -188,26 +191,30 @@ def _get_ixml(self, f):
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()"
"""
Walk all of the available metadata fields.
: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']:
Expand Down

0 comments on commit 77517db

Please sign in to comment.