メモリサイズ
時間が足りない
コードが長大になってくると、時々ディレイを使いすぎるということが起こります。
個々のディレイが短くても、合計時間には上限があるらしい。何十秒もあれば充分だろうと思うかもしれないが、そんなことはない。って俺だけか
これは23秒ディレイ。
SynthDef(\hoge, { arg dur; var a = DelayN.ar(SinOsc.ar(100),dur,dur); Out.ar(0,a!2); }).store; Synth(\hoge, [\dur, 23]);
これがもし24秒ディレイだと、
Synth(\hoge, [\dur, 24]);
alloc failedなんたらと言われ、メモリ増やせと死ぬほど怒られます。うぜーのでAlt+.で黙らす。
そんなら只今のメモリサイズとはいかほどであるのか?
s.options.memSize
特に設定をいじってなければ8192と出ます。
ちなみに8192とは2の13乗(2**13)。なほ、メモリサイズは2**nとするがいいらしい。根拠は知らぬ。
ある方によれば、使えるディレイ時間とはメモリサイズをサンプリングレート(通常44100)で割ったものだそうです。
しかし8192/44100とは1(秒)にも満たないのでこれはおかしい。
さっきは23秒までできたのであった。では23秒にサンプリングレートをかけたものは2**ナニであるのか。
log2(23*44100) 19.952052991389 log2(24*44100) 20.013453536053
メモリサイズをサンプリングレートで割る説に従えば、恐らくメモリサイズは2**20であることになりますが、プラス7乗ということは単位が違うとしか思えない。それはともかく、
2**20/44100 23.777233560091
実際やってみると、確かにだいたいdur=23.77まではいけるもよう。dur=23.777だとコケますが。
ではメモリサイズ増やす。startup.scを開いて、
s.options.memSize = 2**19; s.boot;
などと書き足しましてAlt+K。
このmemSizeは数字が大きすぎると起動すらしなくなるのであり、当方の環境では偶々2**19が上限だったということです。
s.bootはおまけですが、便利ですね。何で今まで気付かなかったんだろう。さて、
Synth(\hoge, [\dur, 24]);
無事走ったもよう。
2**(19+7)/44100 1521.7429478458
さきほどのプラス7乗説によれば、上のごとく使えるディレイタイムは約25分。
この段階で既にお腹一杯ですが、何でも余裕があることは良いことですね。
Synth(\hoge, [\dur, 1521]);
おー走った。
1秒増やすとまたキレられたので、どうやらプラス7乗説はありなもよう。
それにしても本当に25分ディレイできてるのかというと、結論は25分後であり、ヒポクラテス先生の言うとおり、あっという間に死ぬ我々ですから、ここはNRT(レンダリング)にて検証します。
どんどんWAVに書き出して、プレイヤーでシークしたりすればいいじゃんていう。
NRTも時間が足りない
x = [ [0, [\s_new, \hoge, 1000, 0, 0, \dur, 1521]], [1800, [\c_set, 0, 0]] ]; o = ServerOptions.new.numOutputBusChannels = 1; Score.recordNRT(x, "hoge.osc", "hoge.wav", options: o);
あれ、またメモリ足りねーとか。
んだてめえやんのかこら。
などと凄んでる場合ではなく、果たしてdurいくつなら通るのかというと、悪い予感どおりと申しますか、またもや23.77のあたり。
デフォルトと変わってねー!ということはNRTではまた別のメモリの使い方をしておるのだろう、とか、何が何だか私にはよくわかりませんが、startup.scのmemSizeが効いてないのは確かなようです。
他にもうまい策がありそうだが、とりあえず考えたのは、BufDelay使う。
SynthDef(\hoge, { arg dur; var a = BufDelayN.ar(10,SinOsc.ar(100),dur); Out.ar(0,a!2); }).store;
つまりScoreにb_allocとでも書けば、NRTでもメモリを使えるだろうという読み。
d = 1800; x = [ [0, [\b_alloc, 10, d*44100]], [0, [\s_new, \hoge, 1000, 0, 0, \dur, d]], [2000, [\c_set, 0, 0]] ]; o = ServerOptions.new.numOutputBusChannels = 1; Score.recordNRT(x, "hoge.osc", "hoge.wav", options: o);
でけた。
しかもお気づきかもしれませんが、数字おかしいです。これは30分ディレイ。
プレイヤーでシークしてみると、確かにそのようです。
まとめ
以上、当方の環境では書き出せましたが、何しろメモリ云々のことですし、他でもできるかは知りません。
あと、何分まで出来るか、とか追究するのも無意味な領域に達している気がするので、やりません。30分あればさすがにどうにかなるだろう。というかしろ。
あと、他のUGenとの絡みもわかりませんし、サンプリングレートやらチャンネル数が変われば、使える時間も自ずと変わると思われます。