sfplay~ not working properly

due_friday's icon

Hi,
have been having my grief with sfplay~ lately and it is hard to debug and provide accurate feedback on how to reproduce this error.
The problem: at random times, sfplay~ somehow thinks that the cue has finished, even though it has not. Not results in playback of files prematurely stopping, or sfplay~ jumping to the next cue, even though the previous cue has not finished, yet.
My suspicion is, that it has to do with assigning a buffer size in the arguments. Here is a current example I have in front of me:
Because of problems with sfplay~ (for example that it STILL doesn't suppor wav64 or rf64!), I decided to write myself a multichannel player that contains as many sfplay~ objects that I need... and I manually separate the multichannel wav file into individual mono ones using a script written with sox. So far so good.
Just now, my multichannel player is acting up. I attached a screen shot, where you can see that the first of the sfplay~ has a buffer defined and the position outlet flag set. I ONLY define the buffer, because I need the position outlet flag!
Previously this has worked good, but just now, if I press play, the first sfplay~ jumps after one buffer length to the next cue, while the rest of the sfplay~'s remain in the cue that I want them to be. I know this is an issue due to the arguments passed sfplay~, because if I switch it around by making the second sfplay~ the one that outputs the position signal and reverting the first one to a "normal" sfplay~ without any arguments apart from the 1 as the channel count, the second one jumps to the next cue after one buffer size and the first one suddenly behaves the way it should.

Being forced to provide a buffer size before I can set the position outlet flag is a bit unfortunate. I would love to have the position outlet by default, or, at least, have a way to receive this outlet without having to specify a buffer length? (...which is the default one any way... all I want is that outlet!)

Or, is there any message I can send to sfplay~ to query the current position in the file?

Thanks!

Channel 1 supplying the position information jumps to the next cue in after just 10160 samples, while the other sfplay~s correctly finish the first cue properly.

Now, channel 2 is supplying the position information, but now channel 1 plays the cues correctly and channel 2 skips it just after (presumably) 20160 samples (although it sounds even faster)

due_friday's icon

Doing some more tests I can report the following:
I send a series of messages, for example like "preload 2 14089 216629, preload 3 216629 251055, preload 4 251055 302250, preload 5 302250 515774, preload 6 515774 550782, preload 7 550782 590142, preload 8 590142 835129, preload 9 835129 870150, preload 10 870150, loopone 0, 2 3 4 5 6 7 8 9 10" to play a section of a long file (I do this to define sections that are individually loop-able in real-time).
The error of the first sfplay~ jumping to cue 3 happens only in relation to the amount of sfplay~s that this series of messages being sent are connected to. If the amount of objects is greater-equal than 15, the error always happens and the immediate jump from cue 2 to 3 in the first sfplay~ occurs. If I only send the message to less-or-equal to 9 objects I can safely say I could not get the error to appear. Anything in-between seems to have a gradual curve of error: with 10 objects connected, I could only provoke the jump from cue 2 to 3 in the first sfplay~ object in a few rare cases, while with 14 connected, I could only get it working as it should in rare cases. With 12 objects, it is almost as if it a 50/50 gamble, if you get the correct behaviour or not.

Also, not having any sfplay~ use a position outlet also prevents this error from happening. But, then of course, I have no way of giving feedback to the user how far in and at which playback position the playback is happening right now... which is also undesirable :(

due_friday's icon

So, after trying to figure out as much as I can about this issue, I restarted my computer and it is gone!

While I am happy it works like normal again, I am also sad for two reasons: for the sake of debugging this, but, more importantly, this issue can creep up randomly in the future again. During a performance this could be horrendous!

I am running OSX 10.13.6 on a late 2015 MacBook Pro. Issues similar to these keep creeping up with sfplay~. Not just the MacBook, but also in two MacPro's (trashcan model) and other machines was I able to work on recently. What they do have in common is the 10.13 OS version. I am hesitant to update to Mojave for several reasons, including software like Dante Virtual Sound card not yet officially being supported (or I cannot find the 10.14 download link to the driver).

I hope the minimal amount of information I could gather can help with debugging. Perhaps if one of the dev's tells me what I could analyse next time I bump into an sfplay~ problem similar to this, I'll make note of this and be sure to report back in this thread! (or however else you'd like to report this)

Best

due_friday's icon

Hm, one more report on this one: I was trying to do a screen recording using Quick Time Player by dragging an area. To record the sound, I set my Max/MSP output to Soundflower (2ch) and the input to the screen recording of Quick Time to Soundflower (2ch) as well.

In this case, the cue error as described above happens reliably.

If I turn off the recording, close Quick Time without saving, turn off the audio in Max/MSP, switch back to Built-in Output and turn it back on again, I have no more issues with cue jumps.

What is also remarkable to me is the fact that previously (before rebooting) I was not able to get rid of the error this easily. I can, however, attest that that I originally wanted to do the screen recording when this crept up the first time.

I mean, this cannot be normal, right? Is there anything that can be done to fix this? Because it might not just be Quick Time but a question of resources from the OS or machine and I do need this to work reliably without prematurely finishing playback at any time.

Thanks!

Augustine Bannatyne - Leudar's icon

Im a bit busy and only read the first bit of your post - but you can use info object to get the exact length of the newly loaded sample and dynamicly set the buffer size so its always set to exactly the length of the actual sample. its playing - might be of use

Source Audio's icon

My advice - use multichannel 16 bit audio files and multichannel sfplay~
for live.
Nobody will ever hear the difference between 16,32, or 64 bit,
wave or aiff, or even better compressed mp3
audio through PA speakers.
That many preload messages, cue recall etc are not in signal domain,
and there is no way to guarantee synced playback anyway.
Any CPU spike will get You out.
At home, You can do whatever, but stuff on stage
must be rock solid.
Just my 2 cents.
And have a good look at buffer settings for sfplay
in the help file, multiply 20160 for as many channels in use,
and then multiply again 4 or 8 times.
Big buffer - big fun.

due_friday's icon

Im a bit busy and only read the first bit of your post - but you can use info object to get the exact length of the newly loaded sample and dynamicly set the buffer size so its always set to exactly the length of the actual sample. its playing - might be of use

Unfortunately I am dealing with samples with minutes of audio. This the example above, I am samples of about 15 min of length. Considering that this is multichannel audio, this is gigabytes of data.

Also, assigning a buffer size of the exact length of the sample is equivalent to loading it into a buffer~ object, correct? If so, this sort of defeats the purpose of the sfplay~ object in the first place, in my opinion, namely using it precisely to not have to load the whole file into memory, but rather being able to stream it from disk in portions.

due_friday's icon

My advice - use multichannel 16 bit [...]
Nobody will ever hear the difference between 16,32, or 64 bit

I agree with you on that, but there are two problems I face here: I have tried this already, using Reaper to create a large multichannel file in 16 bit, but the file size of a 30+ channel wave file with 15+ minutes of audio can still exceed 2GB quickly. So the lack of support for wave64 or rf64 is a huge disappointment! Furthermore, the audio is not mine originally and the person who created it will be offended if I reveal that I reduced his work to 16 bits. Granted, I could keep it a dirty secret, but this is beside the point and not nice anyway. Again, it is not that this should be a limit in the first place, not in the 8th generation of a piece of software that I have an incredible love-hate relationship with :)

in the help file, multiply 20160 for as many channels in use, and then multiply again 4 or 8 times.

Yes, I took those suggestions from the help file, but I didn't consider multiplying the result by an additional 4 or 8 times. I assume this might be for good measure, but there is not sure heuristics that could keep me safe in extreme 1h long samples with 64 channels :/ But I'll will try this additional multiplication in the future and see if it gives me more stability.

Thanks a lot!

Source Audio's icon

You still have option to split number of channels into 2 or more multichannel
sfplay objects.
That would be still better than sooo many singlechannel players.
I remember having good experience with 8 Stereo Players, staying very well
in sync with preloaded cues, almost 20 Years ago with max 4 on OS9.
Remember having to preload cues using qmetro, uzi or iter
made sfplayers act quirky , maybe that is Your problem now too.
I used to place cue numbers together with start/stop times
into coll, and then run slowuzi, qlimited counter to preload them.
Another trouble was if one of the players had shorter file
and preload values were beyond file length.
Sometimes it crashed max then.
P.S. 20160 is not a magic number for all file resolutions.
I hope You read that

due_friday's icon

slowuzi, qlimited counter

Hm, I never heard of these objects. Slowuzi, as in a metro object hooked up to a counter?

Anyway, I hacked something together that seems to solve the above problem now:

Using scipy.io.wavfile I added another section of code that produces an extra wave file of the same length with a smooth ramp produced using numpy.linspace to my script that already splits the multichannel file into mono files. Basically this:

in = scipy.io.wavfile.read('./split_audio.00.wav')
audio_samps = in[1].shape[0]
out = numpy.linspace(0.0, 1.0, audio_samps, dtype='float32')
scipy.io.wavfile.write('./ramp.wav', 48000, out)

So now, my multichannel player looks for this "ramp.wav" file additionally in the same directory, and plays it in synchrony with the rest, which effectively outputs normalised elapsed time. Multiplying this with the total time gained through info~, you get the same result as the position outlet would have, only more complicated but – as far as I could test – with no quirks, misbehaviour or errors. Runs stable for now as far as I can tell.

I mean, I consider sfplay~ pretty broken, but especially simply old and also in dire need of an overhaul if all this hoop jumping is necessary just to get anything halfway stable and decent to work – especially when it comes to basics such as argument order. For backwards compatibility, I believe making the position outlet available via an additional attribute flag would be great, just to avoid having to choose a buffer size, which I am surely doing wrong somehow...

Source Audio's icon

Here is example of slow uzi.
qmetro - counter combo will play nice with loading many preload cues to
sfplay objects

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

Jaky's icon

I dunno, if you ever have solved this issue, but I had to implement a multi sfplayer too, becaquse of not able to read a 12 ch audio file 16 bits by the way. Max just crashes.
More than 8 channels makes Max crash...
on win pro 10