MaxのGenExprを使ってみた

先日Pure Dataのexternを書きました。

これを、Maxでも動かせるようにしようと思って、Max SDKのドキュメントを読み始めました。ただMaxにはgen~もありますしJavaも使えるので、まずはgen~で試してみようと思い立ってから1時間強……同じものが書けてしまいました。

f:id:amarui:20160908131040p:plain

キモはcodeboxの中でGenExprを使うところにあります。codebox中では複数行のGenExprが書け、しかも条件分岐や繰り返しなどの制御構文を使うことができます。僕のプログラムではforループが使えることが必須だったので、助かりました。

codeboxの中身は以下の通りです。

Param numPartials(1);
Param spectralSlope(1);

History phase(0);

ph = phasewrap(phase);
np = numPartials;
if (np*in1 > samplerate/2) {
  np = floor(samplerate/2 / in1);
}

rad_per_fs = ((((in1 * 2)) * PI)) / samplerate;

val = 0;
for (i=1; i<=np; i+=1) {
  val += pow(-1,i-1) * sin(i * ph) / pow(i,spectralSlope);
}

phase = fixdenorm(rad_per_fs + ph);
out1 = val / 2;

最初はcycleを使うといいかと思ったのですが、倍音の合成がなかなかうまくいかなかったので、結局sinで作ることになりました。CPU負荷はexternで書いた時とそれほど変わりません。倍音数を多くすると音飛びが起こります。