トリボナッチ・ポリリズム
トリボナッチ数列に基づき、ポリリズムのテンポで再生。
フィボナッチ数列
F_0 = 1
F_n = F_{n-1} + F_{n-2}
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 | 144 |
トリボナッチ数列
T_0 = 1
T_n = T_{n-1} + T_{n-2} + T_{n-3}
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1 | 1 | 2 | 4 | 7 | 13 | 24 | 44 | 81 | 149 |
| 1 | 1 | 1 | 3 | 5 | 9 | 17 | 31 | 57 | 105 | 193 | 355 |
0開始と、1開始がある。
プログラム
Processingとminimライブラリ
import ddf.minim.*;
import ddf.minim.signals.*;
Minim minim;
AudioOutput out;
SineWave waveA;
SineWave waveB;
String[] T = new String[20];
String patternA, patternB;
int idxA = 0;
int idxB = 0;
int intervalA = 300; // ms
int intervalB = 500; // ms
int lastTimeA = 0;
int lastTimeB = 0;
boolean playingA = false;
boolean playingB = false;
int noteDurationA = 200; // ms
int noteDurationB = 300; // ms
char currentCharA = ' ';
char currentCharB = ' ';
void setup() {
size(600, 300);
minim = new Minim(this);
out = minim.getLineOut();
generateTribonacci(13); // ★ T[12] で約1500文字 → 1分以上の演奏に対応
patternA = T[12]; // 長めのトラック
patternB = T[11];
waveA = new SineWave(440, 0.0, out.sampleRate());
waveB = new SineWave(660, 0.0, out.sampleRate());
out.addSignal(waveA);
out.addSignal(waveB);
textAlign(CENTER, CENTER);
textSize(80);
frameRate(60);
}
void draw() {
background(255);
int now = millis();
// トラックA処理
if (idxA < patternA.length() && now - lastTimeA >= intervalA) {
currentCharA = patternA.charAt(idxA);
waveA.setFreq(charToFreqA(currentCharA));
waveA.setAmp(0.5);
lastTimeA = now;
playingA = true;
idxA++;
}
if (playingA && now - lastTimeA >= noteDurationA) {
waveA.setAmp(0.0);
playingA = false;
}
// トラックB処理
if (idxB < patternB.length() && now - lastTimeB >= intervalB) {
currentCharB = patternB.charAt(idxB);
waveB.setFreq(charToFreqB(currentCharB));
waveB.setAmp(0.5);
lastTimeB = now;
playingB = true;
idxB++;
}
if (playingB && now - lastTimeB >= noteDurationB) {
waveB.setAmp(0.0);
playingB = false;
}
// 画面表示
fill(0);
text("A: " + currentCharA, width * 0.3, height / 2);
text("B: " + currentCharB, width * 0.7, height / 2);
}
float charToFreqA(char ch) {
if (ch == 'a') return 110;
if (ch == 'b') return 220;
if (ch == 'c') return 440;
return 110;
}
float charToFreqB(char ch) {
if (ch == 'a') return 220;
if (ch == 'b') return 440;
if (ch == 'c') return 880;
return 220;
}
void generateTribonacci(int n) {
T[0] = "a";
T[1] = "b";
T[2] = "c";
for (int i = 3; i <= n; i++) {
T[i] = T[i - 1] + T[i - 2] + T[i - 3];
}
}
