Basic playlist player - gaps between audio files

Marc Carlton's icon

I'm working on a very basic audio player that plays audio files back in sequence according to a tab-delimitted txt, like this:
playlists.txt
playlist1 (tab) file1.wav (tab) file2.wav
playlist2 (tab) file2.wav (tab) file 1.wav

Here's what I have so far:

Max Patch
Copy patch and select New From Clipboard in Max.


It is working as desired so far - except I'm getting silence gaps between files. (IE in playlist1, there is a large noticeable gap between file1.wav and file2.wav. Ideally hand-offs between files would be sample accurate.

I'm a pretty novice Max user, but my instinct tells me I'll need to redesign the way this is working.
You'll see in the patch that I'm using the output of play~ to trigger the next audio file to play.

Can anyone point me in the right direction to fix this?
Ever grateful.

Baffalop's icon

Your js file wasn't included in the pasted patch. Could you paste it here as well?

If you're reading each file into a buffer as you receive the bang from [play~], I'd guess that alone would account for the delay, and so you'd want to preload a second buffer after you retrigger [play~]...

Anyway, your js code would hopefully help diagnose it further.

Marc Carlton's icon

playlists.txt
text/plain 0.09 KB

Thanks for your help. I've attached the JS file.

Marc Carlton's icon

whats strange... im on my laptop now, and pulled the repo and ran it on this machine - and I don't notice the gaps... regardless, I'm sure I'm not laying this out the best way, and I'm sure there are much better ways to do this. Thanks in advance.

Marc Carlton's icon

aaand it looks like i uploaded the playlist.txt instead of the js file... here's that...

playlist_player.js
text/plain 3.62 KB

Baffalop's icon

Alright, this looks to be some rather well-designed code. At least better than I could do. You're already using a polybuffer I see so my advice doesn't really hold.

Perhaps it's simply a matter of turning on Scheduler Overdrive?

If you're new to Max but experienced in Javascript, perhaps it'd be a good exercise to gradually get more of that functionality out of js and implemented through Max patching? Would certainly make it more legible.

Not sure what more I can suggest for the play~ issue though...

Marc Carlton's icon

Thanks! I'll check into Scheduler Overdrive.

I'm wondering if the hand-offs between files would be more efficient if I used two Identical polybuffers that trigger each, other outside of JS. Does JS slow everything down where directly connecting non-JS max objects would not?

Baffalop's icon

Actually, I think the answer is yes, JS slows everything down. Just dug up this good foundational article on Max's threading model: https://cycling74.com/articles/event-priority-in-max-scheduler-vs-queue/

The last heading is Javascript Threading Concerns:

The first thing to note is that at the time of this writing the Javascript implementation is single threaded and will only execute at low priority. For timing sensitive events the js and jsui objects should not be used for this reason. However, this may change in a future release.

The time of writing was ca. 2011 but I'm not sure anything has changed since then. I guess this makes the migration of most of your JS code into Max patching rather more urgent... You could still use it for the initial setup of each playlist and hopefully for holding onto the file info etc. in arrays. You could probably also keep your polybuffer in JS. You'd just need to find a way of keeping JS out of the pathway between [play~]'s bang output and retriggering it with a new buffer pointer.

Marc Carlton's icon

Thanks again for your help.
I'm thinking I need to setup the patch so that after the playlist has started, the handoffs don't need to touch JS until the next playlist needs to be setup. I'm thinking of perhaps having two play~ objects that communicate with each other directly. I'll post another version when I figure out that structure.

Baffalop's icon

Yeah, that's what I was trying to say - though I'd try it still with one [play~] first.

Marc Carlton's icon

K, so same problem. If you hookup two play~ objects, so the eof bang triggers the next one to play, there is still a noticable gap. I'm wondering what the correct way is to sequence buffers so they are sample accurate handoffs.

Marc Carlton's icon

playlist_player.maxpat
text/plain 27.97 KB

playlists.txt
text/plain 0.07 KB