top of page

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)
})
)

 

bottom of page