Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track and restore the last audio position #387

Merged
merged 2 commits into from May 22, 2020
Merged

Track and restore the last audio position #387

merged 2 commits into from May 22, 2020

Conversation

@kcgen
Copy link
Member

@kcgen kcgen commented May 22, 2020

One of the enhancements in the CDDA code is tracking the 'read head' position to avoid unnecessary seeking during sequential decodes. This technique breaks down if the program mixes data reads with audio playback in the same track, such as in Secret of Monkey Island when using a single the BIN/CUE pair of its CDROM (ISO+tracks, or seprated BINs +CUE are not affected).

This PR now keeps track of the last audio position in all audio events that move the file pointer. It also now confirms and re-positions the track on subsequent audio events, if needed.

Thank you to @flashmasta for catching this and writing up a detailed issue!

Fixes #385 (the crux of the issue anyway).

@kcgen kcgen requested a review from dreamer May 22, 2020
@kcgen kcgen self-assigned this May 22, 2020
@kcgen kcgen added the bug label May 22, 2020
Copy link
Member

@dreamer dreamer left a comment

Seems OK, I'll do some tests.

PR description is a very good explanation of reasons behind this change - add it to the commit message, please.

@@ -143,6 +143,7 @@ class CDROM_Interface_Image : public CDROM_Interface
uint32_t adjustOverRead(const uint32_t offset,
const uint32_t requested_bytes);
int length_redbook_bytes = -1;
uint32_t audio_pos = (std::numeric_limits<uint32_t>::max)(); // last position when playing audio

This comment has been minimized.

@dreamer

dreamer May 22, 2020
Member

There's no need for parenthesis around ::max any more :)

This comment has been minimized.

@kcgen

kcgen May 22, 2020
Author Member

Excellent! I thought it was just the simpler min(a, b), max(a, b) functions; great to see us not pinned down by MSVC-custom stuff anymore.

This comment has been minimized.

@kcgen

kcgen May 22, 2020
Author Member

Fixed in 9963a43.

@@ -176,6 +178,8 @@ class CDROM_Interface_Image : public CDROM_Interface
Bit32u getRate() { return 44100; }
Bit8u getChannels() { return 2; }
int getLength();
void setAudioPosition(uint32_t pos) { audio_pos = pos; };

This comment has been minimized.

@dreamer

dreamer May 22, 2020
Member

Remove unnecessary semicolon.

This comment has been minimized.

@kcgen

kcgen May 22, 2020
Author Member

Fixed in 9963a43.

void setAudioPosition(uint32_t pos) { (void)pos; };
// This is a no-op because we track the audio position in all
// areas of this class.
Comment on lines 205 to 206

This comment has been minimized.

@dreamer

dreamer May 22, 2020
Member

Suggested change
void setAudioPosition(uint32_t pos) { (void)pos; };
// This is a no-op because we track the audio position in all
// areas of this class.
// This is a no-op because we track the audio position in all
// areas of this class.
void setAudioPosition(uint32_t) {}

This comment has been minimized.

@kcgen

kcgen May 22, 2020
Author Member

Folded into the main commit.

track_pos = requested_pos;
audio_pos = requested_pos;
else
audio_pos = {};

This comment has been minimized.

@dreamer

dreamer May 22, 2020
Member

Why not audio_pos = 0;?

This comment has been minimized.

@kcgen

kcgen May 22, 2020
Author Member

I had read somewhere that {} resets class/struct members back to their original initialized values, so I had wanted this to be std::numeric_limits<uint32_t>::max().

But alas.. that's a myth and it simply sets it to zero, which makes your comment perfectly valid! (to answer why we don't want to save 0 in the failed-seek case: if this function'srequested_pos argument was also 0 but we failed to seek to 0, then saving 0 would cause subsequent streaming-decodes to assume the track is correctly positioned when it's actually not; and is probably in a broken state).

I've added this correction back into the main commit.

@dreamer
Copy link
Member

@dreamer dreamer commented May 22, 2020

I did some testing with games mounting via cue/ogg and iso and in all cases CD audio playback worked fine, so there are no obvious regressions.

@kcgen
Copy link
Member Author

@kcgen kcgen commented May 22, 2020

Thanks @dreamer for the extra testing; I can also confirm tests are passing on my side too.

@kcgen kcgen force-pushed the kc/bin-pos-fix-1 branch from 392b649 to 522719e May 22, 2020
kcgen added 2 commits May 21, 2020
In the CDROM image code, we previously kept track of
the 'read head' to avoid unnecessary seeking and allow
sequential decode. This technique breaks down if the
program mixes data reads with audio playback in the
same track, such as in Secret of Monkey Island when
using a single the BIN/CUE pair of its CDROM
(ISO+tracks, or seprated BINs +CUE are not affected).

This commit now keeps track of the last audio position
in all audio events that move the file pointer. It also
now confirms and re-positions the track on subsequent
audio events, if needed.
@kcgen kcgen force-pushed the kc/bin-pos-fix-1 branch from 522719e to 9963a43 May 22, 2020
@dreamer dreamer merged commit bacd531 into master May 22, 2020
25 checks passed
25 checks passed
@github-actions
Script linters
Details
@github-actions
${{ matrix.conf.name }}
Details
@github-actions
${{ matrix.conf.name }}
Details
@github-actions
${{ matrix.conf.name }}
Details
@github-actions
Script linters
Details
@github-actions
GCC-5 (Ubuntu 16.04)
Details
@github-actions
PVS-Studio static analyzer
Details
@github-actions
MSVC 32-bit
Details
@github-actions
Clang
Details
@github-actions
GCC-7 (Ubuntu 18.04)
Details
@github-actions
MSVC 64-bit
Details
@github-actions
GCC-9
Details
@github-actions
GCC-9 (Ubuntu 18.04)
Details
@github-actions
Clang-8 (Ubuntu 18.04)
Details
@github-actions
Clang static analyzer
Details
@github-actions
Release build (dynamic)
Details
@github-actions
Release build (32-bit)
Details
@github-actions
Release build
Details
@github-actions
Clang static analyzer
Details
@github-actions
Release build (dynamic)
Details
@github-actions
Release build (32-bit)
Details
@github-actions
Release build
Details
@github-actions
${{ matrix.conf.name }} dynamic sanitizers
Details
@github-actions
Clang dynamic sanitizers
Details
@github-actions
GCC dynamic sanitizers
Details
@dreamer
Copy link
Member

@dreamer dreamer commented May 22, 2020

@kcgen Thanks! :) Merged to master, and I cherry-picked the first commit to the 0.75.x branch: 0ad071e

@kcgen kcgen deleted the kc/bin-pos-fix-1 branch May 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

2 participants