Skip to content

feat: AudioStream | expose frame-activity oracle (LastFrameReceivedAt)#69

Merged
popuz merged 2 commits into
mainfrom
chore/frame-activity-oracle-on-AudioStream
May 21, 2026
Merged

feat: AudioStream | expose frame-activity oracle (LastFrameReceivedAt)#69
popuz merged 2 commits into
mainfrom
chore/frame-activity-oracle-on-AudioStream

Conversation

@popuz
Copy link
Copy Markdown

@popuz popuz commented May 20, 2026

Add a cheap monotonic timestamp on every AudioStream that ticks inside the FFI callback whenever a media frame is decoded. This is the foundation for the NearbyVoiceChat single-active-sid resolver (stream deduplication): a stream that's alive is decoding frames; a ghost never decodes.

  • AudioStreamInternal: private lastFrameReceivedAt (init -1), Volatile.Read/Write around Environment.TickCount, set right before the buffer write under the existing channel/sampleRate guards.
  • AudioStream: pass-through LastFrameReceivedAt.
  • IAudioStreams.GetLastFrameReceivedAt(StreamKey): returns -1 when the stream is missing or has never emitted (sentinel chosen over 0 because TickCount is signed and can legitimately be 0/negative).

explorer consumer - decentraland/unity-explorer#8817

  Add a cheap monotonic timestamp on every AudioStream that ticks
  inside the FFI callback whenever a media frame is decoded. This is
  the foundation for the NearbyVoiceChat single-active-sid resolver:
  a stream that's alive is decoding frames; a ghost never decodes.

  - AudioStreamInternal: private `lastFrameReceivedAt` (init -1),
    Volatile.Read/Write around Environment.TickCount, set right before
    the buffer write under the existing channel/sampleRate guards.
  - AudioStream: pass-through `LastFrameReceivedAt`.
  - IAudioStreams.GetLastFrameReceivedAt(StreamKey): returns -1 when
    the stream is missing or has never emitted (sentinel chosen over
    0 because TickCount is signed and can legitimately be 0/negative).

  No Explorer-side consumer yet — existing API surface unchanged.
@popuz popuz self-assigned this May 20, 2026
@github-actions
Copy link
Copy Markdown

🔗 Merge Alignment Reminder

If this PR targets main, please make sure the corresponding changes in unity-explorer are also ready to merge.

Both repos should be merged in coordination to avoid breaking changes. Do not merge one without the other being ready.

@popuz popuz changed the title feat(AudioStream): expose frame-activity oracle (LastFrameReceivedAt) feat: AudioStream | expose frame-activity oracle (LastFrameReceivedAt) May 20, 2026
Copy link
Copy Markdown

@NickKhalow NickKhalow left a comment

Choose a reason for hiding this comment

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

Great, addition. Please address the comments and then we can proceed to merge

);

private bool disposed;
private int lastFrameReceivedAt = -1;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

lastFrameReceivedAt should be named with Volatile prefix to prevent its misuse

return stream.AudioStreamInfo;
}

public int GetLastFrameReceivedAt(StreamKey streamKey)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

use Option<> and avoid sentinel values

public interface IAudioStreams : IStreams<AudioStream, AudioStreamInfo>
{

int GetLastFrameReceivedAt(StreamKey streamKey);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks like it could be an extension method or a method with default impl

@popuz popuz requested a review from NickKhalow May 21, 2026 09:40
@popuz popuz merged commit 9caeba7 into main May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants