LoginSignup
2
1

More than 5 years have passed since last update.

GLSLで音楽(和音を使ってみる)

Last updated at Posted at 2018-06-28

和音をどう扱うのか

しばらく音楽理論と格闘して、シンプルなとこ見つけた。sus4とかセブンスを使わないでオーソドックスなところで行くなら、文字数使わずに書けそうです。
キーをC3、ノート番号でいうと60にします。ピアノの白鍵だけがメジャースケールになります。このスケールをこう書きます。

#define Scale 60+int[](0,2,4,5,7,9,11,12,14,16,17) 
//例えばドなら
int do = (Scale[0]);
//例えばミなら
int mi = (Scale[2]);
//例えばソなら
int so = (Scale[4]);

メジャーコードとかマイナーコードとかあるけど、スケール使っての和音なら,スケールのインデックスをaとした場合

(Scale[a])
(Scale[a+2])
(Scale[a+4])

この組み合わせが和音になります。この仕組みを使います。
Iはa=0
IImはa=1
IIImはa=2
IVはa=3
Vはa=3
VImはa=5
VIIm_5はa=6
でいけます。
これを踏まえた上でサンプルを書きます。コード進行は王道進行(Ⅳ→Ⅴ→Ⅲm→Ⅵm)を使ってみます

#define BPM 120.
#define A (15./BPM)
#define B (240./BPM)

float distortion(float gain, float d)
{
    return clamp(gain * d, -1.0, 1.0);
}

float sound(float f, float time)
{
    return distortion(sin(6.2831*f*time), 2.5) *exp(-time*3.0);
}

float note2freq(int n)
{
    return 440.0*exp2((float(n)-69.0)/12.0);
}

#define Scale 60+int[](0,2,4,5,7,9,11,12,14,16,17) 

float chord(int a, float time)
{
    return (
        sound(note2freq(Scale[a]), time) +
        sound(note2freq(Scale[a + 2]), time) +
        sound(note2freq(Scale[a + 4]), time) 
        )/3.0;
}

float sequenceTime(int s,float time)
{
  float n =mod(time,A);
  for(int i=0;i<16;i++){
    if((s>>(int(time/A)-i)%16&1)==1)break;
    n+=A;
  }
  return n;
}

vec2 mainSound( float time)
{
    int n = int[](4,5,3,6)[int(time/B)%4]-1;
    return vec2(chord(n, sequenceTime(0x0101, time)));
}

この音はshader toyで聞けます。

ベースについて

ベースラインはコードのルート音を弾くのが基本らしいので、この応用も利きそうです。

GLSLで音楽の記事

GLSLで音楽(はじめに)
GLSLで音楽(まずは、ドラムだ)
GLSLで音楽(メロディーいってみます)
GLSLで音楽(今までの応用の一つ)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1