The short answer is… yes. A matrix decoder doesn’t require the use of Buffers. (That’s why we needed to save the decoder kernel to a score.)
You can design the matrix decoder within the SynthDef function, or outside of it. For each of these cases, the decoder needs to be completely defined (instanced) before the SynthDef is instanced. E.g., for the former, no SynthDef args can be referenced. For the later, the matrix decoder must be completely defined (instanced) before the SynthDef is described.
Here’s an example to do the job, derived from this and this example:
(
var score, bufnum, sndPath, duration, decoder, sampleRate, headerFormat, sampleFormat, numChannels;
var offset = 0.1;
// deinfe our score
score = Score.new;
// get a buffer number from the server
bufnum = Server.default.bufferAllocator.alloc(1);
// the path to our B-Format sound file
sndPath = Atk.userSoundsDir ++ "/b-format/Pampin-On_Space.wav";
// get some info about the soundfile we are decoding for the Score requirements
SoundFile.use(
sndPath,
{arg soundFile;
headerFormat = soundFile.headerFormat;
sampleFormat = soundFile.sampleFormat;
sampleRate = soundFile.sampleRate;
numChannels = soundFile.numChannels;
duration = soundFile.duration;
}
);
// define our deocder
decoder = FoaDecoderMatrix.newStereo((131/2).degrad, 0.5);
// define an encoding and decoding synth
SynthDef(\foaStereoDecode, {arg buffer;
var out, src;
// play B-format sound file from a buffer
src = PlayBuf.ar(numChannels, buffer, BufRateScale.kr(buffer));
// decode our B-format signal
out = FoaDecode.ar(src, decoder);
Out.ar(0, out);
}).load;
score.add(
[ 0.0,
[ 'b_allocRead', bufnum, sndPath, 0, 0 ],
],
);
// add commands to free the synth and buffer
score.add([ duration, [ 'n_free', 1001 ] ],);
score.add([ duration + 0.1, [ 'b_free', bufnum ] ],);
// add the needed dummy command to stop NRT
score.add([offset + duration + 0.2, [0]] );
// render our score to a sound file
score.recordNRT(
"/tmp/trashme",
"~/Desktop/myDecode.wav".standardizePath,
sampleRate: sampleRate,
headerFormat: headerFormat,
sampleFormat: sampleFormat,
options: ServerOptions.new.numOutputBusChannels_(decoder.numChannels)
);
)