見出し画像

Csoundでシフトレジスタ&AU/VST plugin化 (1/3)

以前の記事で説明したシフトレジスタをCsoundでプログラミングし、AU/VST plugin化します。

プロトタイプ1:シフトレジスタの動作確認のための単純なプログラム

まずは、シフトレジスタの基本動作が確認できるような、単純なプログラムを作成します(音出力は無し)。簡単にするために、シフトレジスタは8 bitの固定とし、ランダムネスは導入せずに、単にビットを右シフトするだけのものを考えます。
なお、慣習的に最下位のビットはbit 0、最上位のビットbit 7と呼ぶので、以下このように表記します。

作成するロジック

  1. シフトレジスタの変数名をavalとし、初期値をセットする

  2. metroで1秒に1回ビットシフトするためのトリガーを生成する

  3. トリガーの値が1の時、以下を実行する

    1. シフトレジスタの値を2進数と10進数の両方で表示

    2. シフトレジスタのbit 0の値を保存

    3. シフトレジスタの右シフト実行

    4. 保存したbit 0の値をbit 7に入れる

Csoundによるビット操作

Csoundでは'>>'で右ビットシフトが行えます。右シフトすると、bit 1がbit 0にシフトされ、元のbit0の値は上書きされます。 またbit 7には0がセットされます。
ビットシフトする前に、元のbit 0の値を取り出しておく必要がありますが、Csoundには特定のビットの値(0 or 1)を取り出す命令はないので、ビット演算子のAND(Csoundでは'&')を使って以下のようにします。

bit 7の取り出し:avalと$${2^7=128}$$をANDした後128で割る
bit 6の取り出し:avalと$${2^6=64}$$をANDした後64で割る
・・・
bit 1の取り出し:avalと$${2^1=2}$$をANDした後2で割る
bit 0の取り出し:avalと$${2^0=1}$$をANDした後1で割る

avalの値からbit 7を取り出すときは、(aval&128)/128、bit 0を取り出すときは(aval&1)/1となります。

avalをビットシフトした後は、bit 7は0になっています。取り出した元のbit 0の値をbit 7に戻す方法は、以下のようになります。
aval = aval + $${(2^7)}$$*(元のbit 0の値) = aval + 128*(元のbit 0の値)

以上の2進数独特の取り扱いについては、ここでは詳細説明をしませんが、興味のある方は「ビット演算」などのキーワードで調べてみてください。

Csoundプログラムのコア部分は以下のようになります。

;Trigger for bitshift, 1 shift per second
kpulse metro  1

;Convert to k rate for printing
kval = k(aval)
printf "Decimal = %d, Binary = 0b%d%d%d%d%d%d%d%d, Bit0 = %d\n", kpulse, kval, (kval&128)/128,(kval&64)/64,(kval&32)/32,(kval&16)/16,(kval&8)/8,(kval&4)/4,(kval&2)/2,kval&1,kval&1

;Bitshift
if (kpulse == 1) then
  abit0 = aval&1
  anewbit7 = abit0
  aval = (aval>>1)  + anewbit7*128  ;bit shift
endif

プロトタイプ1のCsoundプログラム

このプログラムでは音は生成しません。1秒に1回ビットシフトし、シフトレジスタの値を表示します。シフトレジスタの初期値は185(2進数: 10111001)としているので、出力の期待値は以下のようになります。ログから、期待値通りにシフトレジスタが動作していることが確認できます。

185  (10111001)
220  (11011100)
110  (01101110)
 55  (00110111)
155 (10011011)
205 (11001101)
230 (11100110)
115 (01110011)
185 (10111001)
・・・

実行ログ

次回は、作成したシフトレジスタにランダムネスをコントロールするロジックを入れます。

Version history
v1.0 : 2021/12/19公開




この記事が気に入ったらサポートをしてみませんか?