Exporting analyses components as separate audio files

Hi folks

Just joined, and apologies for a complete newbie question, I’ve not been able to find an example of what I’m looking to do (eventually): to segment some source audio using a variety of analyses, and as an end result export those outputs as separate audio files (in this project, for use in WFSCollider for spatialisation).

Working through examples here is some code; it’s a mess, but hopefully gives an idea of what I’m looking to do - the Routine needs to call each component, then write it to disk as a separate audio file.

// start
// adapted source: Learn FluCoMa
/* AIM

  1. to segment an audio buffer
  2. analyse into components: e.g. spectral contour (basis), amplitude envelope (activation), recontruction of components
  3. playback the components
  4. add code to export the components to separate audio files
    (which can be arranged in WFS)
    source: sc help/DiskOut
    */

s.boot;

// define some mono recording and playback synths
(
// record a mono audio file to disk
SynthDef(\record_mono_Diskout, { |bufnum|
DiskOut.ar(bufnum, In.ar(0, 1));
}).add;
// play a mono audio file from disk
SynthDef(\play_mono_Diskin, { |out, bufnum = 0|
Out.ar(out, DiskIn.ar(1, bufnum))
}).add;
)

// choose source audio
(
~path = “/Users/h_qi/Documents/MUSIQI - SOUNDS/SCWORK/SC_PROJECTS/0PROJECTS/sc.NUQTA_MUHANDIS/AUDIO BUFFERS”;
~src = Buffer.read(s, ~path++“/05 The Shadow’s Kiss excerpt mono.wav”); // mono
~srceChanNum = ~srce.numChannels;
)

// take a listen
~src.play;

// prepare some buffers
(
~resynth = Buffer(s); // components: reconstruction
~bases = Buffer(s); // components: spectral contour (basis)
~activations = Buffer(s); // components: amplitude envelope (activation)
~nComponents = 2; // number of analysed components, in this case looking for ‘dum’ and ‘tek’
//~record = Buffer.alloc(s, 65536, 1); // allocate a disk i/o mono buffer for recording to disk
~record = Bus.audio(s, numChannels:1);
)
// create an output file for mono recording buffer, leave it open
(
~record.write(
path: “/Users/h_qi/Music/SuperCollider Recordings/test_components.aiff”,
headerFormat: “aiff”,
sampleFormat: “int24”,
numFrames: 0, // -1
startFrame: 0,
leaveOpen: false,
completionMessage: {“recording file prepped!”.postln;}
);
)
// process source audio using FluidBufNMF
(
FluidBufNMF.processBlocking(s, ~src,
resynth:~resynth,
bases:~bases,
activations:~activations,
components:~nComponents,
action:{“done!”.postln;});
)

// hear the resynth
(
Routine{
~nComponents.do{
arg i;
“now playing component: %”.format(i+1).postln;
{
var sig = PlayBuf.ar(
numChannels: ~nComponents,
bufnum: ~resynth,
rate: BufRateScale.kr(~resynth),
trigger: 1.0,
startPos: 0.0,
loop: 0.0,
doneAction:2
)[i];
sig; // call the mono sig and duplicate
d = Synth.tail(nil, \record_mono_Diskout, [\bufnum, ~record]);
s.sync;
d.free; // stop recording
~record.close; // close the buffer and the soundfile
}.play;
~resynth.duration.wait; // wait for duration of the reconstructed component
1.wait; // arbitrary wait period before next iteration
};
}.play;
)

// see the bases and activations
~bases.plot;
~activations.plot;

// play it back
(
x = Synth.basicNew(\play_mono_Diskin);
m = { |buf| x.addToHeadMsg(nil, [\bufnum, ~record])};
b = Buffer.cueSoundFile(s,“/Users/h_qi/Music/SuperCollider Recordings/diskouttest.aiff”, 0, 1, completionMessage: m);
)
x.free; b.close; b.free; // cleanup

Hi @al_khawarizm

Maybe I’m misunderstanding what you need, but can’t you just use Buffer#write for this?

Like

~drums = Buffer.read(s,FluidFilesPath("Nicol-LoopE-M.wav"));
~resynth = Buffer(s);
~n_components = 9;

~base_path="/tmp/mymnf_%.wav"
(
fork {
    FluidBufNMF.processBlocking(s,~drums,resynth:~resynth,components:~n_components,resynthMode:1,action:{"Done NMF".postln;});
    //Assuming you want n_components mono files, copy each channel to a buffer and write to disk:
    ~n_components.do{ |i|
        var outbuf = Buffer.new(s);         
        FluidBufSelect.processBlocking(s,~resynth,outbuf,channels:[i]);
        outbuf.write(~base_path.format(i),"wav"); 
        outbuf.free; 
    }; 
    s.sync; 
    "Done Exporting".postln; 
}   
)