楽器の外部からパラメータをいじる
リアルなMIDIインタフェースを持つ楽器では、音を鳴らしっぱなしにして外部のフィジカルインタフェースからモジュレーションやピッチベンド、システムイクスクルーシブなどを送ってパラメータを変更し音色を変えて演奏を行うことがよくある。csoundでは発音する楽器と別にパラメータ変更用の楽器を作ることにより、作者の表現力に直結した高い自由度を持つ楽器を作ることができる。その方法の要点としては以下のとおり。
- 音を鳴らしっぱなしにする側の(楽器1)を作る(鳴らしっぱなしにしなくてもいいんだけど)
- (楽器1)の音の大きさ、高さ、音色の決め手となるパラメータをすべてグローバル変数にする
- グローバル変数にしたパラメータだけいじる(楽器2)を別に作る
- (楽器2)で受け取るパラメータをグローバル変数に設定する
- ただし、(楽器2)でパラメータ補完のアルゴリズムを考慮しグローバル変数を設定する
- パラメータの変化を(楽器2)のスコアとして書く
- (楽器1)のスコアは一定期間発音するように記述する
- グローバル変数の初期化を忘れずに行う
本例では、パラメータを変化させたときの方法を考慮に入れる。すなわち、(楽器2)で前回のスコアで決まったパラメータによって決まる音色から、新たに読みこんだスコアのパラメータで決まる音色まで突然変化させるとその変化の幅が大きい場合にはしばしば不自然になることがある。(楽器2)の発音時間で線形補間してパラメータが緩やかに変化させて、音色の変化が自然になるようにする。これはいくつかのフィジカルな電子楽器のノブの表すパラメータ値が相対値で変化して突然音色や、音の大きさが変わらないようになっている理由と同じである。
csoundではそもそもスコアでは複数のパラメータを同時に読むことが可能なため、複数のつまみをある時間内に同時に一定の早さでいじるような感じを実現できる。(楽器2)を別々にして沢山作り、パラメータを一つだけにすれば、DAWっぽくあらゆるパラメータの時間変化をを個別に好きにいじることもできる。ただし、その分、楽器も複数、スコアも楽器分作るので労を厭わなければである。
また本例のようにパラメータを線形補間をするのではなく、(楽器2)のパラメータ決定のアルゴリズムをイクスポーネンシャルにしたり、ランダムに補完するようにしたり、色々変更させることでまた異なった趣きにすることができる。
今回発音させる(楽器1)としては密度を変えると発音間隔が変わるグラニュラーシンセシスを使った楽器にした。
<CsoundSynthesizer> <CsOptions> -d -m0 -W -o test.wav </CsOptions> <CsInstruments> sr = 44100 kr = 4410 ksmps = 10 nchnls = 2 garvbl init 0 ;リバーブ用 garvbr init 0 ;リバーブ用 gkamp init 0 ;grainの外からいじるパラメータ gkfrq init 0 ;grainの外からいじるパラメータ gkdns init 0 ;grainの外からいじるパラメータ gkpan init 0 ;grainのパン ;最初の発音時には0から線形補完するので楽器外部で初期化する giamp_i init 0 gifrq_i init 0 gidns_i init 0 gipan_i init 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;granular with reverb instr 4 irvbgain = p6 ;二種類の音を作って、それを動かす。 ; grain xamp, xpitch, xdens, kampoff, kpitchoff, kgdur, igfn, iwfn, imgdur [, igrnd] asig1 grain gkamp, gkfrq, gkdns, 8000, 30, .025, 2, 3, 1 asig2 grain gkamp, gkfrq/2.529, 1.0/gkdns, 8000, 30, .05, 1, 2, 1 aoutr = $M_SQRT2/2.0*(cos(gkpan)+sin(gkpan))*asig1+$M_SQRT2/2.0*(cos(gkpan)-sin(gkpan))*asig2 aoutl = $M_SQRT2/2.0*(cos(gkpan)-sin(gkpan))*asig1+$M_SQRT2/2.0*(cos(gkpan)+sin(gkpan))*asig2 outs aoutl, aoutr garvbl = garvbl + aoutl * irvbgain garvbr = garvbr + aoutr * irvbgain endin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; parameter control for instr 4 instr 1 ;つまみを新たに動かす先の値 iamp = p4 ifrq = p5 idns = p6 ipan = p7 ;発音時間で線形補完 gkamp linseg giamp_i, p3, iamp gkfrq linseg gifrq_i, p3, ifrq gkdns linseg gidns_i, p3, idns gkpan linseg gipan_i, p3, ipan ;次の初期値は今回設定した値 giamp_i = iamp gifrq_i = ifrq gidns_i = idns gipan_i = ipan endin ; reverb instr 199 idur = p3 irvbtim = p4 ihiatn = p5 arvb1 nreverb garvbl, irvbtim, ihiatn arvb2 nreverb garvbr, irvbtim, ihiatn outs arvb1, arvb2 garvbl = 0 garvbr = 0 endin </CsInstruments> <CsScore> ; function tables f 1 0 8193 10 1 ; sine wave f 2 0 8193 10 1 .5 .333 .25 .2 .166 .142 .125 .111 .1 .09 .083 .076 .071 .066 .062 f 3 0 8193 20 2 1 ; window for granular synthesis ;;;;stereo reverb ; ins st dur rvbtim hfroll i 199 0 100 5 .5 ;;;;grain ; p1/ins p2/st p3/dur p4/amp p5/frq p6/rvbsnd i 4 0 100 .05 3000 .5 ;;;;パラメータ制御 ; p1/ins p2/st p3/dur p4/amp p5/frq p6/dns p7/pan i 1 0 2 .05 2000 10.0 -0.9 i 1 3 2 .07 7000 0.1 -0.5 i 1 7 2 .02 5000 7.5 0.5 i 1 8 2 .10 9000 1.8 0.1 i 1 15 5 .97 1000 12.0 0.9 i 1 20 2 .08 3000 0.05 0.4 i 1 25 5 .01 9000 9.0 0.1 i 1 31 6 .21 1840 1.2 -0.5 i 1 50 10 .41 10000 7.2 -0.9 i 1 90 10 .01 200 0.2 -0.3 e </CsScore> </CsoundSynthesizer>
なおこの楽器の原型については、Mike Marshが4/15/2000に作成したSoundscape with a wash of noise and various bleeps and bloops.を参考にさせて頂き、grainオプコードのパラメータを変化させる部分やパラメータを変化させたときにおもしろく動くようにのPANの部分などに手を加えた。
これをcsoundにかけると左右を乱れ飛ぶ音が生成できる。
次はやはりローパスをいじくってQ値を買えたり、動的にフィルタ構造を変えるようなものを作りたいな。新しいopcodeの「imagegetpixel」を使って、パラメータの変換のさせ方のインプットをイメージファイルにしても良いかも。
今日は頭がさえていたみたいで、これを作るのに一晩でうまく行った!(自己満足)しかし、寝ないとかなりヤバい。