その内容は以下のようなものだった。GenはMaxのパッチワーク環境の拡張で、ビジュアルにビルドしたものを効率的なコンパイルコードに変換しながら進めていくものです。外部で使用することができます。オブジェクトが含まれています。Tutorials」は僕には不要なものだった。見てみると、ここはなんと「GEN大喜利大会」という無法地帯だった(^_^;)。Series」から順に眺めていくことにした。Anxiety」(不安の解消)というコラムもあった。help」という概説までで、これはアッサリと読み終えた。(類似点と相違点)は、これまでMaxを使いこなしてきた僕には逆に重要なパートである。Attributes」と進んだが、このパートも問題なかった。実際にExamplesを触って、何か問題があればここに戻ってくることにしよう。あたりから、ちょっとゆっくりと試してみることにした。演算子を追加すれば、準備は完了です。調べる必要がありそうだ。上のパッチは従来のMSPのサウンドバッファを経由せず、サンプルポイントごとにサウンドサンプルをcounterで読み出してはそのデータごとにサウンド出力しているというもので、それだけでも十分に凄い。以下のように、さらに「スピード」で指定したり「周波数」で指定して、可変のサンプル再生が可能になるのだった。Messages」というのも大きな違いである。「シングルサンプルGen~の世界では、バングメッセージのない世界で生きるという、ちょっと変わった特徴があるんです。Gen~の世界では、通常のMaxパッチのイベントレート(bangメッセージを使用)やMSPのオーディオレート(シグナルベクターごとに1回値を送信できる)ではなく、一度に1サンプルずつ操作しているのです。Genの世界では、パルスはバングメッセージに相当するもので、1サンプルの時間枠内で起こるゼロ値から任意の非ゼロ値への遷移を指します。Genの環境では、このシングルサンプル長のパルスをいたるところで使用しています」というのは、ちょっとした発想の転換である。latch」という下の方)はなかなか刺激的なものだった。MSPをオーディオレート領域で使用する場合、スレッショルド値に基づいてオーディオレート入力をサンプリングするためにsah~オペレータを使用したことがあると思います。latchオペレータも同様ですが、これはスレッショルドを使用しません。ラッチオブジェクトの右インレットに0でない値を送ると、左インレットに入力されたサンプルはすべて渡されます。ラッチオペレータは、次のゼロ入力を受け取ると、その左インレットで受け取った最後の値を出力し続けます(ラッチオペレータをインスタンス化したときのデフォルトの最後の値は0ですが、ラッチオペレータの@init属性を使用して変更することができます)。上の例は、ランダムなソースを手動でサンプリングする方法を示しており、2番目の例は、少しのMSPパッチを使用して自動的にクリックを駆動する方法を示しています(あなたは、MSPを使用して、クリックを生成するためにITM値を使用して実験することが望ましいかもしれません)。このシンプルでわかりやすい手間いらずのデザインは、様々な場面で非常に役に立ちます。Genが動作するシングルサンプルレートより低いレートで周期的に値を出力することです(このテクニックの動作の素晴らしい例として、Genのexamplesフォルダにあるgen~.chaos.maxpatパッチャーを見てみてください)。パッチの中で、ラッチが何度も使われているのを見ることでしょう。いう小さなパッチが含まれており、いくつかの簡単な演算子でできることのいくつかを見て、あなたの食欲を少し刺激することでしょう。楽しんで、そしてパッチャーで何が起こっているのかを調べてみてください。ここで「ラッチ」がこれほど活躍するとは思ってもいなかった。音源LSI(DSP)を設計していた頃、システムクロックで全てのデータをその瞬間に保持するというラッチは、全ての基本だった。主役は、ラッチであるとも言える。以下の回路図を見れば、まさに「ラッチ(574)の山」である。続いているが、ゼミ吉田さんアポの作戦会議、そして領域の教務関係の連絡があったりしたのでここで今日はオシマイとなった。オブジェクトの内部では、シングルサンプルパルスが広く使用されています。この考え方のコツをつかめば、gen~オブジェクトの内部でロジックを扱う際の多くのことがよりシンプルになります。加えて、ロケット手術を行わなくても、素敵なノイズを作ることができます」と書かれていれば、これは何とか頑張ってみようという気になる。(comparator)という演算子は、左インレットに送られたパルスに反応します(実際には、+=演算子やplusequals演算子のように、2つの異なるエイリアスを持つ同じ演算子です)。そのパルスを見たとき、第1インレットに送られた0以外の値は、第2インレットで受信したものを通過させます。0の値は、第3のインレットで受信したものを通過させます。Sync的に使えそうだったので、さっそく上(下)のように3つ並べてみた。CPUの重さは激軽なので、これなら相当に多重化できそうだ。演算子の初期状態をリセットするためにパルスを使用してきました。サンプルごとの非ゼロ値の出現は、Gen~のツールボックスの中で、最も地味な状況においても、強力なツールです」とあった。上のように、こちらもサンプルのブロックを3つ並べてみたが、これらに個別に多数のセンサ情報を与えることで、何か面白い音響が生成できないか、いずれ試してみよう。pulses」として、上のようにcounterオブジェクトを「生のサンプリングレートで刻々と」up/dpwn/updownカウンタにする、というのも容易に実現できることが示されていた。Sync的に使えそうな気がする。オペレータは、パルスを入力として働くだけでなく、パルスを出力することもできます。その出力がoutオペレータに送られる場合、scope~オブジェクトを使って出力を見ることができます。ロジックを追加することができます。演算子)がレート演算子の出力をゼロに戻し、チェンジ演算子がその低下を負の値として報告すると、パルス(1の数値からなる「メッセージ」と考えてください)を送ることを示しています(ところで、チェンジ演算子は任意のステップ信号を一連のパルスに変換する最も簡単な方法です)」・「クロック乗算器も同じように動作します。レート演算子に異なる引数を使用するだけです。入力にparam演算子を使用してレート演算子の値を設定できるクロック乗算器/除算器を作成できるかどうか、ちょっと試してみるのもよいかもしれません」と、上のようなサンプルがあった。クロックデバイダをこんな風に設計するという発想は無かったが、これはどうも、だいぶ頭を柔らかくする必要がありそうだ。ここで出てきた「history」オブジェクトは、おそらくGENの「肝」なので、今後も注目していこう。Part....」では、「ここで説明した多くの機能を使用するGen~パッチの例として、あなたがいつも使っているもの、しかしその繊細さがあまり知られていないかもしれないものをエミュレートしています:MSPゲイン~オブジェクトです。皆さんは、レベルをコントロールするためにgain~オブジェクトをいつも使っていると思います。フェーダを動かしている間、実際には進行方向を追跡し、スムーズな出力を生成するために作業している間、その入力を増加または減少させているのです。これは、実は奥が深く、微妙なMSPオブジェクトなのです。ここに、gain~オブジェクトと同じ機能を果たすgen~パッチャーがあります」ということで、上のようなサンプルがあった。最後のあたり「control_12.maxpat」で、入力データを「細かくサンプルしつつ指数関数的に補間する」というパッチで行っていた、上のような考え方に似ている気がした。そこでとりあえず、「control_12.maxpat」のサブパッチ部分を「gen」で置換できるかどうか・・・とやってみたのが以下である。)が使えないらしい、とは分かったものの、「if」も駄目だと判明したのは大きな収穫である。GENを作る(過去のパッチをGEN化する)のは先だ、と判明したところで今日はオシマイとなった。終わって、明日はその次からである。2022年8月10日(水)明日は祝日、その後はお盆の連休に突入するという時期なのだが、CIVID-19は相変わらずである。機材返却のアポを入れていた鈴木さんは家族のコロナのためアポをキャンセルして、あと同様に機材返却の小島さんのアポがあるだけで、週2のギター(20分)と午後のJoyJoyヒトカラぐらいしか他に予定の無いこの日は、実質は半日もないものの、格好のお勉強日和ということになった。この冒頭、「あなたはGenでの作業を学ぶことに興奮し、genオブジェクトのヘルプファイルを開き、ヘルプファイルのbuffer-and-dataタブをクリックし、中身を見るためにgenオブジェクトをダブルクリックすると...というのは、よくある問題です。あなたは混乱したオプションのセットに直面することになります。誤解しないでください。ヘルプファイルに書かれていることは、素晴らしい可能性の全宇宙を簡潔に、そして有用な形で抽出したものです。基本的な例をいくつか見ていく方が簡単だし、その過程でちょっと楽しくなってくるかもしれません。Cookが2001年のNIME基調講演で述べた、新しい楽器をデザインするためのアドバイスを紹介しましょう」とあった。Cook氏の写真を発掘した。Cook氏から僕に依頼のメイルが届いたのはだいぶ昔のことだった。Cook氏の論文を参照していた。Mathews先生の姿もあった。Zicarelliが作ったのがその名をとった"Max"だったのだ。Zicarelliは現在までCycling'74社のCEOとして、Max8までの全てのversionの現役メインプログラマーである。access」ということで、「ここで紹介するプレイバックのテクニックは、gen~パッチャーにあるバッファ演算子とデータ演算子の両方に使えますが、ここではバッファ演算子に焦点を当てます。Bufferを1アドレスごとにアクセスしているのに驚かされる。「先週紹介した基本的な再生パッチのバリエーションをお見せしたいと思います。sections」というパラメータが3とか10であればこれまで聞き慣れた「random_section_playback」だったものの、これを100とか200とかまで上げられるというのに驚いた。「パッチャーの残りのロジックは、次の2つのことを行うためのものです。(1)バッファの内容を等しいセクションに分割する、(2)バッファの内容を均等に分割し、その中からランダムに1つを選んで再生する。サンプル数で数えるので、バッファを等しいセクションに分割するのは、バッファ内のサンプル数をセグメント数で割ればよいだけです」と、言われてみればその通りだが、これはDJプレイには強力な武器になりそうだ。演算子が含まれていることにお気づきでしょう。演算子と同じ名前の引数を取ることに気づけば、この演算子が何をするものなのか、おそらく見当がつくでしょう。これは、あなたのパッチをもう少しスパゲッティ・パッチコードのない状態に保つのに役立ちます。このGen~パッチャーで、ランダムセクションを選択して再生する部分では、乱数ソースとしてノイズオペレータを使用しています。カウンタ演算子が限界に達するたびに、前回のチュートリアルで紹介したラッチオブジェクトにパルスを発し、ラッチオブジェクトはノイズ演算子から値を取得して保持します(ノイズ演算子の出力は波形なので、スケール演算子を使用して適切な範囲に収め、0から最終セグメント(もちろんセグメント番号は-1)までの数値を与える必要があります)。これは、小数点の右側の部分を取り除くことによって浮動小数点数を整数値に変換するものです。セグメント番号とセグメント内のサンプル数が分かれば、あとはピーキングオペレータに送るカウント値を、再生したいセグメントの開始位置に対応するサンプル数だけオフセットすればよいだけで、あとはちょっとした掛け算と足し算だけです。これらのパッチで作業していると、おそらく遭遇することの1つは、ここにあるサンプルファイルがモノラルファイルであるということです。ステレオバッファ〜オブジェクトを使って作業したいかもしれません。するためには、もちろん、あなた自身のステレオバッファ〜オブジェクトを親Maxパッチに追加するか、replaceメッセージを使用することになります。peekオペレータの新しいアトリビュートを使います。これは、存在しない再生チャネルを選択した場合、ラップして存在するチャネルを選択することを保証するものです。チャンネル0と1を要求した場合、モノラルのファイルであれば0と0が再生されます。この実例は後に出てくることになる。」と続いていて、なかなかここの著者は親切なのだった。環境ではバッファやデータ演算子を扱うための興味深いメソッドが他にも用意されています。簡単に言うと、これらのメソッドは、バッファオペレータから情報を取得するために、異なる種類の信号入力を使用します」とのことで、peek以外の演算子についての話題となった。上のサンプルでは、phasor~で基本的なサンプル読み出しスピードを自在に設定した上で、rate~で設定した値に応じてgen~内部で読み出しアドレスを変調して、第2のgen~内部のlookup演算子のパラメータを生成している。これもまた、DJ屋であればあれこれ改造したくなる、格好の材料のようだ。playback」と解説が続いたが、どうも僕にはあまり美味しい感じがしなかったので軽くパスした。(^_^;)考えてみれば、信号処理の際に値をサンプルの集まりのインデックスとして使う場面はもうひとつある。この場合、入力信号を使って、ある種の伝達関数を含むバッファのインデックスを作り、その結果を再生に利用するのです。インデックスのために使用する入力は信号なので、インデックスのために使用する範囲は、phasor~/phasorが与える0.-1.0の出力ではなく、-1.0から1.0という標準の信号範囲になります。lookup~オブジェクトを使ったことがある人は、その使い方にも慣れていることでしょう)。オブジェクトの出力を書き込む方法を示しています。オペレータを関連付け、波形整形を行う準備ができました。mayhem」となった。上のサンプルは、自分で波形テーブルを描画して、それに従ってウェーブシェーピングを行うという、まぁ古典的な処理をGenで実装したものだという。僕はどちらかというとWaveShapingはお好みの範疇ではないので、ここは軽く読み流す感じになったが、「歪み好き」な人たちにとっては、ここは美味しいところなのだ。wave-ing」では、peekに続いて、遂に「poke」がやってきた。リアルタイム(サンプリング周波数)で、波形メモリをpeekするだけでなく、ライヴ・サンプリングとして波形メモリにpokeできるとすると、これはちょっと面白い可能性が出てきた。オブジェクトのレートを変化させます。rateオペレータに送られる値は、スタートポイントとエンドポイントのサンプル値の一方または両方が変更されるたびに、バッファの何パーセントが再生されるかを知ることに基づいて計算されます。オペレータを使用していることです。演算子と同様に、バッファの名前を引数として受け取ります。オブジェクトの右アウトレットからの接続を使用するかのように、その名前のバッファに含まれるチャンネル数を出力します。上のサンプルでは、サウンドとしては可変リバーブのようだが、gen~の中身を見てみると、まず刻々と「可変poke」で波形バッファに書き込みつつ(historyで遅延ループあり)、それを「可変peek」で読み出すことで遅延ループのリバーブを実現している。これはかなり画期的で、DSPモニタのCPUも4%程度と「超軽い」処理なのだった。今後はもう、ディレイ/リバーブ系はGENでないと駄目っぽい感じである。