| 14 | using namespace gam; |
| 15 | |
| 16 | class MyApp : public AudioApp{ |
| 17 | public: |
| 18 | |
| 19 | int seed; |
| 20 | STFT stft; |
| 21 | Accum<> tmr; |
| 22 | LFO<> osc1, osc2; |
| 23 | LFO<> oscA, oscB; |
| 24 | LFO<> mix; |
| 25 | FreqShift<> fshift1, fshift2; |
| 26 | LFO<> modfs1, modfs2; |
| 27 | Chorus<> chrA1, chrA2, chrA3, chrB1, chrB2, chrB3; |
| 28 | |
| 29 | MyApp() |
| 30 | : stft(4096, 4096/4, 0, HANN, COMPLEX), |
| 31 | chrA1(0.31, 0.002, 0.20111, -0.7, 0.9), |
| 32 | chrA2(0.22, 0.002, 0.10151, -0.7, 0.9), |
| 33 | chrA3(0.13, 0.002, 0.05131, -0.7, 0.9), |
| 34 | chrB1(0.31, 0.002, 0.20141, -0.7, 0.9), |
| 35 | chrB2(0.22, 0.002, 0.10171, -0.7, 0.9), |
| 36 | chrB3(0.13, 0.002, 0.05111, -0.7, 0.9) |
| 37 | { |
| 38 | tmr.period(10); |
| 39 | osc1.freq(40); |
| 40 | osc2.freq(40.003); |
| 41 | oscA.freq(62); |
| 42 | oscB.freq(62.003); |
| 43 | mix.period(60); |
| 44 | modfs1.period(101); |
| 45 | modfs2.period(102); |
| 46 | } |
| 47 | |
| 48 | void onAudio(AudioIOData& io){ |
| 49 | while(io()){ |
| 50 | |
| 51 | // Generate new seed? |
| 52 | if(tmr()){ if(rnd::prob()) seed++; } |
| 53 | |
| 54 | // Modulated mix between pulse waves |
| 55 | float mx = mix.hann(); |
| 56 | float s = (oscA.up() - oscB.up())*mx + (osc1.up() - osc2.up())*(1-mx); |
| 57 | |
| 58 | // Add frequency shifted versions of signal to get barberpole combs |
| 59 | fshift1.freq(modfs1.tri()*2); |
| 60 | fshift2.freq(modfs2.tri()*2); |
| 61 | s += (fshift1(s) + fshift2(s))*0.5; |
| 62 | |
| 63 | if(stft(s)){ |
| 64 | // Apply spectral thin |
| 65 | rnd::push(seed); |
| 66 | float prb = rnd::uni(0.3, 0.1); |
| 67 | for(unsigned k=0; k<stft.numBins(); ++k){ |
| 68 | //float frac = double(k)/stft.numBins(); |
| 69 | float m = rnd::pick(rnd::pick(2,1, 0.1),0, prb); |
| 70 | stft.bin(k) *= m; |
| 71 | } |
| 72 | rnd::pop(); |
| 73 | stft.zeroEnds(); |