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

Shuffle tracks in place #1445

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from

Conversation

photovoltex
Copy link
Member

Follow up on #1356 (comment)

  • removes duplication of context tracks when shuffling
  • shuffle by a given seed, by that we can restore the shuffle state after a spontaneously disconnect

With the updated protobuf definitions, there is technically a given seed from the side of spotify when transfering playback. The given seed seems to be a hex value which we can convert into a u64 (which we currently use as seed value). But the shuffled queue isn't even similar to what spotify shuffles (which makes sense as they use a more preference base algorithm with less randomness). So when transferring we reshuffle unless we have a previous shuffle seed in the context metadata.

@roderickvd roderickvd requested a review from Copilot January 19, 2025 10:48

Choose a reason for hiding this comment

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

Copilot reviewed 5 out of 11 changed files in this pull request and generated no comments.

Files not reviewed (6)
  • connect/src/lib.rs: Evaluated as low risk
  • connect/src/state.rs: Evaluated as low risk
  • connect/src/state/context.rs: Evaluated as low risk
  • connect/src/context_resolver.rs: Evaluated as low risk
  • connect/src/state/tracks.rs: Evaluated as low risk
  • connect/src/state/options.rs: Evaluated as low risk
Comments suppressed due to low confidence (1)

connect/src/shuffle_vec.rs:92

  • The unshuffle method might not correctly restore the original order if the vector was shuffled multiple times with different seeds. Consider storing the original order or using a different approach to unshuffle.
let n = indices[self.vec.len() - i - 1];
@photovoltex
Copy link
Member Author

Huh, fair point from copilot that multiple shuffles might create weird states. Will try to appoint that possible issue. I don't think it can occur in the current state, but it might still make sense to prevent possible multiple unshuffle or shuffle calls.

@roderickvd
Copy link
Member

🎉 for AI

@photovoltex
Copy link
Member Author

Welp never mind. I had hoped copilot found something that isn't there... But the cases are already covered.

When you unshuffle it only does so, when it was shuffled to begin with. And we only shuffle on the base content. So when it's already shuffled we unshuffle before we shuffle.

Copy link
Member

@roderickvd roderickvd left a comment

Choose a reason for hiding this comment

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

Cool!

Question: when you shuffle or unshuffle, while you already have the next track preloaded for gapless playback, how do you manage that gets unloaded or anyway the "right" next track starts playing?

connect/src/shuffle_vec.rs Show resolved Hide resolved
}

pub fn shuffle_with_seed(&mut self, seed: u64) {
self.shuffle_with_rng(rand::rngs::StdRng::seed_from_u64(seed))
Copy link
Member

Choose a reason for hiding this comment

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

As SmallRng is being used by the ditherer, you could consider using that. It provides sufficient randomness and may help keep the binary a bit less inflated.

Copy link
Member Author

Choose a reason for hiding this comment

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

So I changed it up to use small_rng. But I don't think it will currently decrease the binary size as other parts of the library includes rand without disabling the default features. By which we don't disable the std feature of rand which includes the other dependencies. Might be a issue to resolve later tho.

connect/src/shuffle_vec.rs Outdated Show resolved Hide resolved
@roderickvd roderickvd assigned photovoltex and unassigned roderickvd Jan 22, 2025
When losing the connection and restarting the dealer, the seed is now stored in the context metadata. So on transfer we can pickup the seed again and shuffle the context as it was previously
@photovoltex
Copy link
Member Author

photovoltex commented Jan 23, 2025

Question: when you shuffle or unshuffle, while you already have the next track preloaded for gapless playback, how do you manage that gets unloaded or anyway the "right" next track starts playing?

Comment from player.rs in handle_command_load:

// Now we check at different positions whether we already have a pre-loaded version
// of this track somewhere. If so, use it and return.
...
// If we don't have a loader yet, create one from scratch.

It seems like we only use a preloaded track when the next track to load is a preloaded track. So we will load load the track in real time in that case. I think that is pretty fair, when you decide so late that you might not want to shuffle anymore.

If the preloaded track wasn't the requested track to play, it is replaced by an empty state and by that dropped.

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