diff --git a/src/CUEParser.cpp b/src/CUEParser.cpp index 3de7be4..07e6b6e 100644 --- a/src/CUEParser.cpp +++ b/src/CUEParser.cpp @@ -67,11 +67,8 @@ const CUETrackInfo *CUEParser::next_track() const CUETrackInfo *CUEParser::next_track(uint64_t prev_file_size) { // Previous track info is needed to track file offset - uint32_t prev_track_start = m_track_info.track_start; m_track_info.cumulative_offset += m_track_info.unstored_pregap_length; - uint32_t prev_sector_length = get_sector_length(m_track_info.file_mode, m_track_info.track_mode); // Defaults to 2352 before first track - bool got_file = false; bool got_track = false; bool got_data = false; bool got_pause = false; // true if a period of silence (INDEX 00) was encountered for a track @@ -92,9 +89,6 @@ const CUETrackInfo *CUEParser::next_track(uint64_t prev_file_size) m_track_info.file_offset = 0; m_track_info.file_index++; m_track_info.track_mode = CUETrack_AUDIO; - prev_track_start = 0; - prev_sector_length = get_sector_length(m_track_info.file_mode, m_track_info.track_mode); - got_file = true; } else if (strncasecmp(m_parse_pos, "TRACK ", 6) == 0) { @@ -152,11 +146,12 @@ const CUETrackInfo *CUEParser::next_track(uint64_t prev_file_size) if (got_track && got_data) { - if (!got_file) - { - // Advance file position by the length of previous track - m_track_info.file_offset += (uint64_t)(m_track_info.track_start - (prev_track_start + m_track_info.cumulative_offset)) * prev_sector_length; - } + // File offsets are always calculated by the sector length of the current track, + // even in .cue files that mix different sector formats. This can result in some + // padding needed in the file between a 2048 byte data track and 2352 byte audio + // track. + m_track_info.file_offset = (uint64_t)(m_track_info.track_start - m_track_info.cumulative_offset - m_track_info.file_start) + * m_track_info.sector_length; if (got_pause) { diff --git a/test/CUEParser_test.cpp b/test/CUEParser_test.cpp index 1ce1c0e..eda8ba1 100644 --- a/test/CUEParser_test.cpp +++ b/test/CUEParser_test.cpp @@ -58,7 +58,7 @@ FILE "Sound.wav" WAVE { TEST(strcmp(track->filename, "Image Name.bin") == 0); TEST(track->file_mode == CUEFile_BINARY); - TEST(track->file_offset == 2048 * start2); + TEST(track->file_offset == 2352 * start2); TEST(track->track_number == 2); TEST(track->track_mode == CUETrack_AUDIO); TEST(track->sector_length == 2352); @@ -75,7 +75,7 @@ FILE "Sound.wav" WAVE { TEST(strcmp(track->filename, "Image Name.bin") == 0); TEST(track->file_mode == CUEFile_BINARY); - TEST(track->file_offset == 2048 * start2 + 2352 * (start3_i1 - start2)); + TEST(track->file_offset == 2352 * start3_i1); TEST(track->track_number == 3); TEST(track->track_mode == CUETrack_AUDIO); TEST(track->sector_length == 2352); @@ -427,15 +427,76 @@ FILE "mixed-cd.bin" BINARY return status; } +bool test_mixed_data_pregap_audio() +{ + bool status = true; + const char *cue_sheet = R"( + FILE "CD4.bin" BINARY + TRACK 01 MODE1/2048 + INDEX 01 00:00:00 + TRACK 02 AUDIO + PREGAP 00:02:00 + INDEX 01 01:52:48 + TRACK 03 AUDIO + PREGAP 00:01:74 + INDEX 01 05:09:58 +)"; + + CUEParser parser(cue_sheet); + COMMENT("test_mixed_data_pregap_audio"); + + COMMENT(" track 1"); + const CUETrackInfo *track = parser.next_track(); + TEST(track != NULL); + if (track) + { + TEST(track->file_mode == CUEFile_BINARY); + TEST(track->file_offset == 0); + TEST(track->data_start == 0); + TEST(track->unstored_pregap_length == 0); + TEST(track->stored_pregap_length == 0); + TEST(track->track_mode == CUETrack_MODE1_2048); + } + + COMMENT(" track 2"); + track = parser.next_track(); + TEST(track != NULL); + if (track) + { + TEST(track->track_mode == CUETrack_AUDIO); + TEST(track->file_offset == 0x12f3000); + TEST(track->data_start == 8598); + TEST(track->unstored_pregap_length == 2 * 75); + TEST(track->stored_pregap_length == 0); + } + + COMMENT(" track 3"); + track = parser.next_track(); + TEST(track != NULL); + if (track) + { + TEST(track->track_mode == CUETrack_AUDIO); + TEST(track->file_offset == 0x341cd30); + TEST(track->data_start == 23532); + TEST(track->unstored_pregap_length == 149); + TEST(track->stored_pregap_length == 0); + } + + return status; + +} + int main() { + // Use & to always run all tests even if some fail if (test_basics() - && test_datatracks() - && test_datatrackpregap() - && test_multifile() - && test_dot_slash_removal() - && test_long_filename() - && test_mixed_cd_pregap_and_index0() + & test_datatracks() + & test_datatrackpregap() + & test_multifile() + & test_dot_slash_removal() + & test_long_filename() + & test_mixed_cd_pregap_and_index0() + & test_mixed_data_pregap_audio() ) { return 0;