Documentation

This commit is contained in:
Jamie Hardt
2022-11-26 18:25:12 -08:00
parent a7f77a49f7
commit af5c83b8fc
6 changed files with 126 additions and 21 deletions

View File

@@ -0,0 +1,94 @@
Using `wavinfo` from the Command Line
=====================================
`wavinfo` installs a command-line entry point that will read wav files
from the command line and output metadata to stdout.
.. code-block:: shell
$ wavinfo [--ixml | --adm] INFILE +
By default, `wavinfo` will output a JSON dictionary for each file argument.
Options
-------
Two option flags will change the behavior of the command:
``--ixml``
The *\-\-ixml* flag will cause `wavinfo` to output the iXML metadata payload
of each input wave file, or will emit an error message to stderr if iXML
metadata is not present.
``--adm``
The *\-\-adm* flag will cause `wavinfo` to output the ADM XML metadata
payload of each input wave file, or will emit an error message to stderr if
ADM XML metadata is not present.
These options are mutually-exclusive, with `\-\-adm` taking precedence.
Example Output
--------------
.. code-block:: javascript
{
"filename": "tests/test_files/sounddevices/A101_1.WAV",
"run_date": "2022-11-26T17:56:38.342935",
"application": "wavinfo 2.1.0",
"scopes": {
"fmt": {
"audio_format": 1,
"channel_count": 2,
"sample_rate": 48000,
"byte_rate": 288000,
"block_align": 6,
"bits_per_sample": 24
},
"data": {
"byte_count": 1441434,
"frame_count": 240239
},
"ixml": {
"track_list": [
{
"channel_index": "1",
"interleave_index": "1",
"name": "MKH516 A",
"function": ""
},
{
"channel_index": "2",
"interleave_index": "2",
"name": "Boom",
"function": ""
}
],
"project": "BMH",
"scene": "A101",
"take": "1",
"tape": "18Y12M31",
"family_uid": "USSDVGR1112089007124001008206300",
"family_name": null
},
"bext": {
"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=\r\n",
"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": "0000000000000000000000000000000000000000000000000000000000000000",
"coding_history": "A=PCM,F=48000,W=24,M=stereo,R=48000,T=2 Ch\r\n",
"loudness_value": null,
"loudness_range": null,
"max_true_peak": null,
"max_momentary_loudness": null,
"max_shortterm_loudness": null
}
}
}

View File

@@ -13,14 +13,12 @@ music production metadata.
.. toctree::
:maxdepth: 1
:caption: Notes
:glob:
:numbered:
quickstart
scopes/bext.rst
scopes/ixml.rst
scopes/adm.rst
scopes/dolby.rst
scopes/info.rst
command_line
scopes/*
classes

View File

@@ -1,6 +1,11 @@
wavinfo Quickstart
====================
All metadata is read by an instance of :class:`WaveInfoReader<wavinfo.wave_reader.WavInfoReader>`.
Each type of metadata, iXML, Broadcast-WAV etc. is accessible through *scopes*, properties on an
instance of :class:`WaveInfoReader`.
.. code-block:: python
:caption: Using wavinfo

View File

@@ -8,7 +8,7 @@ class TestWalk(unittest.TestCase):
info = wavinfo.WavInfoReader(test_file)
tested_data , tested_format = False, False
for scope, key, value in info.walk():
for scope, key, value in info.iter():
if scope == 'fmt':
if key == 'channel_count':
tested_format = True

View File

@@ -1,6 +1,7 @@
from optparse import OptionParser, OptionGroup
import datetime
from . import WavInfoReader
from . import __version__
import sys
import json
from enum import Enum
@@ -18,7 +19,7 @@ class MissingDataError(RuntimeError):
def main():
parser = OptionParser()
parser.usage = 'wavinfo [FILES]'
parser.usage = 'wavinfo (--adm | --ixml) [FILES]'
# parser.add_option('-f', dest='output_format', help='Set the output format',
# default='json',
@@ -38,15 +39,20 @@ def main():
if this_file.adm:
sys.stdout.write(this_file.adm.xml_str())
else:
raise MissingDataError("--adm option active but ADM metadata not present")
raise MissingDataError("adm")
elif options.ixml:
if this_file.ixml:
sys.stdout.write(this_file.ixml.xml_bytes())
else:
raise MissingDataError("--ixml option active but iXML metadata not present")
raise MissingDataError("ixml")
else:
ret_dict = {'file_argument': arg, 'run_date': datetime.datetime.now().isoformat() , 'scopes': {}}
for scope, name, value in this_file.walk():
ret_dict = {
'filename': arg,
'run_date': datetime.datetime.now().isoformat() ,
'application': "wavinfo " + __version__,
'scopes': {}
}
for scope, name, value in this_file.iter():
if scope not in ret_dict['scopes'].keys():
ret_dict['scopes'][scope] = {}
@@ -54,8 +60,7 @@ def main():
json.dump(ret_dict, cls=MyJSONEncoder, fp=sys.stdout, indent=2)
except MissingDataError as e:
print("Missing metadata error in file %s" % arg, file=sys.stderr)
print(e, file=sys.stderr)
print("MissingDataError: Missing metadata (%s) in file %s" % (e, arg), file=sys.stderr)
continue
except Exception as e:
raise e

View File

@@ -64,22 +64,25 @@ class WavInfoReader:
self.path = absolute_path
#: Wave audio data format
#: Wave audio data format.
self.fmt :Optional[WavAudioFormat] = None
#: Broadcast-Wave metadata
#: Statistics of the `data` section.
self.data :Optional[WavDataDescriptor] = None
#: Broadcast-Wave metadata.
self.bext :Optional[WavBextReader] = None
#: iXML metadata
#: iXML metadata.
self.ixml :Optional[WavIXMLFormat] = None
#: ADM Audio Definiton Model metadata
#: ADM Audio Definiton Model metadata.
self.adm :Optional[WavADMReader]= None
#: Dolby Bitstream Metadata
#: Dolby bitstream metadata.
self.dolby :Optional[WavDolbyMetadataReader] = None
#: RIFF INFO Metadata
#: RIFF INFO metadata.
self.info :Optional[WavInfoChunkReader]= None
with open(path, 'rb') as f:
@@ -163,7 +166,7 @@ class WavInfoReader:
ixml_data = self._find_chunk_data(b'iXML', f, default_none=True)
return WavIXMLFormat(ixml_data.rstrip(b'\0')) if ixml_data else None
def walk(self) -> Generator[str,str,Any]:
def iter(self) -> Generator[str,str,Any]:
"""
Walk all of the available metadata fields.