foa -> hoa5 with decorrelation. This workflow can be applied to any decorrelation purpose:
foa-> hoa5, hoa2 -> hoa5, hoa5-> hoa5, etc..
​
//prep.....
(
~foaPath = "/Volumes/Project_WeiYang/test/snd/flute.wav";
~buffer = CtkBuffer(~foaPath).load;
~duration = ~buffer.duration;
)
(
//encoder for foa -> hoa1
~hoa1Encoder = HoaMatrixEncoder.newFormat(format: AtkFoa.format, order: AtkFoa.defaultOrder);
//spherical design, decoder and encoder for hoa1 -> a format -> hoa5; using 'basic' beamShape, which has lower impoact in terms of harmonic bias than using energy beamShape
~lowerOrder =1;
~higherOrder = 5;
~tdesign = TDesign.newHoa(nil, \spreadE, ~higherOrder); // spherical design
~aFormatDecoder = HoaMatrixDecoder.newSphericalDesign(~tdesign, \basic, ~lowerOrder); //decode to a format
~hoa5Encoder = HoaMatrixEncoder.newSphericalDesign(~tdesign, \basic, ~higherOrder); //re-encode to b format
)
//________________________________________
(
~synth = CtkSynthDef(\test, {|dur, ris=0.1, dec=0.1, outbus=0, gain= -12.0, deviation=0.0, buffer, envBuf= -1, sourceRadius = 10, modRate=0.5, bpfFreq = 400, rq=0.1, targetRadius = 1.5, density=5, grainDur=0.01, grainDurScale=5, plbRate=1, loop=1, startPos=0.0, angle=0.33pi, combFreq=400|
var foaSig, hoa1Sig, aFormatSig, hoa5Sig, out;
var fftsize = 8192;
var hpSig, lpSig;
var amp, ampEnv;
amp = gain.dbamp;
// ampEnv = EnvGen.kr(Env([0, 1.0, 0.8, 0.0], [ris, 1 - (ris+dec), dec]), timeScale: dur,doneAction: 2);
ampEnv = EnvGen.kr(Env.perc(ris, dur - ris));
//source FOA
foaSig = PlayBuf.ar(HoaOrder.new(1).size, buffer, BufRateScale.kr(buffer)* plbRate, loop: loop, startPos: startPos * BufFrames.kr(buffer));
//Encode to HOA1
hoa1Sig = HoaEncodeMatrix.ar(foaSig, ~hoa1Encoder);
// update reference radius
hoa1Sig = HoaNFDist.ar(hoa1Sig, 1);
// look @ source radius
hoa1Sig = HoaNFCtrl.ar(hoa1Sig, AtkHoa.refRadius, sourceRadius, 1);
// hoa1Sig = BPF.ar(hoa1Sig, LFNoise2.kr(density).range(0.5, 2.0) * bpfFreq, rq);
//decode to a format
aFormatSig = HoaDecodeMatrix.ar(
in: hoa1Sig,
hoaMatrix: ~aFormatDecoder
);
//DSP Here
// aFormatSig = aFormatSig * LFNoise2.ar(modRate.dup(~hoa5Encoder.numChannels)); //decorrelation with LF Modulation
aFormatSig = aFormatSig.collect({ |aFormatChan, i| //decorrelation with Granular Synthesis
var granSig;
granSig = GrainIn.ar(
1,
Dust.ar(density),
) ;
granSig
});
// re-encode to target order
hoa5Sig = HoaEncodeMatrix.ar(aFormatSig, ~hoa5Encoder);
// translate back to source radius
hoa5Sig = HoaNFCtrl.ar(
hoa5Sig,
targetRadius,
AtkHoa.refRadius,
order: 5
);
out = hoa5Sig * amp * ampEnv*0.5;
Out.ar(outbus, out)
})
)