WebAudioの基礎まとめ。(NodeSchoolのWeb Audio Schoolをやってみたときの備忘録、レッスン00〜02まで)

WebAudio初心者です。

[NodeSchool](https://nodeschool.io/)にWebAudioのレッスンがあったのでやってみました。
英語ですが、なかなか分りやすい。

そのときのメモです。

#はじめ方

ターミナルで、
`$ npm install -g web-audio-school`
と打ち、workshopperをインストールしましょう。

そして、
`$ web-audio-school`
とすると、勝手にブラウザでレッスン画面が立ち上がります。

ちなみにレッスン画面はこんな感じ。

![WebAudio.png](https://qiita-image-store.s3.amazonaws.com/0/99740/8d51110e-dea4-c542-a1b8-2d259cf12161.png)

左上に問題とヒント、右上にコードを書いていくとこ、
左下は正解の音が聴ける、右下は自分が書いたコードによる音が聴けます。

#レッスン0：オシレーターで音を鳴らし、波形の種類を設定する。（00. Browser make sound!）

まずはWebAudioAPIを使うには、AudioContext()を生成します。

```js
var audioContext = new AudioContext()
```

そして、WebAudioAPIを使って音を生成していくには、下図のようにいろんなNodeをつなげていくイメージです。

![image](https://qiita-image-store.s3.amazonaws.com/0/99740/c4d17b6a-2b0b-f7dc-3d2f-11a624c7f5e8.png)

※画像はレッスンからの引用

次に、オシレーター(音の元となる波形を作り出すもの)を生成してみます。

下記なようなオシレーターノードを作り、destinationに繋いで(connectして)いきます。

```js
var oscillator = audioContext.createOscillator()
oscillator.connect(audioContext.destination)

oscillator.start(audioContext.currentTime)
oscillator.stop(audioContext.currentTime + 2) //2秒で止まるよ
```

レッスン0の問題は波形の種類を変えてみましょう、というもの。
波形は下記4種類あり、
'sine', 'triangle', 'sawtooth', and 'square'
その中でデフォルトとなっているのは`sine`です。

①sine　...　サイン波
②triangle ... 三角波
③swatooth ... 鋸歯(きょし)状波
④square ... 矩形波

図でいうと、
①sine　...　サイン波
![image](https://qiita-image-store.s3.amazonaws.com/0/99740/503688db-0c92-024e-d69f-062bcc8bdd74.png)
※[画像引用先](http://www.wdic.org/w/SCI/%E4%B8%89%E8%A7%92%E6%B3%A2)

②triangle ... 三角波
![image](https://qiita-image-store.s3.amazonaws.com/0/99740/c166b337-bbc3-21f2-75ea-34884c2602c4.png)
※[画像引用先](http://www.wdic.org/w/SCI/%E4%B8%89%E8%A7%92%E6%B3%A2)

③swatooth ... 鋸歯（きょし）状波
![image](https://qiita-image-store.s3.amazonaws.com/0/99740/ff54b465-1e1e-7f6d-7aad-31ef2ceeda58.png)
※[画像引用先](http://www.wdic.org/w/SCI/%E9%8B%B8%E6%AD%AF%E6%B3%A2)

④square ... 矩形波
![image](https://qiita-image-store.s3.amazonaws.com/0/99740/0733f82d-2581-231c-1557-a9d8b16cccae.png)
※[画像引用先](http://www.wdic.org/w/SCI/%E7%9F%A9%E5%BD%A2%E6%B3%A2)

これらの波形の種類を指定するには、下記のように書きます。

```js
oscillator.type = 'square'
```

#レッスン1：オシレーターの周波数を設定してみる。（01. Play a pitched sawtooth wave）

オシレーターノードには`frequency`ってプロパティがありますが、下記のようにやるとうまくいきません。

```js
//これはうまくいかないよ
oscillator.frequency = 200
```

下記のように設定しましょう。
```js
oscillator.frequency.value = 880
```

#レッスン2：半音階(02. Chromatic Scale)

(ここらへんから音楽の知識ないときつくなってくる。。。orz)

半音階における周波数は、440Hzの「ラ」を基準(MiddleA)とし、1オクターブ高い「ラ」が880Hzで、1オクターブ低い「ラ」が220Hzといった具合に、1オクターブ上がると周波数が倍になるように計算されているので、すこし複雑なので、
`baseFrequency * Math.pow(2, noteOffset / 12).`って式を使いましょう、という話。

具体的には、
```js
oscillator.frequency.value = 440 * Math.pow(2, 7 / 12) // 659.255...
oscillator.frequency.value = 440 * Math.pow(2, -14 / 12) // 195.998...
```
といった感じ。

`noteOffset`にあたる数字は下記な感じです。（レッスンから丸パクり）

```
                         -3  -1   1       4   6       9   11
                       -4  -2   0   2   3   5   7   8   10  12
  .___________________________________________________________________________.
  :  | |  |  | | | |  |  | | | | | |  |  | | | |  |  | | | | | |  |  | | | |  :
  :  | |  |  | | | |  |  | | | | | |  |  | | | |  |  | | | | | |  |  | | | |  :
  :  | |  |  | | | |  |  | | | | | |  |  | | | |  |  | | | | | |  |  | | | |  :
<-:  |_|  |  |_| |_|  |  |_| |_| |_|  |  |_| |_|  |  |_| |_| |_|  |  |_| |_|  :->
  :   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   :
  : A | B | C | D | E | F | G | A | B | C | D | E | F | G | A | B | C | D | E :
  :___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___: 
    ^                           ^           ^               ^           ^
  220 Hz                      440 Hz      523.25 Hz       880 Hz     1174.65 Hz
(-1 Octave)                 (middle A)                 (+1 Octave)
```

あるいはdetunesを使うともっと簡単に表現できます。
detunesは、440Hzの「ラ」を基準(MiddleA)=100として、100ごとに1音階上がっていくイメージです。
なので、「ラ#」なら200、「シ」なら300、「ド」なら400、、、といった感じです。

下記のように設定します。

```js
oscillator.detune.value = 700 // noteOffset * 100
```

#レッスン3:(03. Play a short sequence of notes)
Comming Soon...