-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate proper test WAV files #55
Conversation
A simple solution would be to use MAT files instead. The disadvantage is that MAT files do not have a sample rate or a number of channels. This is probably not important for the tests though. |
I managed to create a (hopefully) proper WAV file with sox (see db6e428). Appending data still doesn't work correctly. For some inexplicable reason I get these values after appending in
Could you please have a look? |
This file was formatted quite weirdly.
I removed the It's been a while since I last modified binary data with a hex editor! |
Thanks for shedding some more light on this.
But according to Erik, the 'fact' chunk is necessary for float WAVs: libsndfile/libsndfile#70
How did you do that? I think it's not good to have an undocumented binary blob in the repository. I never thought it was so hard to get correct floating-point WAV files! We can probably create our simple test files with Python and the
This is the original error (because of the missing 'fact' chunk) which I tried to overcome by converting the malformed file with sox. |
Using a hex editor. RIFF/WAV files are pretty simple. The chunk length of the I can put that chunk back if you want, and only truncate the Seeing how difficult this is, I again propose to use MAT files instead. |
Yes please, it would be interesting to see if the tests work then. However, I think it would be much nicer if we could provide a script that generates our test files. I don't really know the different parts of a WAV file, but if you can tell me what byte (or group of bytes) means what, I could create a script that creates our two WAV files (and one RAW file) using the
I don't really like MAT files, because they are strongly associated with a certain proprietary software environment. And the whole reason why I'm supporting PySoundFile (and scientific Python in general) is to get away from it. Using MAT files now would feel like a personal defeat. Also, I don't see MAT as a proper sound file format. Of course it can be used like that (and libsndfile supports that), but to me this seems like an abuse of the MAT format. BTW, I just tried saving a MAT with PySoundFile (I've never done that before), and to my surprise the channels are stored along the rows! Are you using MAT files like that? |
Wave is a really simple format. At a basic level, it is a RIFF file. Riff files start with the letters
Next, the file type has to be specified:
After that, RIFF files contain one or more named chunks. Each named chunk starts with four characters as chunk identifier, then the chunk length as 32 bit integer (again excluding the chunk header itself), then the chunk content. For WAVE files, the first chunk is the
As far as I know, the next chunk is optional. At least, I have never seen it before this PM (documentation here). The linked website says that this should contain the number of samples, but sox put a 4 here, which would be number of frames:
Lastly, the data itself:
The |
Thanks for the detailed listing! I think having this script to generate the test files is better than just uploading un-documented binary files. The generated WAV-files are bit-wise identical to the ones we had before (with your manual changes) and the tests finally pass. Whether or not the 'fact' chunk is obligatory for float WAVs seems to be a grey area in the specification. I guess this is the official "standard" document: http://download.microsoft.com/download/9/8/6/9863C72A-A3AA-4DDB-B1BA-CA8D17EFD2D4/RIFFNEW.pdf On page 12 it says:
The question is whether WAVE_FORMAT_IEEE_FLOAT is considered a "new The information stored within the 'fact' chunk is of course completely redundant in the case of an uncompressed file, but the "standard" seems to require this information nevertheless. The meaning of the first number within the 'fact' chunk is also a little confusing. The first part ...
... doesn't help to much, but the second part clarifies things:
... therefore we must be talking about the number of frames. If there are no objections, I'd like to combine the last few (temporary) commits into one proper commit and then merge this PR. |
Sounds good! Generating the files by hand using the Come to think of it, we could use this fact to test the |
I combined some commits to a new commit 37756c8. Now that we don't have external dependencies, we could also create the test files on-the-fly before running the tests (e.g. with
That's what I wanted to do originally. Now this should be possible, we just have to add a 'peak' chunk to our float test file. I created a new issue for that: #56. If the changes in this PR are OK (and if you think we shouldn't create the test files on-the-fly), please merge. |
Generate proper test WAV files
Originally, I wanted to avoid creating the test files with the system under test, this just didn't seem right.
Therefore, I created the test WAV files with
scipy.io.wavfile.write()
.Recently, I found out that the 32-bit floating point WAV file is malformed.
See libsndfile/libsndfile#70 and scipy/scipy#3778.
I tried to find an alternative way to generate a floating point WAV file, but it's surprisingly hard to find something that doesn't involve libsndfile.
Sox produces correct files, but I didn't find a way to write specific floating-point values (like 1.0 and 0.75) to a file.
Is there a better way to create our test WAV files?
If not, I guess we'll have to create them with PySoundFile.
Another possibility would be to use only PCM test files (which can be generated correctly with many tools), but then we would have to add
dtype='float16'
in many places in the test code, which I originally wanted to avoid.