Shuffle is dead, long live shuffle.

If you’ve been following along you know I’m experimenting with overhauling the queue and playback system for Cesium. I’ve outlined the reasons here, but in a nutshell the old system is too divorced from the iOS system functions, and a new approach that integrates better and utilizes the existing features built into iOS should be faster and more reliable.

The new code is lightyears better (admittedly in large part because the old code wasn’t written as efficiently as it could have been), however in continuing to test serious limitations are coming to light, particularly with the existing iOS shuffle function. I outlined in the last post how the only real “catch” to the new system is that the playback queue is shuffled as soon as it is set, meaning that I couldn’t continue to support “Play Next” with shuffle. The track set to play next would just get shuffled into the queue and not stay where it needed to be. Well, what I should have realized at the time was that this also meant that reordering, or removing tracks from the queue also couldn’t be supported with shuffle. I couldn’t even support selecting a track from the upcoming queue because the whole thing would get reshuffled (there might be a workaround for that, but the point stands).

There was a method to my poorly written madness. There’s just no way to leverage the system shuffle and the existing Cesium feature-set.

So what does this mean? The features have to come first. The new beta build uses the same strategy as before for shuffling, but has been rewritten to be considerably more efficient to manage. The result is basically a hybrid of the two: Cs will set and manage queues the way it always has, but general playback (where I extended the queue management too far) can be handled by the system queue. I wouldn’t say it’s the best of both worlds, but that seems impossible and it’s a much better solution to the current code.

Performance

What does this mean in terms of performance? Tracking forward and backward during playback should be improved. It can’t get much more fundamental; so it will be tough to get much faster. Cs has to do more work when shuffling queues, but the performance hit shouldn’t be overly noticeable unless thousands of tracks are involved. I’m looking for another way to improve responsiveness for those situations.

Several users in the last few days have also raised a lag issue when selecting a song. Basically the UI becomes unresponsive for several seconds after selecting the song. The issue is fairly straightforward: all UI tasks (scrolling, animation, changes to any UI elements, etc) must be carried out on the main processing thread. If another process is running on the main thread then updates to the UI can be delayed. This is a lag/hang/pause, etc. The simple solution would be to identify what process is holding up the main thread and offload it to another thread so that the main can get back on with the work of updating the UI. Unfortunately, the music player can also only be run on the main thread. This is why the UI freezes up after selecting a song, it can’t update again until the music player has finished loading the queue, starting playback and any other tasks it may need to execute. I had foolishly added code trying to shift this off the main thread, but the system would have to shift them right back. It’s possible that this back and forth would actually cause an additional performance hit. Now everything runs on the main thread as it should, but there’s not much more I can do beyond looking for a strategy to get faster code and/or add a UI element to mitigate the delay (like a loading bar that was present in earlier versions). I’m working on it.