Hi again -
I’ve been following along with @tedmoore’s SuperCollider video series and it has helped answer a lot of questions - but I’m hoping to understand pitch-tracking a little better within FluCoMa’s toolkit.
I’ve adapted the example from the 2nd video in the “Corpus Plotter” series, “plotter-2” with the intent of taking a sound file, slicing the transients, and then re-organizing the input according to pitch.
The outcome is pretty murky - I think my code definitely has some issues that I’m missing - but I’m also curious about what the approach generally is, in terms of creating a sense of an “ascending” corpus? Is Spectral Centroid usually the preferred method for this, in order to handle polyphonic incoming sounds? Maybe a different SpectralShape feature, in general?
Any help would be appreciated. Thanks!
~src = Buffer.read(s,FluidFilesPath("Tremblay-AaS-AcBassGuit-Melo-M.wav"));
~src.play;
(
~indices = Buffer(s);
FluidBufOnsetSlice.processBlocking(s,~src,metric:9,threshold:0.36,indices:~indices,action:{"done".postln});
)
~indices.postln;
FluidWaveform(~src,~indices);
(
~play_slice = {
arg index;
{
var startsamp = Index.kr(~indices,index);
var stopsamp = Index.kr(~indices,index+1);
var phs = Phasor.ar(0,BufRateScale.ir(~src),startsamp,stopsamp);
var sig = BufRd.ar(1,~src,phs);
var dursecs = (stopsamp - startsamp) / BufSampleRate.ir(~src);
var env = EnvGen.kr(Env([0,1,1,0],[0.03,dursecs-0.06,0.03]),doneAction:2);
sig.dup * env;
}.play;
};
)
// analysis
(
~indices.loadToFloatArray(action:{
arg fa;
var pitchInfo = Buffer(s);
var pitchBuf = Buffer(s);
fa.doAdjacentPairs{
arg start, end, i;
var num = end - start;
start.postln;
end.postln;
i.postln;
FluidBufPitch.processBlocking(s, ~src,start,num,features:pitchInfo);
FluidBufCompose.processBlocking(s,pitchInfo,
destination:pitchBuf,destStartFrame:i);
s.sync;
pitchBuf.loadToFloatArray(action:{
arg fa;
~pitch_features_array = fa.clump(2);
"done".postln;});
}});
)
(
~selected_indices = List.new;
~pitch_features_array.do({
arg val, i;
if((val[0] > 120) && (val[1] > 0.5),{
~selected_indices.add([val[0], val[1], i]);
});
});
~selected_indices.sort({arg a, b, c; a.asArray[0]>b.asArray[0]});
~sorted = ~selected_indices.collect{|a|a[2]};
)
(
fork{
~new.do{
arg i, ct;
("playing slice: %".format(i)++"ct:"++ct).postln;
~play_slice.(i);
0.09.wait;
};
}
)