From 9ca55c96b02f53454a34ecffe1c861ea8d84abb3 Mon Sep 17 00:00:00 2001 From: "J. Morio Sakaguchi" Date: Fri, 13 Mar 2026 16:44:56 -0700 Subject: [PATCH] Fix unstored pregap offset regression The previous fix for mixed unstored and stored pregaps (CUE file PREGAP and INDEX 00) broke standard unstored pregap handling. --- src/CUEParser.cpp | 14 ++++++++++---- src/CUEParser.h | 4 ++++ test/CUEParser_test.cpp | 6 +++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/CUEParser.cpp b/src/CUEParser.cpp index 6aff446..3de7be4 100644 --- a/src/CUEParser.cpp +++ b/src/CUEParser.cpp @@ -75,7 +75,6 @@ const CUETrackInfo *CUEParser::next_track(uint64_t prev_file_size) 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 - uint32_t stored_pregap = 0; while(!(got_track && got_data) && start_line()) { if (strncasecmp(m_parse_pos, "FILE ", 5) == 0) @@ -105,6 +104,7 @@ const CUETrackInfo *CUEParser::next_track(uint64_t prev_file_size) m_track_info.track_mode = parse_track_mode(skip_space(endptr)); m_track_info.sector_length = get_sector_length(m_track_info.file_mode, m_track_info.track_mode); m_track_info.unstored_pregap_length = 0; + m_track_info.stored_pregap_length = 0; m_track_info.data_start = 0; m_track_info.track_start = 0; got_track = true; @@ -131,14 +131,12 @@ const CUETrackInfo *CUEParser::next_track(uint64_t prev_file_size) { // Stored pregap that is present both on CD and in data file m_track_info.track_start = m_track_info.file_start + time + m_track_info.cumulative_offset; - stored_pregap = time; got_pause = true; } else if (index == 1) { // Data content of the track m_track_info.data_start = m_track_info.file_start + time + m_track_info.cumulative_offset; - stored_pregap = time - stored_pregap; got_data = true; } } @@ -163,7 +161,15 @@ const CUETrackInfo *CUEParser::next_track(uint64_t prev_file_size) if (got_pause) { // Advance file position by any stored pregap - m_track_info.file_offset += stored_pregap * m_track_info.sector_length; + m_track_info.stored_pregap_length = m_track_info.data_start - m_track_info.track_start; + m_track_info.file_offset += (uint64_t)(m_track_info.stored_pregap_length) * m_track_info.sector_length; + m_track_info.track_start += m_track_info.unstored_pregap_length; + m_track_info.data_start += m_track_info.unstored_pregap_length; + } + else + { + uint32_t adjustment = m_track_info.data_start - (m_track_info.track_start + m_track_info.unstored_pregap_length); + m_track_info.file_offset += (uint64_t)adjustment * m_track_info.sector_length; } return &m_track_info; diff --git a/src/CUEParser.h b/src/CUEParser.h index a2937bd..02b9ff2 100644 --- a/src/CUEParser.h +++ b/src/CUEParser.h @@ -73,6 +73,10 @@ struct CUETrackInfo // These frames of silence are not stored in the underlying data file. uint32_t unstored_pregap_length; + // The CD frames of PREGAP time at the start of this track, + // which are present both on CD and in data file. + uint32_t stored_pregap_length; + // The cumulative lba offset of unstored data uint32_t cumulative_offset; diff --git a/test/CUEParser_test.cpp b/test/CUEParser_test.cpp index 4fe01ad..1ce1c0e 100644 --- a/test/CUEParser_test.cpp +++ b/test/CUEParser_test.cpp @@ -409,12 +409,12 @@ FILE "mixed-cd.bin" BINARY if (track) { uint32_t pregap_offset = 2 * 75; - uint32_t start2_i0 = ((29 * 60) + 9) * 75 + 48; - uint32_t start2_i1 = ((29 * 60) + 10) * 75 + 48; + uint32_t start2_i0 = ((29 * 60) + 9) * 75 + 48 + pregap_offset; + uint32_t start2_i1 = ((29 * 60) + 10) * 75 + 48 + pregap_offset; TEST(strcmp(track->filename, "mixed-cd.bin") == 0); TEST(track->file_mode == CUEFile_BINARY); - TEST(track->file_offset == start2_i1 * 2352); + TEST(track->file_offset == (start2_i1 - pregap_offset) * 2352); TEST(track->file_index == 1); TEST(track->track_number == 2); TEST(track->track_mode == CUETrack_AUDIO);