128 Voices Generator by 0b5vr
#Entity_Music #bytebeat.demozoo.org #bytebeat
https://youtu.be/y0DOxMxbgdc
128 Voices Generator by 0b5vr
243 chars Bytebeat (bytebeat.demozoo.org)
Appeared in Lovebyte 2024 Bytebeat Music Compo
https://demozoo.org/music/337718/
https://bytebeat.demozoo.org/#t=0&e=0&s=48000&bb=5d00000100f20000000000000000240f4923d194b95238ce9a3e995469870563ec58ea7f8ff22178227d29ce5e17ffe59b64c6fcf3ce5bda591ea16b2c6f0ab72e265f3b7b30cba3adcd1eaabb95f3e63fda7de7020668838a6c821cb18d8c71ab700d413efde718a26aeee4acc08726c77fd2ca29d15a52c0deb33d3c592852fc0bfb36dc869fcda72e1da3c00f99d9f679a4b604564cdca8283ce73dd47dbf1e7fc5e67161c48915df0b154b774ec22725ab4c5705dd7b5f97338fa63da2520ecde5566f8611ed94c3651e022388364c1d3414e444cc9acf49b573b9ff6d1bc000
Write-up
Beautified Code
code:js
H=i=128,
s=t/5e3,
o=H,H,
F=i=>((57454323>>4*i&31)-(s>>3&4))/12,
(_=>{while(i--)oi%2+=
sin(40*log(s%4)+9*s)/3
+s%4*(
exp(-s%1*2)*(
(t*2**[
F(7)-2,
5+i/90,
F(~~s-4*(i<48))+i%4/H
]i%3+s%1*i/5&H)-64
)
+(t*2**(F(i%7)-(i/2&1))+1e4*sin(i+s/H))%H-64
)/H
})(),
o
H は様々な用途で使われる定数 128
i は 128 から 1 まで1ずつデクリメントされていくループ用インデックス
o は最終出力 (2 channels)
F (pitch function)
F はコードの構成音から1つpitch (log2 of frequency) を持ってくる関数
57454323>>i*4&31 は、引数となる整数 i が 0 から 7 まで変化するごとに
19, 15, 14, 10, 12, 22, 3, 0 と変化する
code:heck
1P 3m 7m^ 1P^ 7m 2M^ 3m^ 5P^
0 3 22 12 10 14 15 19
0000 0011 0110 1100 1010 1110 1111 0011
= 57454323
s>>3&4 はstepが32変化するごとに4半音トランスポーズを行う
Chord: 平行移動ってやつ
最後に /12 で割って十二平均律の音階にしてやる
実際に2の肩に乗っけるのはこの関数を使うとき
The loop
(_=>{while(i--)o[i%2]+= ... })()
本コードの肝となるループ部分
単純な波形をピッチをずらしつつ複数鳴らすことによって、SuperSaw的なユニゾンを生み出すのが基本的なコンセプト
bytebeat.demozoo.orgにおいて、入力したコードは式として評価されるため、ここに文(statement)を置くことはできない
ただし、式の中で即時関数を実行することはできるので、その中でwhile文を実行してしまう
さらに、式の中でカンマ区切りで複数の式が使われている場合、返り値となるのは最後の式であることを利用する (最後の ,o )
o[i%2]+= によって、左右のチャンネルそれぞれ交互に各64回加算代入がされる
Kick
sin(40*log(s%4)+9*s)/3
ほぼほぼfendoap先生の受け売り
sin の中に log を入れることによって鋭いアタックを生み出すことができる
いままでずっと exp でやっていたが、sizecodingにおいては log はたいへん優秀
log(0) で -Infinity ができてしまうのであんまりお行儀は良くない。logの中の式に 1e-3 とか適当な定数を足してやったほうがお利口
リリースの太さを調整するため、 9*s を追加した
Sidechain
s%4
後述するBass, Hihat, Arp, Chordに対してかかるサイドチェイン
極めてシンプルだが、あるとないとでは音のメリハリが全く変わってくる
Bass, Hihat, Arp
code:js
exp(-s%1*2)*(
(t*2**[
F(7)-2,
5+i/90,
F(~~s-4*(i<48))+i%4/H
]i%3+s%1*i/5&H)-64
)
ベースシンセ・ハイハット・アルペジオを1つの式で一気に生成している
どれも &H によって矩形波を生成しているが、 i%3 でループごとに3種類の音階を選択して実現している
F(7)-2 がBassに対応
単純に F から生成した主音を2オクターブ下で鳴らしているだけ
5+i/90 がHihatに対応
i/90 によって対数で等間隔の不協和音を生成する
TR-808のハイハットやSinewave Shotgunに近い手法
F(~~s-4*(i<48))+i%4/H がArpに対応
i%4/H によってデチューンのかかったユニゾンを生み出す
4*(i<48) はディレイ的な効果を生み出す
共通部分の s%1*i/5 は、ユニゾンごとに少しだけ位相をずらすことによってエンベロープのかかったローパスフィルター的な効果を生み出している
Bassで特に顕著
以下に、式内の各項が i ごとにどうなっているかを表で示す
https://observablehq.com/d/af4b99973a40285c
Chord
Supersawでコードを鳴らす部分
%H によってノコギリ波を鳴らしている
F(i%7)-(i/2&1) の部分は、左右チャンネルでバランスよく聞こえるようやや説明の面倒な数字あそびをしているものの、結局はコードの構成音を2オクターブにわたって鳴らしたいだけ
位相のシフト 1e4*sin(i+s/H) によってムラのないデチューンを生み出す
下手にピッチに対して i/H/H とかを足しちゃうと、再生開始直後にフランジャー的な違和感のある音が生まれてしまう