[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [sc-users] Notes and observations from a large SC project





Can you be more specific about what you'd like server side? Some things are already in place, like trace and dumpTree.

trace and dumpTree provide most of what is needed. As I mentioned when talking about trace below, getting that info as an object (even just as a string that could be parsed) would make it a whole lot more useful. Regarding server execution order, there's currently no way I know of to debug exactly what order each osc message is being processed in. It's easy enough to figure it out with simple sets of messages, but when you're sending multiple bundles, spread between many classes, it becomes tougher. dumpOSC gets part of the way there, but when you care about the order things are actually executed (not sent), there's no solution I know of.

There are simple paradigmatic ways of getting things done. But are you concerned with node order or asynchronous actions?

The first can be dealt with with targets and add actions. Groups can also be helpful. If you're really concerned wrap things in a bundle to guarantee order. e.g. s.bind({thing1; thing2; ...});

The latter can be dealt with using sync as you said. Perhaps it's that it's not clear which things are asynchronous?
Mainly asych actions. Bundling is useful, but it doesn't guarantee order for asynchronous actions.
    s.makeBundle(nil, {
        m = { Out.kr( 100, [100,200,300] ) }.play;
        n = { |a,b,c|  Mix( SinOsc.ar( [a,b,c] ) ) }.play;
        n.map( \a, 100 );
        n.map( \b, 101 );
        n.map( \b, 102 );
    });
Fails. You can split it into two bundles to get it to work again:
    s.makeBundle(1-0.1, {
        m = { Out.kr( 100, [100,200,300] ) }.play;
        n = { |a,b,c|  Mix( SinOsc.ar( [a,b,c] ) ) }.play;
    });
    s.makeBundle(1, {
        n.map( \a, 100 );
        n.map( \b, 101 );
        n.map( \b, 102 );
    });
But it stops working if you embed that code into a bundle:
    s.makeBundle(nil, {
        s.makeBundle(1-0.1, {
            m = { Out.kr( 100, [100,200,300] ) }.play;
            n = { |a,b,c|  Mix( SinOsc.ar( [a,b,c] ) ) }.play;
        });
        s.makeBundle(1, {
            n.map( \a, 100 );
            n.map( \b, 101 );
            n.map( \b, 102 );
        });
    })

We ran into this a lot - we would build a class that abstracted a bunch of synths/busses/etc, test it, and get it initializing just fine. But later, if we tried to initialize it inside another .makeBundle()
        s.makeBundle(nil, {
            spatializer.play();
            someSynth.play( spatializer );
        })
It would stop working again. Debugging, at that point, got very difficult.
completion messages can be used sometimes, but (a) not everything has these, and (b) sequencing 7 or 8 steps like this is difficult.

Ultimately, it would have best for us to separate all our major initialization steps with s.sync()'s, and then made sure all initializations happened inside a Routine. One major reason I was hesitant about this was that it seemed like it would be difficult when using multiple servers on diff. machines - but it looks like BroadcastServer supports sync'ing to multiple servers appropriately.

Perhaps, then, the solution is some more detailed docs/examples for Server.sync, and more explicit documentation about which server actions are synchronous vs asynchronous.

- Scott

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: https://listarc.bham.ac.uk/marchives/sc-users/
search: https://listarc.bham.ac.uk/lists/sc-users/search/