diff --git a/examples/wavinfo.ipynb b/examples/wavinfo.ipynb index be36e03..513b43d 100644 --- a/examples/wavinfo.ipynb +++ b/examples/wavinfo.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -21,18 +21,18 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "metacorder_path = '../tests/test_files/metacorder/Sr001-001-06_01.WAV'\n", + "path = '../tests/test_files/protools/PT A101_4.A1.wav'\n", "\n", - "info = wavinfo.WavInfoReader(metacorder_path)" + "info = wavinfo.WavInfoReader(path)" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": { "scrolled": true }, @@ -42,17 +42,19 @@ "output_type": "stream", "text": [ "[ ChunkDescriptor(ident=b'bext', start=20, length=858),\n", - " ChunkDescriptor(ident=b'fmt ', start=886, length=16),\n", - " ChunkDescriptor(ident=b'data', start=910, length=1725696),\n", - " ChunkDescriptor(ident=b'iXML', start=1726614, length=2852),\n", - " ChunkDescriptor(ident=b'iXTC', start=1729474, length=20)]\n" + " ChunkDescriptor(ident=b'iXML', start=886, length=5226),\n", + " ChunkDescriptor(ident=b'fmt ', start=6120, length=16),\n", + " ChunkDescriptor(ident=b'data', start=6144, length=864840),\n", + " ChunkDescriptor(ident=b'umid', start=870992, length=24),\n", + " ChunkDescriptor(ident=b'minf', start=871024, length=16),\n", + " ChunkDescriptor(ident=b'regn', start=871048, length=92)]\n" ] } ], "source": [ "import wavinfo.wave_parser\n", "\n", - "with open(metacorder_path,'rb') as f:\n", + "with open(path,'rb') as f:\n", " chunk_tree = wavinfo.wave_parser.parse_chunk(f)\n", "\n", "pp.pprint(chunk_tree.children)" @@ -60,69 +62,68 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 5, "metadata": {}, - "outputs": [], - "source": [ - "# with open(metacorder_path,'rb') as f:\n", - "# f.seek(chunk_tree.children[4].start)\n", - "# iXTC_data = f.read(chunk_tree.children[4].length)\n", - " \n", - "# print(iXTC_data)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "scrolled": true - }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "WavBextFormat(description='gSCENE=001\\r\\ngTAKE=06\\r\\ngTAPE=Sr001\\r\\ngUBITS=00000000\\r\\n', originator='Metacorder Demo', originator_ref='', originator_date='2019:01:01', originator_time='13:36:16', time_reference=2350375830, version=0, umid=b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00', loudness_value=0.0, loudness_range=0.0, max_true_peak=0.0, max_momentary_loudness=0.0, max_shortterm_loudness=0.0, coding_history='')\n" + "b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00*\\xfd\\xf5\\x0c$\\xe4s\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\n", + "000000000000002afdf50c24e47380000000000000000000\n", + "24\n" ] } ], "source": [ - "with open(metacorder_path,'rb') as f:\n", - " f.seek(chunk_tree.children[0].start)\n", - " bext_raw = f.read(chunk_tree.children[0].length)\n", - "\n", - "# ptinfo = wavinfo.WavInfoReader(metacorder_path)\n", - "\n", - "print(wavinfo.WavInfoReader(metacorder_path).bext)" + "with open(path,'rb') as f:\n", + " f.seek( chunk_tree.children[4].start )\n", + " umid_bin = f.read(chunk_tree.children[4].length)\n", + " f.seek( chunk_tree.children[6].start )\n", + " regn_bin = f.read(chunk_tree.children[6].length)\n", + " \n", + "print(umid_bin)\n", + "print(umid_bin.hex())\n", + "print(len(umid_bin))" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WavBextFormat(description='dUBITS=12311804\\r\\ndSCENE=A101\\r\\ndTAKE=4\\r\\ndTAPE=18Y12M31\\r\\ndFRAMERATE=23.976ND\\r\\ndSPEED=023.976-NDF\\r\\ndTRK1=MKH516 A\\r\\ndTRK2=Boom\\r\\n', originator='Sound Dev: 702T S#GR1112089007', originator_ref='aa4CKtcd13Vk', originator_date='2018-12-31', originator_time='12:40:07', time_reference=2191709524, version=0, umid=None, loudness_value=0.0, loudness_range=0.0, max_true_peak=0.0, max_momentary_loudness=0.0, max_shortterm_loudness=0.0, coding_history='A=PCM,F=48000,W=24,M=stereo,R=48000,T=2 Ch\\r\\n')\n" + ] + } + ], "source": [ - "library_sound = testfile_path + 'BULLET Impact Plastic LCD TV Screen Shatter Debris 2x.wav'\n", - "\n", - "recinfo = wavinfo.WavInfoReader(library_sound)\n", - "\n", - "recinfo.ixml.source" + "print(info.bext)" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "b'\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00*\\xfd\\xf5\\x0c$\\xe4s\\x80\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0c3\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00T\\xd5\\xa2\\x82\\x00\\x00\\x00\\x00\\x10PT A101_4.A1.wavGK\\xaa\\xaf\\x7f\\x00\\x00@ }\\x06\\x00`\\x00\\x00'\n", + "01000000000000000000002afdf50c24e473800000000000000000000c330200000000000000000000000000000000000000000054d5a2820000000010505420413130315f342e41312e776176474baaaf7f000040207d0600600000\n", + "92\n" + ] + } + ], "source": [ - "with open(library_sound,'rb') as f:\n", - " chunk_tree = wavinfo.wave_parser.parse_chunk(f)\n", "\n", - "pp.pprint(chunk_tree.children)" + "print(regn_bin)\n", + "print(regn_bin.hex())\n", + "print(len(regn_bin))" ] }, { diff --git a/tests/test_wave_parsing.py b/tests/test_wave_parsing.py index 2057403..29295d9 100644 --- a/tests/test_wave_parsing.py +++ b/tests/test_wave_parsing.py @@ -71,7 +71,7 @@ class TestWaveInfo(TestCase): if 'originator_reference' in ffprobe_info['format']['tags']: self.assertEqual( info.bext.originator_ref, ffprobe_info['format']['tags']['originator_reference'] ) else: - self.assertEqual( info.bext.originator_ref, None) + self.assertEqual( info.bext.originator_ref, '') # these don't always reflect the bext info #self.assertEqual( info.bext.originator_date, ffprobe_info['format']['tags']['date'] ) @@ -79,12 +79,9 @@ class TestWaveInfo(TestCase): self.assertEqual( info.bext.time_reference, int(ffprobe_info['format']['tags']['time_reference']) ) if 'coding_history' in ffprobe_info['format']['tags']: - if len(ffprobe_info['format']['tags']['coding_history']) > 0: - self.assertEqual( info.bext.coding_history, ffprobe_info['format']['tags']['coding_history'] ) - else: - self.assertEqual( info.bext.coding_history, None ) + self.assertEqual( info.bext.coding_history, ffprobe_info['format']['tags']['coding_history'] ) else: - self.assertEqual( info.bext.coding_history, None ) + self.assertEqual( info.bext.coding_history, '' ) def test_ixml(self): expected = {'A101_4.WAV': {'project' : 'BMH', 'scene': 'A101', 'take': '4', diff --git a/wavinfo/wave_reader.py b/wavinfo/wave_reader.py index 3253902..7978324 100644 --- a/wavinfo/wave_reader.py +++ b/wavinfo/wave_reader.py @@ -125,10 +125,26 @@ class WavInfoReader(): trimmed = bytes decoded = trimmed.decode(encoding) - if len(decoded) > 0: - return decoded - else: - return None + return decoded + + bext_version = unpacked[6] + if bext_version > 0: + umid = unpacked[6] + else: + umid = None + + if bext_version > 1: + loudness_value = unpacked[8] / 100.0, + loudness_range = unpacked[9] / 100.0 + max_true_peak = unpacked[10] / 100.0 + max_momentary_loudness = unpacked[11] / 100.0 + max_shortterm_loudness = unpacked[12] / 100.0 + else: + loudness_value = None + loudness_range = None + max_true_peak = None + max_momentary_loudness = None + max_shortterm_loudness = None return WavBextFormat(description=sanatize_bytes(unpacked[0]), originator = sanatize_bytes(unpacked[1]), @@ -137,12 +153,12 @@ class WavInfoReader(): originator_time = sanatize_bytes(unpacked[4]), time_reference = unpacked[5], version = unpacked[6], - umid = unpacked[7], - loudness_value = unpacked[8] / 100.0, - loudness_range = unpacked[9] / 100.0, - max_true_peak = unpacked[10] / 100.0, - max_momentary_loudness = unpacked[11] / 100.0, - max_shortterm_loudness = unpacked[12] / 100.0, + umid = umid, + loudness_value = loudness_value, + loudness_range = loudness_range, + max_true_peak = max_true_peak, + max_momentary_loudness = max_momentary_loudness, + max_shortterm_loudness = max_shortterm_loudness, coding_history = sanatize_bytes(bext_data[rest_starts:]) )