I solved it in "ugly" way. I left loop 1 message and I'm using a timer to count the time of the audio playing...
I'm curious though, did my last version work or not work for you? Because I did actually fix it for you but never heard back ... it now goes "pause - resume - pause - resume - (many times) - pause" and after it hits the end, "start 0 xxxxx xxxxx"
As for "all vanilla," there are trade-offs. readsf~ assumes that the system sample rate matches the file's sample rate -- not a problem in many cases, but worth noting. (IMO this is a gap in Pd's functionality -- in SC, I can
VDiskIn.ar(numChannels, bufnum, BufRateScale.kr(bufnum)), and Max 1/ automatically compensates and 2/ has an "srate" message to sfplay~, but in Pd vanilla, you're stuck.)
tabread4~ couldn't handle 20 minutes of audio (but cyclone/play~ keeps a double precision phase, so it's fine for big files).
However, cyclone/play~ doesn't handle a mismatch between file and system sample rates -- which is why I made those abstractions. IMO you should be able to say "play at the file's normal speed" and get normal speed, regardless of the system's sample rate. My abstractions work that way. tabread4~ can, but you have to do the math yourself, every time. cyclone/play~ and readsf~ don't handle it at all. So I guess it's a matter of whether you're more interested in the vanilla functionality as given, or in a functional spec that works properly.