I’m currently updating juce_WavAudioFormat to support RF64 for > 4GB files, and as reading the following code lines (juce_WavAudioFormat.cpp), I’m wondering if it’s normal that ‘smpl’ chunk size is not taken into account for Master Riff header size??
Well, I’m not aware of how the smpl chunk works but I would have expected it to be a sub chunk of the RIFF chunk and thus the RIFF chunk size to include the size of smpl chunk…
ok makes more sense now
Now I just finished updating and validating my modifications on WavAudioFormat for RF64 (being able to write and read > 4GB wav files, following the MBWF/RF64 specifications http://tech.ebu.ch/docs/tech/tech3306-2009.pdf). Basically, the writer now creates fully compliant RIFF Wave file as far as the amount of audio data is small enough, and turns the header into an RF64 wave file on the fly when reaching the 32 bit limit.
Changes:
writer automatically switch to RF64 format when needed (audioDataChunkSize > 0xffffffff), using a ‘JUNK’ chunk for space reservation necessary to store eventual ‘ds64’ chunk as the file grows above the 4GB limit
reader can handle both RF64 and normal RIFF WAVE file
written format now use the WAVEFORMATEX structure rather than WAVEFORMAT
Would you be interested in integrating these changes in JUCE ?
Stupid question but if Juce uses int for sample indexes (for example, PositionableAudioSource::getNextReadPosition) isn’t it possible that a large-file WAV cannot have every sample individually addressed by a 32-bit signed integer?
true, but still allows to read about up to ~2+ hours 48k/24bit/stereo files (or even longer if resolution is higher) through PositionableAudioSource… which is more than the maximum length of a standard one disc album…
The AudioFormatReader already uses 64-bit values for addressing sample numbers, so it can read/write large files with no problem - it’s just PositionableAudioSource that doesn’t take advantage of this, but that could be tweaked.
Thanks for updating WavAudioFormat with these changes. I saw you removed the bool IsRF64() method from the reader/writer. Well I think this can still be useful for the reader, my experience being for example that it let me filtering the RF64 wav files and avoiding trying to tag them with TagLib (TagLib::RIFF parsing’s 32 bit indexing causes the ID3 Tag to be written over a part of the data chunk instead of being appended…).
I was just debugging an issue where WavAudioFormat wouldn’t read a regular wav file that is larget than 2gb - maybe it was introduced with the change discussed here.
else if (firstChunkType == chunkName ("RIFF"))
{
len = (uint64)(input->readInt());
end = input->getPosition() + len;
}
As far as I understand the Wav/RIFF format, the length is supposed to be an unsigned 32 bit value and so it should allow up to 4gb file sizes. But casting the signed integer returned by readInt() directly to uint64 leads to a wrong value for the file length (and then “end” becomes negative because it’s a signed int64).
Casting the length to uint32 first seems to fix this, but I have not yet properly tested it. I’d like to know first if this is a regression bug or there are indeed other reason why the WavAudioFormat won’t work with regular wav files between 2gb and 4gb size.
any chance this fix can merged back in the master branch? we’d like to do a maintenance release based on the pre-quake version, and this is the only patch we currently need to apply now that you backported the other plugin fixes