ChucK で波形を表示する

ChucK で作業してると波形を直感的に眺められなくて困る…なんてつぶやいてしまうと、ChucK 使うなと怒られそうだが。ChucK のデバッグプリントを使ってコンソールに簡単に波形を表示できるようにしてみた。

fun string display(float gain) {
  50 => int MAX_LINE;

  string line[MAX_LINE];
  line.cap() / 2 => int center;
  for(0 => int i; i<line.cap(); i++) {
    if(i == center) {
      "|" @=> line[i];
    } else {
      if((i - center) % 10 == 0) {
        ":" @=> line[i];
      } else {
        "." @=> line[i];
      }
    }
  }
  (center + gain * 10) $ int => int pos;
  if(pos < 0) {
    "!" @=> line[0];
  } else if(line.cap() <= pos) {
    "!" @=> line[line.cap()-1];
  } else {
    "*" @=> line[pos];
  }
  "" @=> string value;
  for(0 => int i; i<line.cap(); i++) {
    line[i] +=> value;
  }
  return value;
}

// test
SinOsc osc => dac;
440 => osc.freq;

while(true) {
  <<< display(osc.last()) >>>;
  100::samp => now;
}

適当にサイン波を表示してみる。

% chuck display.ck
".....:.........:.........*.........:.........:...." : (string)
".....:.........:.........|....*....:.........:...." : (string)
".....:.........:.........|.......*.:.........:...." : (string)
".....:.........:.........|........*:.........:...." : (string)
".....:.........:.........|.......*.:.........:...." : (string)
".....:.........:.........|...*.....:.........:...." : (string)
".....:.........:........*|.........:.........:...." : (string)
".....:.........:...*.....|.........:.........:...." : (string)
".....:.........:*........|.........:.........:...." : (string)
".....:.........*.........|.........:.........:...." : (string)
".....:.........:*........|.........:.........:...." : (string)
".....:.........:....*....|.........:.........:...." : (string)
".....:.........:.........*.........:.........:...." : (string)

ChucK に文字列を操作するための組み込み関数がほとんどないので、まじめに実装しようと思うと色々とつらいものがある。実際のところ使い物になるのかっつーと激しく疑問ではあるけれど、奇麗な波形を眺めることができたのでひとまずは良しとする。