mirror of
https://github.com/iluvcapra/wavinfo.git
synced 2026-01-02 09:50:41 +00:00
Text cleanup/red policing
This commit is contained in:
@@ -8,17 +8,20 @@ class WavBextReader:
|
|||||||
"""
|
"""
|
||||||
Read Broadcast-WAV extended metadata.
|
Read Broadcast-WAV extended metadata.
|
||||||
:param bext_data: The bytes-like data.
|
:param bext_data: The bytes-like data.
|
||||||
:param encoding: The encoding to use when decoding the text fields of the
|
:param encoding: The encoding to use when decoding the text fields of
|
||||||
BEXT metadata scope. According to EBU Rec 3285 this shall be ASCII.
|
the BEXT metadata scope. According to EBU Rec 3285 this shall be
|
||||||
|
ASCII.
|
||||||
"""
|
"""
|
||||||
packstring = "<256s" + "32s" + "32s" + "10s" + "8s" + "QH" + "64s" + "hhhhh" + "180s"
|
packstring = "<256s" + "32s" + "32s" + "10s" + "8s" + "QH" + "64s" + \
|
||||||
|
"hhhhh" + "180s"
|
||||||
|
|
||||||
rest_starts = struct.calcsize(packstring)
|
rest_starts = struct.calcsize(packstring)
|
||||||
unpacked = struct.unpack(packstring, bext_data[:rest_starts])
|
unpacked = struct.unpack(packstring, bext_data[:rest_starts])
|
||||||
|
|
||||||
def sanitize_bytes(b : bytes) -> str:
|
def sanitize_bytes(b : bytes) -> str:
|
||||||
# honestly can't remember why I'm stripping nulls this way
|
# honestly can't remember why I'm stripping nulls this way
|
||||||
first_null = next((index for index, byte in enumerate(b) if byte == 0), None)
|
first_null = next((index for index, byte in enumerate(b) \
|
||||||
|
if byte == 0), None)
|
||||||
trimmed = b if first_null is None else b[:first_null]
|
trimmed = b if first_null is None else b[:first_null]
|
||||||
decoded = trimmed.decode(encoding)
|
decoded = trimmed.decode(encoding)
|
||||||
return decoded
|
return decoded
|
||||||
@@ -50,8 +53,8 @@ class WavBextReader:
|
|||||||
#: BEXT version.
|
#: BEXT version.
|
||||||
self.version : int = unpacked[6]
|
self.version : int = unpacked[6]
|
||||||
|
|
||||||
#: SMPTE 330M UMID of this audio file, 64 bytes are allocated though the UMID
|
#: SMPTE 330M UMID of this audio file, 64 bytes are allocated though
|
||||||
#: may only be 32 bytes long.
|
#: the UMID may only be 32 bytes long.
|
||||||
self.umid : Optional[bytes] = None
|
self.umid : Optional[bytes] = None
|
||||||
|
|
||||||
#: EBU R128 Integrated loudness, in LUFS.
|
#: EBU R128 Integrated loudness, in LUFS.
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ class CueEntry(NamedTuple):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def read(cls, data: bytes) -> 'CueEntry':
|
def read(cls, data: bytes) -> 'CueEntry':
|
||||||
assert len(data) == cls.format_size(), \
|
assert len(data) == cls.format_size(), \
|
||||||
f"cue data size incorrect, expected {calcsize(cls.Format)} found {len(data)}"
|
(f"cue data size incorrect, expected {calcsize(cls.Format)} "
|
||||||
|
"found {len(data)}")
|
||||||
|
|
||||||
parsed = unpack(cls.Format, data)
|
parsed = unpack(cls.Format, data)
|
||||||
|
|
||||||
|
|||||||
@@ -208,8 +208,8 @@ class DolbyDigitalPlusMetadata:
|
|||||||
|
|
||||||
class PreferredDownMixMode(Enum):
|
class PreferredDownMixMode(Enum):
|
||||||
"""
|
"""
|
||||||
Indicates the creating engineer's preference of what the receiver should
|
Indicates the creating engineer's preference of what the receiver
|
||||||
downmix.
|
should downmix.
|
||||||
§ 4.3.8.1
|
§ 4.3.8.1
|
||||||
"""
|
"""
|
||||||
NOT_INDICATED = 0b00
|
NOT_INDICATED = 0b00
|
||||||
@@ -386,7 +386,8 @@ class DolbyDigitalPlusMetadata:
|
|||||||
|
|
||||||
# downmix_mode, ltrt_center_downmix_level, ltrt_surround_downmix_level
|
# downmix_mode, ltrt_center_downmix_level, ltrt_surround_downmix_level
|
||||||
def ext_bsi1_word2(b):
|
def ext_bsi1_word2(b):
|
||||||
return DolbyDigitalPlusMetadata.PreferredDownMixMode(b & 0xC0 >> 6), \
|
return DolbyDigitalPlusMetadata\
|
||||||
|
.PreferredDownMixMode(b & 0xC0 >> 6), \
|
||||||
DolbyDigitalPlusMetadata.DownMixLevelToken(b & 0x38 >> 3), \
|
DolbyDigitalPlusMetadata.DownMixLevelToken(b & 0x38 >> 3), \
|
||||||
DolbyDigitalPlusMetadata.DownMixLevelToken(b & 0x7)
|
DolbyDigitalPlusMetadata.DownMixLevelToken(b & 0x7)
|
||||||
|
|
||||||
@@ -423,14 +424,19 @@ class DolbyDigitalPlusMetadata:
|
|||||||
pid = program_id(buffer[0])
|
pid = program_id(buffer[0])
|
||||||
lfe_on, bitstream_mode, audio_coding_mode = program_info(buffer[1])
|
lfe_on, bitstream_mode, audio_coding_mode = program_info(buffer[1])
|
||||||
ddplus_reserved1(buffer[2:2])
|
ddplus_reserved1(buffer[2:2])
|
||||||
center_downmix_level, surround_downmix_level, dolby_surround_encoded = surround_config(buffer[4])
|
center_downmix_level, surround_downmix_level, \
|
||||||
langcode_present, copyright_bitstream, original_bitstream, dialnorm = dialnorm_info(buffer[5])
|
dolby_surround_encoded = surround_config(buffer[4])
|
||||||
|
langcode_present, copyright_bitstream, original_bitstream, \
|
||||||
|
dialnorm = dialnorm_info(buffer[5])
|
||||||
langcode = langcod(buffer[6])
|
langcode = langcod(buffer[6])
|
||||||
prod_info_exists, mixlevel, roomtype = audio_prod_info(buffer[7])
|
prod_info_exists, mixlevel, roomtype = audio_prod_info(buffer[7])
|
||||||
|
|
||||||
loro_center_downmix_level, loro_surround_downmix_level = ext_bsi1_word1(buffer[8])
|
loro_center_downmix_level, \
|
||||||
downmix_mode, ltrt_center_downmix_level, ltrt_surround_downmix_level = ext_bsi1_word2(buffer[9])
|
loro_surround_downmix_level = ext_bsi1_word1(buffer[8])
|
||||||
surround_ex_mode, dolby_headphone_encoded, ad_converter_type = ext_bsi2_word1(buffer[10])
|
downmix_mode, ltrt_center_downmix_level, \
|
||||||
|
ltrt_surround_downmix_level = ext_bsi1_word2(buffer[9])
|
||||||
|
surround_ex_mode, dolby_headphone_encoded, \
|
||||||
|
ad_converter_type = ext_bsi2_word1(buffer[10])
|
||||||
|
|
||||||
ddplus_reserved2(buffer[11:14])
|
ddplus_reserved2(buffer[11:14])
|
||||||
compression = compr1(buffer[14])
|
compression = compr1(buffer[14])
|
||||||
@@ -494,8 +500,9 @@ class DolbyAtmosMetadata:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, data: bytes):
|
def load(cls, data: bytes):
|
||||||
assert len(data) == cls.SEGMENT_LENGTH, "DolbyAtmosMetadata segment "\
|
assert len(data) == cls.SEGMENT_LENGTH, ("DolbyAtmosMetadata segment "
|
||||||
"is incorrect length, expected %i actual was %i" % (cls.SEGMENT_LENGTH, len(data))
|
"is incorrect length, "
|
||||||
|
"expected %i actual was %i") % (cls.SEGMENT_LENGTH, len(data))
|
||||||
|
|
||||||
h = BytesIO(data)
|
h = BytesIO(data)
|
||||||
|
|
||||||
@@ -513,7 +520,9 @@ class DolbyAtmosMetadata:
|
|||||||
warp_mode = a_val & 0x7
|
warp_mode = a_val & 0x7
|
||||||
|
|
||||||
return DolbyAtmosMetadata(tool_name=toolname,
|
return DolbyAtmosMetadata(tool_name=toolname,
|
||||||
tool_version=(major, minor, fix), warp_mode=DolbyAtmosMetadata.WarpMode(warp_mode))
|
tool_version=(major, minor, fix),
|
||||||
|
warp_mode=DolbyAtmosMetadata\
|
||||||
|
.WarpMode(warp_mode))
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -521,7 +530,8 @@ class DolbyAtmosSupplementalMetadata:
|
|||||||
"""
|
"""
|
||||||
Dolby Atmos supplemental metadata segment.
|
Dolby Atmos supplemental metadata segment.
|
||||||
|
|
||||||
https://github.com/DolbyLaboratories/dbmd-atmos-parser/blob/master/dbmd_atmos_parse/src/dbmd_atmos_parse.c
|
https://github.com/DolbyLaboratories/dbmd-atmos-parser/blob/
|
||||||
|
master/dbmd_atmos_parse/src/dbmd_atmos_parse.c
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class BinauralRenderMode(Enum):
|
class BinauralRenderMode(Enum):
|
||||||
@@ -617,7 +627,8 @@ class WavDolbyMetadataReader:
|
|||||||
else:
|
else:
|
||||||
seg_size = unpack("<H", h.read(2))[0]
|
seg_size = unpack("<H", h.read(2))[0]
|
||||||
seg_payload = h.read(seg_size)
|
seg_payload = h.read(seg_size)
|
||||||
expected_checksum = WavDolbyMetadataReader.segment_checksum(seg_payload, seg_size)
|
expected_checksum = WavDolbyMetadataReader\
|
||||||
|
.segment_checksum(seg_payload, seg_size)
|
||||||
checksum = unpack("B", h.read(1))[0]
|
checksum = unpack("B", h.read(1))[0]
|
||||||
|
|
||||||
segment = seg_payload
|
segment = seg_payload
|
||||||
@@ -628,7 +639,8 @@ class WavDolbyMetadataReader:
|
|||||||
elif stype == SegmentType.DolbyAtmosSupplemental:
|
elif stype == SegmentType.DolbyAtmosSupplemental:
|
||||||
segment = DolbyAtmosSupplementalMetadata.load(segment)
|
segment = DolbyAtmosSupplementalMetadata.load(segment)
|
||||||
|
|
||||||
self.segment_list.append( (stype, checksum == expected_checksum, segment) )
|
self.segment_list\
|
||||||
|
.append((stype, checksum == expected_checksum, segment))
|
||||||
|
|
||||||
def dolby_digital_plus(self) -> List[DolbyDigitalPlusMetadata]:
|
def dolby_digital_plus(self) -> List[DolbyDigitalPlusMetadata]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user