Skip to content

Instantly share code, notes, and snippets.

@0b5vr
Last active August 7, 2021 14:55
Show Gist options
  • Save 0b5vr/e0df8119d79dc67a7d3cbf7d73268d52 to your computer and use it in GitHub Desktop.
Save 0b5vr/e0df8119d79dc67a7d3cbf7d73268d52 to your computer and use it in GitHub Desktop.
prod05 sierpinski chord by 0x4015完全理解した
// https://www.youtube.com/watch?v=H8UqnTE3mUY より引用
#define A for(int i=0;i<9;++i){int y=p>>((p>>19)+i&3),z=p*((878086607>>(i&7)*4)&15)*(510+1%5)>>14;if((p>>15&1<<(i&15))>0)s.y+=float(((y>>7&z*3|y>>11&z*6)&1023)-512)/3e4;}
vec2 mainSound(float t){int p=int(t*144e3);vec2 s;A;s.yx=s;p-=65536;A;return s*mat2(7,1,5,-3);}
// 原文ではマクロ
void A(int p, inout vec2 s)
{
for(int i=0;i<9;++i)
{
// iが3変わる・サンプルが2^19変わるごとに周期が半分になっていくノコギリ波(AND取ればノコギリ波になる)
int y=p>>((p>>19)+i&3);
// 倍音をノコギリ波で作っている(AND取ればノコギリ波になる)
// `((878086607>>(i&7)*4)&15)` の部分は:
// - i=0 ... 15 : 3oct + maj7 - 11.731cent
// - i=1 ... 12 : 3oct + 5 + 1.955cent
// - i=2 ... 9 : 3oct + maj2 + 3.910cent
// - i=3 ... 8 : 3oct
// - i=4 ... 6 : 2oct + 5 + 1.955cent
// - i=5 ... 5 : 2oct + maj3 - 13.686cent
// - i=6 ... 4 : 2oct
// - i=7 ... 3 : 1oct + 5 + 1.955cent
// - i=8 ... 15 : 3oct + maj7 - 11.731cent
int z=p*((878086607>>(i&7)*4)&15)*(511)>>14;
// ここの条件式がtrueのときのみ音がなるっぽい
// i=0 : .x.x.x.x.x.x.x.x
// i=1 : ..xx..xx..xx..xx
// i=2 : ....xxxx....xxxx
if((p>>15&1<<(i&15))>0)
{
// t>>x&t はシェルピンスキーの基本形
// y>>7&z*3 : 音程の低い、速く変わる音
// y>>11&z*6 : 音程の高い、遅く変わる音
// これが取りうる値の範囲は[-512 - 511]
s.y+=float(((y>>7&z*3|y>>11&z*6)&1023)-512)/3e4;
}
}
}
vec2 mainSound(float t)
{
int p=int(t*144e3); // 再生速度が変わるだけ。大した意味はない
vec2 s; // 最終出力
// マクロ発動
A(p, s);
s.yx=s; // sの左右を入れ替えている。各 `A` マクロは片方のチャンネルにしか音を生成していない
p-=65536; // 左右でちょっと音の出るタイミングをずらしている
// もう片方のチャンネルにも同じことをする
A(p, s);
return s*mat2(7,1,5,-3); // ミキシング
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment