WAV reader: add support for RF64 files

This commit is contained in:
Moritz Bunkus 2019-12-02 22:35:08 +01:00
parent 7ed2cb502a
commit c96745578f
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
5 changed files with 63 additions and 3 deletions

View File

@ -26,6 +26,7 @@
* MKVToolNix GUI: update check: the dialog showing the latest news & version
information states explicitly where the links take the user (the MKVToolNix
`NEWS.md` file and YouTube respectively).
* mkvmerge: WAV reader: added support for reading RF64 files.
## Bug fixes

View File

@ -64,6 +64,10 @@ wav_reader_c::determine_type() {
&& !std::memcmp(&wheader.riff.wave_id, "WAVE", 4))
return type_e::wave;
if ( !std::memcmp(&wheader.riff.id, "RF64", 4)
&& !std::memcmp(&wheader.riff.wave_id, "WAVE", 4))
return type_e::rf64;
if ( !std::memcmp(w64_header.riff.guid, mtx::w64::g_guid_riff, 16)
&& !std::memcmp(w64_header.wave_guid, mtx::w64::g_guid_wave, 16))
return type_e::wave64;
@ -138,9 +142,9 @@ wav_reader_c::parse_file() {
void
wav_reader_c::dump_headers() {
mxinfo(fmt::format("File '{0}' header dump (mode: {1})\n", m_ti.m_fname, m_type == type_e::wave ? "WAV" : "Wave64"));
mxinfo(fmt::format("File '{0}' header dump (mode: {1})\n", m_ti.m_fname, m_type == type_e::rf64 ? "RF64" : m_type == type_e::wave ? "WAV" : "Wave64"));
if (m_type == type_e::wave)
if ((m_type == type_e::rf64) || (m_type == type_e::wave))
mxinfo(fmt::format(" riff:\n"
" id: {0}{1}{2}{3}\n"
" len: {4}\n"
@ -149,6 +153,13 @@ wav_reader_c::dump_headers() {
get_uint32_le(&m_wheader.riff.len),
char(m_wheader.riff.wave_id[0]), char(m_wheader.riff.wave_id[1]), char(m_wheader.riff.wave_id[2]), char(m_wheader.riff.wave_id[3])));
if (m_type == type_e::rf64)
mxinfo(fmt::format(" ds64:\n"
" riff_size: {0}\n"
" data_size: {1}\n"
" sample_count: {2}\n",
m_ds64.riff_size, m_ds64.data_size, m_ds64.sample_count));
mxinfo(fmt::format(" common:\n"
" wFormatTag: {0:04x}\n"
" wChannels: {1}\n"
@ -235,12 +246,47 @@ wav_reader_c::read(generic_packetizer_c *,
void
wav_reader_c::scan_chunks() {
if (m_type == type_e::wave)
if (m_type == type_e::rf64)
scan_chunks_rf64();
else if (m_type == type_e::wave)
scan_chunks_wave();
else
scan_chunks_wave64();
}
void
wav_reader_c::scan_chunks_rf64() {
scan_chunks_wave();
auto chunk_idx = find_chunk("ds64");
auto debug_chunks = debugging_c::requested("wav_reader|wav_reader_chunks");
if (!chunk_idx) {
mxdebug_if(debug_chunks, fmt::format("scan_chunks_rf64() no ds64 chunk found\n"));
throw mtx::input::header_parsing_x();
}
auto const &chunk = m_chunks[*chunk_idx];
mxdebug_if(debug_chunks, fmt::format("scan_chunks_rf64() found ds64 at {0} size {1}\n", chunk.pos, chunk.len));
if (chunk.len < 24)
throw mtx::input::header_parsing_x();
m_in->setFilePointer(chunk.pos);
m_ds64.riff_size = m_in->read_uint64_le();
m_ds64.data_size = m_in->read_uint64_le();
m_ds64.sample_count = m_in->read_uint64_le();
m_bytes_in_data_chunks = m_ds64.data_size;
chunk_idx = find_chunk("data");
if (chunk_idx)
m_chunks[*chunk_idx].len = m_ds64.data_size;
}
void
wav_reader_c::scan_chunks_wave() {
m_in->setFilePointer(0);

View File

@ -58,8 +58,13 @@ struct wav_chunk_t {
class wav_reader_c: public generic_reader_c {
public:
struct ds64_chunk_t {
uint64_t riff_size{}, data_size{}, sample_count{};
};
enum class type_e {
unknown,
rf64,
wave,
wave64,
};
@ -75,6 +80,7 @@ private:
wav_demuxer_cptr m_demuxer;
uint32_t m_format_tag;
ds64_chunk_t m_ds64;
public:
virtual mtx::file_type_e get_format_type() const {
@ -98,6 +104,7 @@ protected:
boost::optional<std::size_t> find_chunk(const char *id, int start_idx = 0, bool allow_empty = true);
void scan_chunks();
void scan_chunks_rf64();
void scan_chunks_wave();
void scan_chunks_wave64();

View File

@ -523,3 +523,4 @@ T_674ui_locale_bg_BG:dd68e655c0478092911742dc17732ad9-c4878d09282b7199ee7aac5860
T_675mp4_cover:fde70c906b8cd3e28f3575244e79b938-263986c0b88ed5d2e7e99bfc27e11077-060170d57bac3c83175be67abc289b27+060170d57bac3c83175be67abc289b27+true-ab252d885c54298aef5e588ca7a9caa3:passed:20191103-131313:0.260241763
T_676cover_art_vorbis_opus:51817472f0c8e80978da32091bdb0787-0cee77f31051e123a9e38ae2e9b728c2-72e193b0682dad985317cd03d2be1ab9+72e193b0682dad985317cd03d2be1ab9+true-11715255451ec40862d95c8a71c331ec-b36830d164a318af72c40cf6a2f57b1f-72e193b0682dad985317cd03d2be1ab9+72e193b0682dad985317cd03d2be1ab9+true-51817472f0c8e80978da32091bdb0787-df51bd4a5723741480be7c6fe2874a7e-e55849ace1748ac515b16881e397101a+e55849ace1748ac515b16881e397101a+true-11715255451ec40862d95c8a71c331ec-6c91f480a84a3ac81f51728a81f3706c-e55849ace1748ac515b16881e397101a+e55849ace1748ac515b16881e397101a+true:passed:20191110-132634:0.286118478
T_677vorbis_in_matroska_with_comments:41b4fa33ce8acdd4f98f2d8a2cf90874-e8ce8a969fb44adfbd6411d909d5f89f-d038d66d9c8d9af5b31103645640fb8d-517bbf85726d51c831b476d6cd503ec3-98b764f6d71c45e0302cd8ef65d1fb6d:passed:20191201-213124:0.250158232
T_678rf64:20f16e90d6877679fc0deada17ab520b:passed:20191202-223330:0.055722438

5
tests/test-678rf64.rb Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/ruby -w
# T_678rf64
describe "mkvmerge / reading WAV of type RF64"
test_merge "data/wav/v.rf64"