Skip to content

Add channel seek and playback position support#15

Merged
na2axl merged 3 commits into
AmplitudeAudio:developfrom
applebutter180:seek-channel-playback-position
May 31, 2026
Merged

Add channel seek and playback position support#15
na2axl merged 3 commits into
AmplitudeAudio:developfrom
applebutter180:seek-channel-playback-position

Conversation

@applebutter180

@applebutter180 applebutter180 commented May 9, 2026

Copy link
Copy Markdown
Contributor

Add public Channel APIs for setting and querying playback position:
SetPlaybackPosition(AmTime) and GetPlaybackPosition(). The public API uses
AmTime milliseconds, while the mixer continues to use frame-based cursors
internally.

Keep v1 behavior scoped to single-layer channels and blended instancing.
Separate instancing remains unsupported for channel-level playback-position
control and is rejected with a warning. The internal RealChannel::Seek()
path is retained as the implementation detail behind the public API.

Defer playback cursor changes through the Amplimix command queue so cursor
updates run after the current mix iteration. Add AmplimixImpl::ResetLayerState()
to reset the layer data converter and pipeline through ResetPipeline() after
a cursor change, avoiding direct mixer-state mutation during audio rendering.

Add and update tests for normal playback-position changes, paused changes,
playback-position advancement, blended instancing, separate-instancing
rejection, negative position clamping, invalid/stale channel state rejection,
invalid mixer cursor operations, and CI-stable playback cleanup.

This should address #14

Add public Channel APIs for seeking to an AmTime playback position and
querying the current playback position. Wire the calls through channel
state, real channels, and Amplimix cursor access using millisecond-based
public units and frame-based mixer cursors internally.

Keep v1 behavior scoped to single-layer channels and blended instancing,
while warning and rejecting separate instancing. Reset converter and
pipeline state on the mixer thread after cursor changes to avoid racing
audio teardown, and preserve audio converter channel conversion state
across resets.

Add tests for normal seek, paused seek, playback-position advancement,
blended instancing, separate-instancing rejection, and converter reset
configuration preservation.

Co-Authored-By: Codex GPT-5.5 High <noreply@openai.com>
@na2axl na2axl added the enhancement New feature or request label May 9, 2026

@na2axl na2axl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@applebutter180 thank you for your contribution. Here is a small initial review before further tests:

I don't recommend to set the cursor right away. It's better to make use of the command system in Amplimix to push a SetCursor+ResetState command to be executed right after the current mix loop iteration. That will ensure no possible reads of sound data during update. GetCursor() is safe since it only reads data.

You can do that directly in RealChannel::Seek(), with something like:

_mixer->PushCommand([this, layerId = data.mixerLayerId, cursor]() {
  _mixer->SetCursor(_channelId, layerId, cursor);
  _mixer->ResetLayerState(_channelId, layerId); // You may need to create this method
  return true;
});

Amplimix::ResetLayerState() will:

  1. Get the pointer to the layer
  2. Reset the data converter
  3. Reset the pipeline (but using AmplimixLayerImpl::ResetPipeline() insted of raw reset)

Comment thread include/SparkyStudios/Audio/Amplitude/Core/Playback/Channel.h Outdated
Comment thread include/SparkyStudios/Audio/Amplitude/Core/Playback/Channel.h Outdated
@codecov

codecov Bot commented May 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.90411% with 30 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Mixer/RealChannel.cpp 37.84% 13 Missing and 10 partials ⚠️
src/Mixer/Amplimix.cpp 75.00% 0 Missing and 3 partials ⚠️
src/Core/Playback/Channel.cpp 75.00% 0 Missing and 2 partials ⚠️
src/Core/Playback/ChannelInternalState.cpp 87.50% 0 Missing and 2 partials ⚠️
Files with missing lines Coverage Δ
src/Core/Playback/ChannelInternalState.h 86.67% <ø> (ø)
src/DSP/AudioConverter.cpp 67.45% <ø> (-8.42%) ⬇️
src/Mixer/Amplimix.h 100.00% <ø> (ø)
src/Core/Playback/Channel.cpp 48.00% <75.00%> (-16.10%) ⬇️
src/Core/Playback/ChannelInternalState.cpp 43.80% <87.50%> (+0.91%) ⬆️
src/Mixer/Amplimix.cpp 55.15% <75.00%> (+0.93%) ⬆️
src/Mixer/RealChannel.cpp 41.83% <37.84%> (-7.29%) ⬇️

... and 42 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Rename the public channel seek API to SetPlaybackPosition() while keeping
the internal RealChannel::Seek() path, and update the public Doxygen style
to match the SDK headers.

Defer playback cursor changes through the Amplimix command queue and add
ResetLayerState() so cursor updates reset the converter and pipeline after
the current mix iteration. This follows maintainer feedback and avoids
mutating mixer state directly during playback.

Stabilize the playback-position and basic playback tests for CI, including
the macOS timing-sensitive sound test, Ubuntu playback-position advance
test, and Windows collection cleanup assertion. Add coverage tests for
negative seek clamping, invalid/stale channel state rejection, and invalid
mixer cursor operations.

Co-Authored-By: Codex GPT-5.5 High <noreply@openai.com>

@na2axl na2axl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! The remaining review comments are just esthetics. I will run some manual smoke tests locally before the final merge.

Comment thread include/SparkyStudios/Audio/Amplitude/Core/Playback/Channel.h Outdated
Comment thread src/Mixer/Amplimix.cpp
Comment thread src/Mixer/RealChannel.h Outdated
Comment thread src/Mixer/RealChannel.h Outdated
Comment thread tests/core_engine/test_channel_can_seek.cpp
Comment thread tests/core_engine/test_channel_can_seek_while_paused.cpp
Undo accidental formatting changes in nearby documentation and mixer setup code. Add explicit pre-seek playback-position expectations to the seek tests so they verify the cursor actually moves forward from an earlier position.

Co-Authored-By: Codex GPT-5.5 High <noreply@openai.com>
@applebutter180
applebutter180 requested a review from na2axl May 11, 2026 22:52
@applebutter180

Copy link
Copy Markdown
Contributor Author

@na2axl I don't have the ability to merge. Let me know if you need any other changes from me.

@na2axl
na2axl merged commit 7547bb9 into AmplitudeAudio:develop May 31, 2026
55 of 61 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants