Wrapping synchronous Buffer operations in a function

Let’s say I have something like this.

b = Buffer.read(s, "some path");
c = Buffer.new;

Routine{
  t = Main.elapsedTime;
  FluidBufPitch.process(s, b, features: c,action:{c.loadToFloatArray(action: {|x| d = x.reshape((x.size()/2).asInteger, 2)})}).wait;
  (Main.elapsedTime - t).postln;
}.play;

In this example the action converts the FluidBufPitch buffer into a reshaped array. d is now accessible in the global scope.

How do I wrap this in a function and get the Routine to return d in time. I’m trying something like this but it outputs an empty array.

~getFrequencies = { |in,out|
  var outBuf;
  outBuf = Buffer.new(s);
  Routine{
    t = Main.elapsedTime;
    FluidBufPitch.process(s, in, features: outBuf,action:{outBuf.loadToFloatArray(action: {|x| out = x.reshape((x.size()/2).asInteger, 2)})}).wait;
    (Main.elapsedTime - t).postln;
  }.play;
}

I tried a variation using a Task with an s.sync after the FluidBufPitch.

Any ideas?

Welcome @heretogo , thanks for your question!

Do you mean you’d like to have the function return as if it were a synchronous function in the main thread? I don’t think it can be done without running the whole thing in a Routine or similar, because the processing and buffer fetching from the server are both asynchronous, so you need to make things block.

(
~getFrequencies = {|in|
    var out; 
    var cond = Condition.new; 
    var outBuf = Buffer.new; 
    FluidBufPitch.process(s, in, features: outBuf,
        action:{outBuf.loadToFloatArray(
            action: {|x| 
                out = x.reshape((x.size()/2).asInteger, 2); 
                cond.unhang; 
            }
        )
        }
    );
    cond.hang; 
    out
};

fork{   
    b = Buffer.read(s, File.realpath(FluidBufPitch.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Tremblay-ASWINE-ScratchySynth-M.wav");
    s.sync;  
    ~getFrequencies.value(b).postln; 
}
)

This is really helpful example. I’m not familiar with Condition but I can follow. In your code, where does fork come from? Does it have a dedicated documentation page? I see that it’s a method of a bunch of different objects. If you call fork on it’s own like that, what does it mean?

It’s a method of the Function class in this case, that’s a shorthand for making and playing a Routine

https://doc.sccode.org/Classes/Function.html#-fork

It’s quite common to invoke it like fork{...} just because it’s up-front , but it’s still a method call.