簡単なヤツをちょこっと作ってみました。
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方向に別れるかなあ?