iluvcapra / wavinfo

Probe WAVE Files for all metadata
https://wavinfo.readthedocs.io/
MIT License
36 stars 7 forks source link

IXML on Zoom F8 #1

Closed iluvcapra closed 5 years ago

iluvcapra commented 5 years ago

I came across your project whilst looking for ways to read iXML data from WAVs for a task I need to do.  It’s really good, however,  I tried it on some files recorded from a ZOOM F8 Multitrack recorder and it always raise an exception parsing the xml.  I ran the tests that came with the project and all is good, but it still failed with these files as below:

Traceback (most recent call last):   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_reader.py", line 162, in     info = WavInfoReader(path)   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_reader.py", line 62, in init     self.ixml   = self._get_ixml(f)   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_reader.py", line 141, in _get_ixml     return WavIXMLFormat(ixml_string)   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_ixml_reader.py", line 15, in init     self.parsed = ET.parse(xmlBytes)   File "/Users/declan/pybuild/py27/lib/python2.7/xml/etree/ElementTree.py", line 1182, in parse     tree.parse(source, parser)   File "/Users/declan/pybuild/py27/lib/python2.7/xml/etree/ElementTree.py", line 656, in parse     parser.feed(data)   File "/Users/declan/pybuild/py27/lib/python2.7/xml/etree/ElementTree.py", line 1642, in feed     self._raiseerror(v)   File "/Users/declan/pybuild/py27/lib/python2.7/xml/etree/ElementTree.py", line 1506, in _raiseerror     raise err xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 66, column 9

On further inspection it would seem that the Zoom recorder uses all the 5226 bytes allocated and fills them with 0, so I have added the following line in wav_reader.py at line 138:

ixml_string = ixml_data[0:ixml_data.find(chr(0))] Not sure what the consequences of this are but seems to work and doesn’t break the test cases.

I’m also adding in some more properties to extract track details such as channel number and name.

Let me know if this is of interest and whether I’m on the right track & if you want me to formally add the changes to a branch and add new test cases etc.

duffdiode commented 5 years ago

The ZoomF8.zip contains two output types from the Zoom F8 Multichannel recorder. MULTI - This contains a multichannel recorded file (10 channels) DISCRETE - This contains discrete files for all the channels recorded, all mono except the L_R pair. ZoomF8.zip

iluvcapra commented 5 years ago

From email

The following error gets raised:

Traceback (most recent call last):   File "/Users/declan/git/WAV/wavinfo/tests/test_wave_parsing.py", line 83, in test_bext_against_ffprobe     info = wavinfo.WavInfoReader(wav_file)   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_reader.py", line 59, in init     self.bext   = self._get_bext(f, encoding=bext_encoding)   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_reader.py", line 130, in _get_bext     return WavBextReader(bext_data, encoding)   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_bext_reader.py", line 27, in init     self.description     = sanatize_bytes(unpacked[0])   File "/Users/declan/git/WAV/wavinfo/wavinfo/wave_bext_reader.py", line 23, in sanatize_bytes     decoded = trimmed.decode(encoding) UnicodeDecodeError: 'ascii' codec can't decode byte 0xbf in position 53: ordinal not in range(128)

I changed wave_bext_reader.py line 17  from

first_null = next( (index for index, byte in enumerate(bytes) if byte == 0), None ) to first_null = next( (index for index, byte in enumerate(bytes) if byte == chr(0)), None ) and now all nulls are removed from all the fields and the tests run. (this is in addition to the iXML fix)

I will record some various test files on the recorder and upload them. I will do:

• multitrack wave • separate waves for same take • add comments / shot logging • rename on the recorder to build history in the iXML (not sure if this will get recorded)

Regards

iluvcapra commented 5 years ago

@iluvcapra

Dopey question, but what is your python version?

@duffdiode

It’s not a dopey question, I’m using 2.7.14 and I note this is a python 3 project, so the import is for my setup. Would the null testing also be different though?

@iluvcapra

I believe it would, as a matter of fact; struct.unpack in Python 3 returns and array of bytes while in Python 2 it returns a string.

iluvcapra commented 5 years ago

@duffdiode I've just added aline to strip trailing nulls from an iXML chunk as soon as it's read in, this should address the issue as long as you're running in Python 3.