mirror of
https://github.com/iluvcapra/wavinfo.git
synced 2025-12-31 17:00:41 +00:00
Debugging with a jupyter notebook
This commit is contained in:
180
examples/wavinfo.ipynb
Normal file
180
examples/wavinfo.ipynb
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import wavinfo\n",
|
||||||
|
"import pprint"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"pp = pprint.PrettyPrinter(indent=4)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"testfile_path = \"../tests/test_files/\"\n",
|
||||||
|
"sound_devices_file = testfile_path + \"A101_1.WAV\"\n",
|
||||||
|
"\n",
|
||||||
|
"info = wavinfo.WavInfoReader(sound_devices_file)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 4,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"WavInfoFormat(audio_format=1, channel_count=2, sample_rate=48000, byte_rate=288000, block_align=6, bits_per_sample=24)\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"pp.pprint(info.fmt)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"WavBextFormat(description='sSPEED=023.976-ND\\r\\nsTAKE=1\\r\\nsUBITS=$12311801\\r\\nsSWVER=2.67\\r\\nsPROJECT=BMH\\r\\nsSCENE=A101\\r\\nsFILENAME=A101_1.WAV\\r\\nsTAPE=18Y12M31\\r\\nsTRK1=MKH516 A\\r\\nsTRK2=Boom\\r\\nsNOTE=', originator='Sound Dev: 702T S#GR1112089007', originator_ref='USSDVGR1112089007124001008206301', originator_date='2018-12-31', originator_time='12:40:00', time_reference=2190940753, version=1, 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, loudness_range=0, max_true_peak=0, max_momentary_loudness=0, max_shortterm_loudness=0, coding_history='A=PCM,F=48000,W=24,M=stereo,R=48000,T=2 Ch')\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"pp.pprint(info.bext)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"('BMH', 'A101', '1', 240239)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 6,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"info.ixml.project, info.ixml.scene, info.ixml.take, info.data.frame_count"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"pro_tools_file = testfile_path + \"PT A101_4.A1.wav\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 8,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"[ ChunkDescriptor(ident=b'bext', start=20, length=858),\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(pro_tools_file,'rb') as f:\n",
|
||||||
|
" chunk_tree = wavinfo.wave_parser.parse_chunk(f)\n",
|
||||||
|
"\n",
|
||||||
|
"pp.pprint(chunk_tree.children)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 9,
|
||||||
|
"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', 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=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, loudness_range=0, max_true_peak=0, max_momentary_loudness=0, max_shortterm_loudness=0, coding_history='A=PCM,F=48000,W=24,M=stereo,R=48000,T=2 Ch')\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"ptinfo = wavinfo.WavInfoReader(pro_tools_file)\n",
|
||||||
|
"\n",
|
||||||
|
"print(ptinfo.bext)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
||||||
@@ -9,10 +9,7 @@ class WavIXMLFormat:
|
|||||||
self.parsed = ET.fromstring(xml)
|
self.parsed = ET.fromstring(xml)
|
||||||
|
|
||||||
def _get_text_value(self, xpath):
|
def _get_text_value(self, xpath):
|
||||||
print("xpath",xpath)
|
|
||||||
print("search", "./" + xpath)
|
|
||||||
e = self.parsed.find("./" + xpath)
|
e = self.parsed.find("./" + xpath)
|
||||||
print("result was", e)
|
|
||||||
if e is not None:
|
if e is not None:
|
||||||
return e.text
|
return e.text
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
|
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
|
||||||
from .wave_ixml_reader import WavIXMLFormat
|
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
ListChunkDescriptor = namedtuple('ListChunk' , 'signature children')
|
ListChunkDescriptor = namedtuple('ListChunk' , 'signature children')
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import struct
|
|||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
WavDataDescriptor = namedtuple('WavDataDescriptor','byte_count frame_count')
|
from .wave_parser import parse_chunk
|
||||||
|
from .wave_ixml_reader import WavIXMLFormat
|
||||||
|
|
||||||
|
WavDataDescriptor = namedtuple('WavDataDescriptor','byte_count frame_count')
|
||||||
|
|
||||||
WavInfoFormat = namedtuple("WavInfoFormat",'audio_format channel_count sample_rate byte_rate block_align bits_per_sample')
|
WavInfoFormat = namedtuple("WavInfoFormat",'audio_format channel_count sample_rate byte_rate block_align bits_per_sample')
|
||||||
|
|
||||||
@@ -27,11 +29,11 @@ class WavInfoReader():
|
|||||||
self.main_list = chunks.children
|
self.main_list = chunks.children
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
|
|
||||||
self.fmt = self._get_format(self.main_list,f)
|
self.fmt = self._get_format(f)
|
||||||
self.bext = self._get_bext(self.main_list,f)
|
self.bext = self._get_bext(f)
|
||||||
self.ixml = self._get_ixml(self.main_list,f)
|
self.ixml = self._get_ixml(f)
|
||||||
|
|
||||||
self.data = delf._describe_data(self.main_list,f)
|
self.data = self._describe_data(f)
|
||||||
|
|
||||||
def _find_chunk_data(self, ident, from_stream, default_none=False):
|
def _find_chunk_data(self, ident, from_stream, default_none=False):
|
||||||
chunk_descriptor = None
|
chunk_descriptor = None
|
||||||
@@ -49,12 +51,13 @@ class WavInfoReader():
|
|||||||
def _describe_data(self,f):
|
def _describe_data(self,f):
|
||||||
data_chunk = next(c for c in self.main_list if c.ident == b'data')
|
data_chunk = next(c for c in self.main_list if c.ident == b'data')
|
||||||
|
|
||||||
return WavDataDescriptor(byte_count= data_chunk.length, frame_count= data_chunk.length / self.fmt.block_align)
|
return WavDataDescriptor(byte_count= data_chunk.length,
|
||||||
|
frame_count= int(data_chunk.length / self.fmt.block_align))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _get_format(self,chunks,f):
|
def _get_format(self,f):
|
||||||
fmt_data = se._find_chunk_data(b'fmt ',f)
|
fmt_data = self._find_chunk_data(b'fmt ',f)
|
||||||
|
|
||||||
# The format chunk is
|
# The format chunk is
|
||||||
# audio_format U16
|
# audio_format U16
|
||||||
@@ -63,7 +66,7 @@ class WavInfoReader():
|
|||||||
# byte_rate U32 == SampleRate * NumChannels * BitsPerSample/8
|
# byte_rate U32 == SampleRate * NumChannels * BitsPerSample/8
|
||||||
# block_align U16 == NumChannels * BitsPerSample/8
|
# block_align U16 == NumChannels * BitsPerSample/8
|
||||||
# bits_per_sampl U16
|
# bits_per_sampl U16
|
||||||
packstring = "<HHIIHH",
|
packstring = "<HHIIHH"
|
||||||
rest_starts = struct.calcsize(packstring)
|
rest_starts = struct.calcsize(packstring)
|
||||||
|
|
||||||
unpacked = struct.unpack(packstring, fmt_data[:rest_starts])
|
unpacked = struct.unpack(packstring, fmt_data[:rest_starts])
|
||||||
@@ -82,9 +85,9 @@ class WavInfoReader():
|
|||||||
bits_per_sample = unpacked[5]
|
bits_per_sample = unpacked[5]
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_bext(self,chunks,f):
|
def _get_bext(self,f):
|
||||||
|
|
||||||
bext_data = self._find_chunk_data(b'bext',f,default_none=True
|
bext_data = self._find_chunk_data(b'bext',f,default_none=True)
|
||||||
|
|
||||||
# description[256]
|
# description[256]
|
||||||
# originator[32]
|
# originator[32]
|
||||||
@@ -104,7 +107,7 @@ class WavInfoReader():
|
|||||||
# maxshorttermloudness S16 (LUFS*100)
|
# maxshorttermloudness S16 (LUFS*100)
|
||||||
# reserved[180]
|
# reserved[180]
|
||||||
# codinghistory []
|
# codinghistory []
|
||||||
if bext_data == None:
|
if bext_data is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
packstring = "<256s"+ "32s" + "32s" + "10s" + "8s" + "QH" + "64s" + "hhhhh" + "180s"
|
packstring = "<256s"+ "32s" + "32s" + "10s" + "8s" + "QH" + "64s" + "hhhhh" + "180s"
|
||||||
@@ -128,10 +131,10 @@ class WavInfoReader():
|
|||||||
coding_history = bext_data[rest_starts:].decode('ascii').rstrip(' \t\r\n\0')
|
coding_history = bext_data[rest_starts:].decode('ascii').rstrip(' \t\r\n\0')
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_ixml(self,chunks,f):
|
def _get_ixml(self,f):
|
||||||
|
|
||||||
ixml_data = self._find_chunk_data(b'iXML',f,default_none=True)
|
ixml_data = self._find_chunk_data(b'iXML',f,default_none=True)
|
||||||
if ixml_data == None:
|
if ixml_data is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
ixml_string = ixml_data.decode('utf-8')
|
ixml_string = ixml_data.decode('utf-8')
|
||||||
|
|||||||
Reference in New Issue
Block a user