From 75395b59226e654af0be7fe6ce3898bbec263398 Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Thu, 8 Dec 2022 02:32:51 +0000 Subject: [PATCH] Steinberg metadata impl in progress --- wavinfo/wave_ixml_reader.py | 187 +++++++++++++++++++++++++----------- 1 file changed, 133 insertions(+), 54 deletions(-) diff --git a/wavinfo/wave_ixml_reader.py b/wavinfo/wave_ixml_reader.py index 5dd92a7..d4f39c1 100644 --- a/wavinfo/wave_ixml_reader.py +++ b/wavinfo/wave_ixml_reader.py @@ -2,10 +2,69 @@ from lxml import etree as ET import io from collections import namedtuple from typing import Optional +from enum import IntEnum IXMLTrack = namedtuple('IXMLTrack', ['channel_index', 'interleave_index', 'name', 'function']) +class SteinbergMetadata: + """ + Vendor-specific Steinberg metadata + """ + + class AudioSpeakerArrangement(IntEnum): + """ + Steinberg speaker format enumeration. + """ + MONO = 0 + STEREO = 1 + LRC = 10 + LRCS = 14 + QUAD = 15 + CINE_50 = 18 + CINE_51 = 19 + CINE_60 = 20 + CINE_61 = 22 + CINE_70 = 25 + CINE_71 = 27 + SDDS_70 = 24 + SDDS_71 = 26 + MUSIC_60 = 21 #?? + MUSIC_61 = 23 + ATMOS_712 = 33 + ATMOS_504 = 35 + ATMOS_514 = 36 + ATMOS_714 = 44 + ATMOS_702 = 48 + ATMOS_716 = 51 + ATMOS_914 = 53 + ATMOS_916 = 55 + AMB_1ORDER = 45 + AMB_2ORDER = 46 + AMB_3ORDER = 47 + AURO_10_0 = 37 + AURO_10_1 = 38 + AURO_11_0 = 39 + AURO_11_1 = 40 + AURO_13_0 = 41 + AURO_13_1 = 42 + + def __init__(self, xml : ET.ElementTree) -> None: + """ + Parse Steinberg iXML data + :param xml: The entire iXML Tree + """ + self.parsed = xml.find("//BWFXML/STEINBERG") + + @property + def audio_speaker_arrangement(self) -> AudioSpeakerArrangement: + val = self.parsed.find("./ATTR_LIST/ATTR[NAME/text() = 'AudioSpeakerArrangement']/VALUE/text()") + return type(self).AudioSpeakerArrangement(int(val)) + + + + + class WavIXMLFormat: """ iXML recorder metadata. @@ -18,7 +77,7 @@ class WavIXMLFormat: self.source = xml xml_bytes = io.BytesIO(xml) parser = ET.XMLParser(recover=True) - self.parsed = ET.parse(xml_bytes, parser=parser) + self.parsed : ET.ElementTree = ET.parse(xml_bytes, parser=parser) def _get_text_value(self, xpath) -> Optional[str]: e = self.parsed.find("./" + xpath) @@ -31,7 +90,7 @@ class WavIXMLFormat: return ET.tostring(self.parsed).decode("utf-8") @property - def raw_xml(self): + def raw_xml(self) -> ET.ElementTree: """ The root entity of the iXML document. """ @@ -94,6 +153,13 @@ class WavIXMLFormat: """ return self._get_text_value("FILE_SET/FAMILY_NAME") + @property + def steinberg(self) -> Optional[SteinbergMetadata]: + """ + Steinberg vendor iXML metadata if present. + """ + return SteinbergMetadata(self.raw_xml) + def to_dict(self): return dict(track_list=list(map(lambda x: x._asdict(), self.track_list)), project=self.project, @@ -105,44 +171,79 @@ class WavIXMLFormat: ) # Nuendo Audio Speaker Arrangement Codes -# tests/test_files/nuendo//wavinfo Test Project - Audio - 5.0.wav -# 18 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 5.1.4.wav -# 36 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.1 SDDS.wav -# 26 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.0 SDDS.wav -# 24 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 5.1.wav -# 19 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.1.wav -# 27 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 7.0.2.wav -# 48 + + + + + +# Nuendo Keys +# AudioSampleFormatSize, AudioSpeakerArrangement, MediaCompany, MediaDropFrames, MediaDuration(float) (seconds, session length?), +# MediaStartTime(float), MediaTrackTitle, ProgramName, ProgramVersion, + + + + # tests/test_files/nuendo//wavinfo Test Project - Audio - LRCS.wav # 14 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.0.wav -# 25 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 6.0 Music.wav -# 23 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 7.1.2.wav -# 33 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 5.0.4.wav -# 35 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Mono.wav -# 0 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Quad.wav -# 15 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 7.1.4.wav -# 44 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 6.1 Music.wav -# 23 # tests/test_files/nuendo//wavinfo Test Project - Audio - Stereo.wav # 1 # tests/test_files/nuendo//wavinfo Test Project - Audio - LRC.wav # 10 +# tests/test_files/nuendo//wavinfo Test Project - Audio - Mono.wav +# 0 +# tests/test_files/nuendo//wavinfo Test Project - Audio - Quad.wav +# 15 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 5.1.wav +# 19 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 5.0.wav +# 18 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 6.1 Surround EX.wav +# 22 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 6.0 Surround EX.wav +# 20 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.1 SDDS.wav +# 26 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.0 SDDS.wav +# 24 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.0.wav +# 25 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 7.1.wav +# 27 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 6.1 Music.wav +# 23 + +# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 7.1.2.wav +# 33 +# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 5.0.4.wav +# 35 +# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 5.1.4.wav +# 36 + +# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 7.0.2.wav +# 48 +# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 7.1.4.wav +# 44 + # tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 7.1.6.wav # 51 + +# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 9.1.4.wav +# 53 +# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 9.1.6.wav +# 55 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 3OA.wav +# 47 + +# tests/test_files/nuendo//wavinfo Test Project - Audio - 1OA.wav +# 45 +# tests/test_files/nuendo//wavinfo Test Project - Audio - 2OA.wav +# 46 + +# tests/test_files/nuendo//wavinfo Test Project - Audio - Auro3d 10.0.wav +# 37 +# tests/test_files/nuendo//wavinfo Test Project - Audio - Auro3d 10.1.wav +# 38 + # tests/test_files/nuendo//wavinfo Test Project - Audio - Auro3d 13.1.wav # 42 # tests/test_files/nuendo//wavinfo Test Project - Audio - Auro3d 13.0.wav @@ -151,25 +252,3 @@ class WavIXMLFormat: # 39 # tests/test_files/nuendo//wavinfo Test Project - Audio - Auro3d 11.1.wav # 40 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 6.1 Surround EX.wav -# 22 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 2OA.wav -# 46 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Auro3d 10.0.wav -# 37 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Auro3d 10.1.wav -# 38 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 6.0 Surround EX.wav -# 20 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 3OA.wav -# 47 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 9.1.4.wav -# 53 -# tests/test_files/nuendo//wavinfo Test Project - Audio - Atmos 9.1.6.wav -# 55 -# tests/test_files/nuendo//wavinfo Test Project - Audio - 1OA.wav -# 45 - -# Nuendo Keys -# AudioSampleFormatSize, AudioSpeakerArrangement, MediaCompany, MediaDropFrames, MediaDuration(float) (seconds, session length?), -# MediaStartTime(float), MediaTrackTitle, ProgramName, ProgramVersion, \ No newline at end of file