簡単なヤツをちょこっと作ってみました。
PB303 音が大きいかもしれないのでので注意
マウスを左右に動かすことでLow Pass FilterのCutoff Frequencyを操作します。いけてない点としては
- リアルタイムではなくAudioStreamのバッファサイズの切れ目(=ループの切れ目)でしかフィルタの変化が反映されない → バッファ小さくする以外に良い方法がないか調べる。あんまりリアルタイム性にこだわると苦しいのかも
- Cutoff Frequencyが小さくなるとノイズが発生 → アルゴリズムを見る
ソース
import krister.Ess.*;
int WIDTH = 400;
int HEIGHT = 200;
AudioStream myStream;
SawtoothWave myWave;
int duration = 6000;
int offset = 0;
int BUFFSIZE = 24000;
void setup() {
size(WIDTH, HEIGHT);
for (int x = 0; x < WIDTH; x++) {
stroke(255 * ((x + 1.0) / WIDTH));
line(x, 0, x, HEIGHT);
}
Ess.start(this);
myStream = new AudioStream(BUFFSIZE);
myStream.smoothPan = true;
myWave = new SawtoothWave(55, 0.5); // ノコギリ波
myStream.start();
}
void draw() {
}
void audioStreamWrite(AudioStream s) {
// バッファに対して1ループ分をgenerateする
for (int offset = 0, beat = 0; offset < BUFFSIZE; offset += duration, beat++) {
myWave.frequency = arpeggiator(beat);
myWave.generate(myStream, offset, duration);
}
if (mouseX != 0) {
// 横軸のスケールはいい加減です
LowPass lp = new LowPass(440 + 8000 * ((float)mouseX / WIDTH), -20, 16);
lp.filter(myStream);
}
}
float arpeggiator(int beat) {
// A0,A1,A0,E1
int[] notes = {
33, 45, 33, 40
};
return getFrequencyByNote(notes[beat]);
}
float getFrequencyByNote(int note) {
return 55 * pow(2, ((note - 33) / 12.0));
}ProcessingでEssを使うアプローチとしては
の2方向に別れるかなあ?