classification
Title: wave module sets data subchunk size incorrectly when writing wav file
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: Jeff.Pursell, python-dev, r.david.murray, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2010-04-04 13:36 by Jeff.Pursell, last changed 2014-03-08 17:54 by python-dev. This issue is now closed.

Files
File name Uploaded Description Edit
testTone.zip Jeff.Pursell, 2010-04-04 13:36 zip file containing 2 .py files to demonstrate bug
wave_test_write_array.patch serhiy.storchaka, 2013-09-04 13:48 review
audio_write_nonbytes.patch serhiy.storchaka, 2013-10-14 11:43 review
audio_write_nonbytes_2.patch serhiy.storchaka, 2013-11-10 19:49 review
Messages (9)
msg102342 - (view) Author: Jeff Pursell (Jeff.Pursell) Date: 2010-04-04 13:36
I tried to create a 4 second file and only heard the first 2 seconds.  The file size was correct for a 44.1 kHz, 16 bit mono file at 4 seconds, but both aplay and audactiy ignored the second half of the file.  I went to this page https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ and opened the output with a hex editor in little endian mode.  I found that at offset 40, the data chunk size was wrong.  It looked like it was just set to the number of samples.  It should be the number of samples times bytes-per-sample (2) times number-of-channels (1 in my case).  I manually set the number from 176400 to 352800 and that solved the problem for that wav file.

I'm guessing this was just an oversight and the fix will be simple.

I'll attach the code I used to generate the test tone.  Just run python -i testTone.py and it will generate out.wav with the incorrect field.

I am using pything 2.6.4 in ubuntu.
msg102346 - (view) Author: Jeff Pursell (Jeff.Pursell) Date: 2010-04-04 17:57
Here's my fix.  The left file is the original and the right file is my version.  Perhaps someone should check this patch on a big endian machine to make sure there are no issues there.  I do not anticipate any issues.

416c416
<         nframes = len(data) // (self._sampwidth * self._nchannels)
---
>         nframes = len(data) // self._nchannels
427c427
<             self._datawritten = self._datawritten + len(data)
---
>             self._datawritten = self._datawritten + len(data) * self._sampwidth
463c463
<             self._nframes = initlength / (self._nchannels * self._sampwidth)
---
>             self._nframes = initlength // self._nchannels
msg102349 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-04-04 20:31
Any chance you could create a unit test for this? (The current set of tests is...pretty minimal.)  Also, having the patch in unified diff format relative to the top of the source three would be helpful (although this one is small enough we could certainly apply it by hand, having a unified diff makes it more likely someone will test it).
msg196915 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2013-09-04 13:48
It's because you write an array of integers while writeframes() expects a bytes object.

Here is a test.
msg199871 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2013-10-14 11:43
Here is a patch for all three audio modules. After dropping support of string (which is meanless) in the audioop module (issue16685) it can be simplified.

I doubt that this should be applied in maintenance releases. Support of non-bytes arguments in writerawframes() is a new feature.
msg202561 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2013-11-10 19:49
Here is simplified patch. Added versionchanged tags in the documentation.
msg203032 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2013-11-16 12:07
Committed in changeset b96f4ee1b08b.
msg203033 - (view) Author: Roundup Robot (python-dev) Date: 2013-11-16 12:09
New changeset 932db179585d by Serhiy Storchaka in branch 'default':
Fixed issue number for issue #8311.
http://hg.python.org/cpython/rev/932db179585d
msg212939 - (view) Author: Roundup Robot (python-dev) Date: 2014-03-08 17:54
New changeset b72615222c98 by R David Murray in branch 'default':
whatsnew: sunau/aifc/wave writeframes[raw] accept any bytes-like (#8311)
http://hg.python.org/cpython/rev/b72615222c98
History
Date User Action Args
2014-03-08 17:54:17python-devsetmessages: + msg212939
2013-11-16 12:09:22python-devsetnosy: + python-dev
messages: + msg203033
2013-11-16 12:07:43serhiy.storchakasetmessages: + msg203032
2013-11-16 12:06:03serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2013-11-10 19:49:48serhiy.storchakasetfiles: + audio_write_nonbytes_2.patch

messages: + msg202561
2013-10-14 11:43:26serhiy.storchakasetfiles: + audio_write_nonbytes.patch
versions: - Python 2.7, Python 3.3
messages: + msg199871

assignee: serhiy.storchaka
type: behavior -> enhancement
stage: needs patch -> patch review
2013-09-04 13:48:28serhiy.storchakasetfiles: + wave_test_write_array.patch
versions: + Python 2.7, Python 3.3, Python 3.4, - Python 2.6
messages: + msg196915

keywords: + patch
stage: test needed -> needs patch
2013-09-03 20:47:49serhiy.storchakasetnosy: + serhiy.storchaka
2010-04-04 20:31:04r.david.murraysetpriority: normal

nosy: + r.david.murray
messages: + msg102349

components: + Library (Lib), - Extension Modules
stage: test needed
2010-04-04 17:57:10Jeff.Pursellsetmessages: + msg102346
2010-04-04 13:36:51Jeff.Pursellcreate