mackron / dr_libs

Audio decoding libraries for C/C++, each in a single source file.
Other
1.24k stars 205 forks source link

dr_wav bext is before fmt #243

Closed Youlean closed 1 year ago

Youlean commented 1 year ago

It seems that Pro Tools sets bext chunk before fmt. It is not possible to read bext chunk since dr_wav checks metadata only after the fmt.

I am thinking to seek file to start once metadata phrase begins. Would that make sense?

Youlean commented 1 year ago

I manage to fix the issue. The solution is to seek to the file start before processing the metadata. Also, I have added some code to skip the unknown Pro Tools metadata.


DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_unknown_chunk(drwav__metadata_parser* pParser, const drwav_uint8* pChunkId, drwav_uint64 chunkSize, drwav_metadata_location location)
{
    drwav_uint64 bytesRead = 0;

    if (location == drwav_metadata_location_invalid) {
        return 0;
    }

    /* Skip unknown these chunks */
    if (drwav_fourcc_equal(pChunkId, "data") || 
        drwav_fourcc_equal(pChunkId, "ds64") || 
        drwav_fourcc_equal(pChunkId, "fmt ") || 
        drwav_fourcc_equal(pChunkId, "fact")) {
        return 0;
    }

    /* Skip unknown Pro Tools chunks */
    if (drwav_fourcc_equal(pChunkId, "minf") ||
        drwav_fourcc_equal(pChunkId, "elm1") ||
        drwav_fourcc_equal(pChunkId, "regn") ||
        drwav_fourcc_equal(pChunkId, "umid") ||
        drwav_fourcc_equal(pChunkId, "DGDA") ||
        drwav_fourcc_equal(pChunkId, "JUNK")) {
      return 0;
    }

----------------------------------------------------------------------------------------

/* Store cursor before ds64 as we will need it to seek to the file start in order to capture metadata that is before the ds64 and fmt */
    drwav_uint64 cursorBeforeDs64 = cursor;

    /* For RF64, the "ds64" chunk must come next, before the "fmt " chunk. */`

----------------------------------------------------------------------------------------

    /* Set cursor and seek to a position before ds64 and fmt in order to capture metadata that is before the ds64 and fmt */
    cursor = cursorBeforeDs64;

    if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) {
      return DRWAV_FALSE;
    }

    /* Basic validation. */
mackron commented 1 year ago

Thanks for reporting this. I've finally got around to addressing this. It's in the dev branch if you were wanting to try it.