Playing 10 tracks in sync.

martinbb's icon

Hi,
I am trying to create an audio player which will play 10 wav files simultaneously. I have tried with sfplay~ but the sync is not good especialy when the seek command is used on all 10 tracks.

I was thinking about using buffer~ instead but is there a way to connect the buffers so they will start in sync?

Please help.

Best Regards
Martin

f.e's icon

Hi,

Buffer~ won't start, they're buffers. But groove~ will. Use a signal to play and sync several groove~ object together.

best

f.e

Tim Lloyd's icon

What you need to do is use signal rate control of each playback device. In max, control-rate events (float, integer, message, list) have an event priority (read max tutorial 5 for more info) events don't happen at exactly the same time. So if you start 10 sfplay~ objects from one toggle, they do not all start playing at the same time, which you know!

But if you use a signal based playback object (play~ or index~ and groove~ to an extent) they will stay perfectly in sync with eachother.

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

Here is a patch that shows what I mean:

Tim Lloyd's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Actually, groove~ might be more appropriate. It depends on the situation, but groove~ will sound better than play~. Here is one way of syncing groove~ objects together.

Christopher Dobrian's icon

The "seek" message is not the right one for this purpose.

Note the following, from the sfplay~ reference page:
The seek message is intended to allow you to preview and adjust the start and end points of a cue.
NOTE: The seek message is always deferred to low priority.

You want the "preload" message, which looks up and preloads the specified moments and assignes them a cue number, and then you play the audio cues just by sending in the right number.

If you want all your sfplay~ objects to use the same set of cues, see the sflist~ object.

Tim Lloyd's icon
Max Patch
Copy patch and select New From Clipboard in Max.

I just did a little test, that seems to show that groove~ and play~ don't use the same interpolation:

The output of play~ is precisely why I tend to use index~ whenever I can. Maybe it's something I'm doing wrong, but groove~ seems to have significantly better interpolation than the other objects. Wave~ isn't even worth putting in that patch, as it's intended for very short samples and as such needs not have high-quality interp.

Tim Lloyd's icon

I think the only point in play~ is when you need signal control over the playback position, but also want variable speed playback. If you try that with index~ you just get major aliasing, understandably.

I never want that, so I stick to index~. The interpolation in groove~ is amazing though, even with different playback speeds it's output looks consistently accurate. It's just a shame it can't be controlled at signal rate fully. But then, if it was an easy thing to code an object like that, the cyclists probably would have!

volker böhm's icon
Max Patch
Copy patch and select New From Clipboard in Max.

yes, groove~ is quite good, but it has its limitations.

so groove~'s interpolation is not 'ideal' - what ever that means. there's probably no such thing as 'ideal interpolation', but you can do much better than groove~ (e.g. using sinc interpolation), if you accept higher cpu load.
concerning the noisy output of play~ and wave~, i believe this is not an interpolation issue, as the earlier example only uses original playback speed, i.e. no resampling. i guess this is due to the limited precision (32 bit floats) for the playpack pointer (with groove you only provide playback speed, not the actual position in the buffer~).
when i was experimenting with high quality resampling, i found that using a double precision accumulator inside an external for the playback position yielded much better results than using a signal inlet to let the user provide the playback pos in maxmsp.
i realize that this might not make things any clearer... oh, well...

Tim Lloyd's icon

So does anyone know if groove~ uses cubic interpolation? I'm fairly sure the other objects all use linear of varying qualities. Also, does anyone know of any buffer~ playback externals that use cubic or higher quality interpolation? Is there anything that implements sinc interpolation, or is it really too cpu-intensive to be worthwhile?

Variable-speed playback isn't something I normally use, but it would be interesting.

Tim Lloyd's icon

^^^^ other than the hr.objects, because I find those a little difficult to use in normal patches.....

they are good though...

volker böhm's icon

@raja, if you don't care for variable speed playback, then you can safely stick with [index~], as it does no interpolation at all, and thus is friendly to your cpu and sounds fine.

for anyone interested in resampling, here is something to play with:

it is an external similar to groove~, but uses sinc interpolation for the variable playback speed.
this not only gives better quality for upsampling (slower playback -> pitching down), but also for downsampling (faster playback) by mostly eliminating aliasing.

it uses an external library called libresample by dominic mazzoni, which was originally written for audacity.
libresample itself is based on 'resample' by J.O.Smith.

resample~.mxo is compiled for osx, but the sources are included.
if someone wants to try this on windows, you'd have to recompile libresample for your platform first.

i haven't tested this intensively, it was merely a research project for me.
originally i planned to support all features of groove~, but got distracted along the way...
if you find this object useful or come across some bugs (most likely), please drop me a line.
thanks,
volker.