今回は、かなりマニアックな内容です。
ちなみに気になったことなどあれば、ツイッターのほうにでも連絡ください。
レガートを制作する上で、KONTAKT内でグループ単位のサンプルのディレイが必要になった。
しかし、グループ単位で音を遅らせる方法がこれといって無い。
そこで、waitとplay_noteの検証をした。
そして現在押されているキーの数を数えるための$Stackを用意した。
KMG7を制作中、これにかなり悩まされたので、改めて検証。
on note
inc($Stack)
wait(1000000)
$Eve_ID := play_note(60,127,0,-1)
end on
キー50をonにしたとする。
この場合、
50キーオンから1秒たつ前にキーを放すと
・60の音は鳴らない。
・50キーを放したとき60のon releaseはコールバックされない。(50のon releaseだけ働くっぽい)
50キーオンから1秒経過させると
・60の音が鳴る。
・50キーを放したとき60のon releaseはコールバックされる。(2つ分on releaseが働くっぽい)
###########################
on note
inc($Stack)
wait(1000000)
$Eve_ID := play_note(60,127,0,0)
end on
キー50をonにしたとする。
この場合、
50キーオンから1秒たつ前にキーを放しても
・60の音は鳴る。(鳴りっぱなし)
・50キーを放したとき60のon releaseはコールバックされない。(50のon releaseだけ働くっぽい)
50キーオンから1秒経過させると
・60の音が鳴る。(鳴りっぱなし)
・50キーを放したとき60のon releaseはコールバックされない。(50のon releaseのみ働くっぽい)
・60の音は、サンプルが終わるか、fade_outまたはnote_offを使用しなければ止まらない。
ここで、後者の場合、
on release
dec($Stack)
note_off($Eve_ID)
end on
とすると、
50キーオフで、音は50も60も止まる。
on releaseは1つ分だけ働き、note_offによる重複はないっぽい。
ただし、キーオンを和音にすると、$Eve_IDが順次上書きされ、note_offは最後の一つの音しか消えない。
これを回避するには、
play_note時の$Eve_IDを
%Eve_ID[$EVENT_NOTE]
にするなどの必要がある。
release時は
$i := 0
while($i<128)
if($i=$EVENT_NOTE)
note_off(%Eve_ID[$i])
end if
inc($i)
end while
とすれば、オフにしたキーのみ消えてくれて、全部放すと全部消えてくれる。
しかし、play_noteが開始になってからでないと消えない(1秒経過前にキーオフすると1秒経過後に音が鳴り出し、なり続ける)
###########################
もう一つ注意があるようです。
on controller
message($Stack)
end on
をセットし、
音が鳴っている間、CC1を動かしまわって、$Stackの動きを観察した。
on note
inc($Stack)
wait(1000000)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,-1)
end on
on noteの中でplay_noteは、循環しないらしい。
というのは、50キーを押しっぱなしにしたとき、$stackが1以上増えないからである。
on note
inc($Stack)
wait(1000000)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,0)
end on
の場合も同じであった。
そして先ほどの例のように、
on release
dec($Stack)
$i := 0
while($i<128)
if($i=$EVENT_NOTE)
note_off(%Eve_ID[$i])
end if
inc($i)
end while
end on
relaese内でのnote_offも循環しないようである。
注意すべきは、on note内でのnote_offはon releaseがコールバックされるようで、$Stackが減ります。on release内でのplay_noteは$Stackが増えなかったので、そもそもplay_noteはon noteをコールバックしないっぽい?です。
on controller
message($Stack)
end on
on note
inc($Stack)
wait(1000000)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,0)
wait(1000000)
$i := 0
while($i<128)
if($i=$EVENT_NOTE)
note_off(%Eve_ID[$i])
end if
inc($i)
end while
end on
↑これで50キーを押しっぱなしにして2秒以上の間CC1を動かしまわってメッセージを見ると1秒後に1になって2秒後に0になるのがわかります。
実験中気になったのは
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,0)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,-1)
はon note内だと、前者は無条件にplay_noteが起動し、後者はキーがオンになっている場合にplay_noteが起動しましたが、on release内で使うと、共にキーオフ後でもplay_noteの音がなりっぱなしになるようです。
それをふまえて、
つまり、ややこしいのだが、
on note
inc($Stack)
wait(1000000)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,-1)
end on
on release
dec($Stack)
end on
これは、note_offがなくても、1秒以後にキーを放せば、play_noteの音も止まるが
releaseが2個ずつ働くため、3和音を鳴らすと、1秒以後にキーを放すと$Stackは-3になってしまう。(1音だと-1)
on note
inc($Stack)
wait(1000000)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,0)
end on
on release
dec($Stack)
$i := 0
while($i<128)
if($i=$EVENT_NOTE)
note_off(%Eve_ID[$i])
end if
inc($i)
end while
end on
こちらは、note_offをセットしなければ1秒以後に音が消えてくれないが、1秒以後にキーを放せば、play_noteの音はnote_offにより止まる。
そして、on note内のplay_noteやon release内のnote_offは循環しないようなので、3和音を鳴らし、1秒以後にキーを放しても$Stackは正常に0に戻る。
ただし問題は、一度キーをオンにすると、1秒以内にキーをオフにしても、1秒後に60の音が鳴り始めてしまうことである。(オンにしたキーが生きていればplay_noteを起動するという方法も取れるかもしれないがややこしくなる)
つまり前者の場合、play_noteの音が鳴り始めたあとにキーオフすると、$stackが-(マイナス)に
後者の場合、$Stackに異常は発生しないが、無条件に音が鳴ってしまうという。
そこで偶然良い結果を見つけたので、記しておきます。
前者を使い、on release内でnote_offをセットします。
すると、3和音キーオフ時にreleaseが重複し$stackが結果的に-3になるかと思いきや、
かなりめちゃくちゃな演奏をしても、$Stackが必ず0に戻りました。
最終的にplay_noteを使ったディレイ効果としてよさそうなのは、少し改造を加えて、
on note
inc($Stack)
disallow_group($ALL_GROUPS)
wait(1000000)
allow_group(find_group("Legato"))
%Eve_ID[$EVENT_NOTE] := play_note($EVENT_NOTE,$EVENT_VELOCITY,0,-1)
end on
on release
dec($Stack)
$i := 0
while($i<128)
if($i=$EVENT_NOTE)
note_off(%Eve_ID[$i])
end if
inc($i)
end while
end on
これで、1秒後にグループ"Legato"のキーが鳴り、キーオフで遅れた音も消える、そして$Stackに異常も発生しないプログラムのできあがりです。(保障しませんが)これを応用すると、1つのキーオンで2つ以上の任意の音をつないでレガートを作れるはずです。
$Stackが0のときは通常のグループを鳴らし、$Stack>0のときは、このディレイを使って、2つ以上の音をつなげるLegatoグループを鳴らすというわけです。
KSPの説明書を読むと、コールバック関係のことはしっかり書いてあるようなのですが、英語なので正確につかめないというのが、全ての元凶でした。
しかし、説明書にディレイの作り方を書いてあるわけではないので、良しとしませんか・・・。
実は現在制作中の音源には別の方法をとっています。ひと段落したら今回の方法を試したいと思います。そして不具合があればまた記事を修正なり、更新したいと思います。
以下6月25日追加更新
実際に音源に組み込んでみました。
見事バグが発生しました。
理由はwaitです。
上のスクリプトでは1秒だったので気づかなかったのですが、waitをはさんでグチャグチャやると、$Stackに異常が発生しました。
ここでは振れていませんが、消えるはずのノートが消えなかったりと、いろいろ不具合が出ました。
結局何がおきているかというと、おそらくですが、
1.ノートオン
2.wait
3.play_note(同時にID取得)
4.wait
5.play_note(同時にID取得)
となるところが、速い演奏やあるタイミングで、
1.ノートオン
2.wait
3.play_note(同時にID取得)
4.wait前にplay_note(同時にID取得)
5.wait
6.play_note(同時にID取得)
このへんの関係で、note_offで消えないIDが残ってしまい、on releaseで消すことになり、$Stackが余分に減ってしまうのだと思います。
前回の検証で、play_noteはon releaseで消す(止める)と、play_noteを呼び出したノートを止めるreleaseとplay_noteを止めるreleaseの2つが働いてしまうようで、$Stackが1個余分に減ってしまうらしいことがわかりました。
正しく、on release内のnote_offでplay_noteを止めると、on releaseは一つしか働いてないようで$Stackも1個しか減りませんでした。
つまり、waitの前後の関係でplay_noteで取得したIDが%Eve_IDに無い状態になり、on release時に
note_offで止めれてないこととなり、on release自体で止めることとなり、$Stackが減ってしまった、と勝手に解釈しました。
結果的に、$Stackに異常が出ると先に進めないので、
「後者の場合、$Stackに異常は発生しないが、無条件に音が鳴ってしまうという。」
という方を採用しました。
もう一度おさらいです。
on note
inc($Stack)
wait(1000000)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,0)
end on
on release
dec($Stack)
$i := 0
while($i<128)
if($i=$EVENT_NOTE)
note_off(%Eve_ID[$i])
end if
inc($i)
end while
end on
こちらは、note_offをセットしなければ1秒以後に音が消えてくれないが、1秒以後にキーを放せば、play_noteの音はnote_offにより止まる。
そして、on note内のplay_noteやon release内のnote_offは循環しないようなので、3和音を鳴らし、1秒以後にキーを放しても$Stackは正常に0に戻る。
ただし問題は、一度キーをオンにすると、1秒以内にキーをオフにしても、1秒後に60の音が鳴り始めてしまうことである。(オンにしたキーが生きていればplay_noteを起動するという方法も取れるかもしれないがややこしくなる)
「たぶん」$Stackに異常はでません。そのかわり、小文字で表示したややこしい方法をとることにしました。といってもめんどくさかっただけでそんなにややこしくはないのですが。
on note
%Alive_NOTE[$EVENT_NOTE] := 1
inc($Stack)
wait(1000000)
if(%Alive_NOTE[$EVENT_NOTE] = 1)
%Eve_ID[$EVENT_NOTE] := play_note(60,127,0,0)
end if
end on
on release
%Alive_NOTE[$EVENT_NOTE] := 0
dec($Stack)
$i := 0
while($i<128)
if($i=$EVENT_NOTE)
note_off(%Eve_ID[$i])
end if
inc($i)
end while
end on
ということです。
押したキーが生きてるか死んでるかを判断してやり、生きていればplay_noteするとしてやりました。
これで、やっとwaitがからんでも、$Stackに異常なく正しい動作が可能となりました。(たぶんです)
実際に組み込む際は、waitより前に設定する事項と、あとで設定する事項とがあります。
それをしないと、正しく動作しません。
まだ不具合が出るかもしれませんが、ひとまず安心です。
とにかく、前回の記事(この記事の上のほう)は失敗作です。
条件をつけてplay_noteの最後の引数を0にする方を使うことになりました。
おしまい。
人気の投稿
-
愛用のローランドA-90の鍵盤の中が折れました。 購入から15年で3回目です。 (記憶があいまいで、2回かもしれません) 中が折れる?どういうことかというと、、、 こういうことです。 A-90は、ピアノ鍵盤であり、バネで戻るタイプとは...
-
Hollywood Strings Diamond Edition 買いました。 細かい詳細は、グーグル先生に聞いていただくとして、今回は、Gold Edition との違いである、マイクによる音色の違いを聞き比べてみたいと思います。 まずはこの画像をご覧ください。 ...
-
Hollywood Stringsとは、 これです。はい。 なかなかのお値段ですが、している限りのオーケストラStrings音源ではこれが一番では無いでしょうか。 ただし、HDDでは読み込みに時間がかかるため、 SSDでの使用をお勧め といったところです。 私はオ...
-
人から教わりレンダリングがチョー速くなる方法がわかりました。 知らなかった自分が恥ずかしいです(;´Д`) しかし現段階では、お試しレンダリングに使う感じで、最終出力用にはまだ向いておりません。 とりあえずその方法ですが、 アンチエイリアスをはずす。 以上です。 ...
-
Hollywood Stringsとは、 これです。はい。 前回の続きです。 http://studio-major7th.blogspot.jp/2014/09/hollywood-strings.html 画像で確認していきましょう。 まず、音源側でこのような...
-
Hollywood Stringsとは、 これです。はい。 前回の続きです。 http://studio-major7th.blogspot.jp/2014/09/hollywood-strings_27.html 前回までに、エクスプレッションマップの設定まで進みま...
-
とりあえず、私がKMG7の作者です(・ω・;)ゞ 最近ツイートを見ているとエレキギター音源がどんどん増えている気がします。 外国製品はあまり知らないので、国産品でお話を進めますが。 KMG7はKMGと書きます。 ほか、AとBとCとします。何がどの音源かはご想像にお任...
-
続きです。 おー!やっと鍵盤が付きました。 そしてこの鍵盤、88個のオブジェクトでできています(笑) つまり、やろうと思えば1個ずつアニメーションできるわけです。 とりあえずオブジェクトの作り方として、上から見た鍵盤の写真を元に、サイズを合わせつつ、あとは...
-
やっとできあがりましたね(´=ω=`)ゞ Blenderで作ったグランドピアノです。 まだいくつか修正すべきところや、内部の見えないところにハンマーなど加えたいですが、キリが無いので、これでひとまず完成です。 ...
-
最近思うところあって作曲してないのですが、そんな中で思うことは、やっぱり音楽ってなんなんだろうってことです。 スポーツは、競技としてみんな競いあって喜びや感動を得ているわけですが、芸術って僕は競いあうものじゃないと思うんです。 でも、世の中は売れた作品が素晴らしいものとさ...