LoginSignup
39
40

More than 5 years have passed since last update.

コードを音楽にする「コードサウンド」をWebAudioAPIで作った

Posted at

2014-09-16-codesound.png

この前、ハッカソンで作る機会があったので作ってみた。そろそろコードレビューは次世代に行ってもいいと思う。字面や挙動を追うのではなく、コードが奏でる音。それで良し悪しを判断する。…くると思います。いや、こないか。

こちらが、成果物のコードサウンドちゃん。動作確認はChromeでしかしてないので、ごめんなさい+コードはかなり汚いです、ごめんなさい。

どんな動作するのかというと、コードを文字単位に切って、文字に対して音を割り当てて、それを単純に再生させているだけ。一応、タブコードでのインデントがあると、再生速度が上がっていきます。つまり、ネストが深いコードは音が早くて聞きにくくて、ダメコード!っていうわけです。まぁ、実際は早い部分がないと飽きちゃうんですけどね。

そんで、ハッカソン開催した時の記事はこちら。どんなハッカソンだったのか参考までに。

Web Audio API

今回はじめてまともにWeb Audio APIなるものをさわったのだけど、こいつは凄い。音声の処理や合成を簡単にやってくれる。キーボードピアノだって作れる。

javascript
var AudioContext = window.AudioContext || window.webkitAudioContext,
ctx = new AudioContext();
var oscillator = ctx.createOscillator();
var gainNode = ctx.createGain();
oscillator.type = 'sawtooth'; // 音の波形
oscillator.detune.value = 0; // 音の高さとか調整?
oscillator.frequency.value = 880; // 周波数 880Hz
gainNode.gain.value = 0.05; // 音量

oscillator.connect(gainNode);
gainNode.connect(ctx.destination);

oscillator.start();

これだけで、音が鳴る!簡単。

波形

oscillator.typeで音の波形、なる音のタイプを選択できる。個人的には、sineとsawtoothが好み。

  • 正弦波 : sine
  • 矩形波 : square
  • ノコギリ波 : sawtooth
  • 三角波 : triangle
  • カスタム波形 : custom

ハマった所

ハマったというか、音楽っぽくするためにちゃんと単音がでないといけないんだけど、なんか変につながっちゃう!と思ったら、createOscillator().start()createOscillator().stop()で、再生と停止で、音を区切らないとダメだったという。てっきりstart()したら、あとは周波数変えれば良きにはからってくれるかと思ってた。

そして、stop()すると再度createOscillator()インスタンスを再生成する必要がある。ここもハマりポイントだった…。

javascript
var AudioContext = window.AudioContext || window.webkitAudioContext,
ctx = new AudioContext();
var oscillator = ctx.createOscillator();
var gainNode = ctx.createGain();

var score = [440, 550, 660, 770, 880];
function sound(score) {
  var count = 0;
  var flag = false;

  return function() {

    if (flag == true) {
      oscillator.stop();
    }

    // ここで再生成する
    oscillator = ctx.createOscillator();
    oscillator.connect(gainNode);
    gainNode.connect(ctx.destination);

    oscillator.frequency.value = score[count];
    oscillator.type = 'sine';
    oscillator.detune.value = 0;
    gainNode.gain.value = 0.05;

    oscillator.start();

    count += 1;

    if (count <= score.length) {
      flag = true;
      setTimeout(soundFunc, 250);
    } else {
      oscillator.stop();
    }
  }
}

var soundFunc = sound(score);
soundFunc();

参考サイト

今回コードサウンドを作るのに、下記サイトに大変お世話になりました。ありがとうございます。

39
40
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
39
40