#この記事は4月頃書かれたものを再投稿したものです。
前のエントリで正変換と逆変換の間に関数を入れるのにpvcalcと言うのを紹介したが、 他にも2つのchainを処理できるpvcalc2や、関数内でindex(bin数)を利用できるpvcollectがある。pvcollectが便利そう。
UnpackFFT
UnpackFFTはFFTの吐いたchainの中身をDemand rateのストリームで吐き出す。
UnpackFFT(chain, numFrames, frombin, tobin )
これもfrombin, tobin引数によって必要なbin数を指定できる。
出てくる数値はDemand rateのストリームなのでこれにDemand UGenで処理を加えることができる。
出てくるストリームはリアルパートとイマジナリパートが分かれていないので、そこは適せん自分で分ける式を書く。
(あとpvcalcやpvcollectも関数内でDemand UGenで処理を加える事ができる。つまりDemand UGenはサンプル毎に処理ができるってこと。?これってなんかスパコの時間概念って実は結構フレキシブルなんじゃないだろかと思ってしまう。もししたらChuckみたいにサンプルレベルの波形処理も別に普通のことなのかもしれない。このへん後で調べたい)
あとヘルプに注意があるように今の時点でDemand UGenは32のインプットしか処理できないのでbin数はfrombin, tobinでそれ以内に抑えなければいけないようだ。
以下ヘルプから( s.boot.doWhenBooted{ ~fftsize = 1024; b = Buffer.alloc(s, ~fftsize, 1); c = Buffer.read(s,"sounds/a11wlk01.wav"); } )
// ポストウィンドにMagnitude、Phaseとストリームをポストする ( x = { var sig, chain, unp; sig = SinOsc.ar; sig = PlayBuf.ar(1, c, BufRateScale.kr(c), loop: 1); chain = FFT(b, sig);
// frombin と tobin 引数で必要なbinを制限 unp = UnpackFFT(chain, b.numFrames, frombin: 0, tobin: 4); // アンパックしてDemand rateに // 時点でDemand UGenは32のインプットしか処理できない
//なのでbin数はfrombin, tobinでそれ以内に抑える Demand.kr(chain>=0, 0, unp).collect{|anunp, index| anunp.poll(chain>=0, if(index % 2 == 0, "Magnitude", "Phase")+(index/2).floor); };
(sig*0.1).dup;
}.play(s); ) x.free;
またDemand rateのFFTデータをchainバッファに束ねて戻すPackFFTもある。