Web Audio APIを使ってブラウザからクリスマスソングを鳴らそう

#Web Audio APIを使ってクリスマスソングを鳴らそう

##はじめに
この記事は[リンク情報システム](https://www.lis.co.jp/)の2018年アドベントカレンダーのリレー記事です。
engineer.hanzomon のグループメンバによってリレーされます。
（リンク情報システムのFacebookは[こちら](https://www.facebook.com/lis.co.jp/)から）

私がこの題材を選んだ理由ですが、趣味でDTMなど楽しんでおり、音に関するプログラムならば興味を持って調べられるのではないかと考えたからです。私はプログラマーではないので、技術要素は少ないのですが、どうぞよろしくお願い致します。

なお、本日はクリスマス・イブということでクリスマスソングを題材にしてみました。

##WebAudioAPIとは

W3Cで、2018年9月18日に仕様が発表されていますが、[g200kg Music Software](https://www.g200kg.com/)というサイトの著者の方の和訳から一部引用させて頂きます・・・

> 近年のデスクトップ・オーディオ制作アプリケーションに見られるミキシング、プロセシング、フィルタリング処理に加え、近年のゲームオーディオエンジンに見られるような機能も持たせる事を目標とします。

Webブラウザでは、Audioを扱うためには、HTML5のAudioタグを使うことなどが考えられますが、それにしても自由な音作りというものではなく、それってつまりは”予め用意された音源”をただ鳴らすことです。

ところが、このWebAudioAPIというものができて以来、Webブラウザで~~簡単に~~シンセサイザーが作れると言うではないですか。Yマハ、Kルグ、R-ランド等楽器メーカーでないとできないと思っていたことが、素人でも出来そうです。元手もかからずシンセが作れるならばやってみた～～いと私の好奇心はカナリそそられました！

##WebAudioAPIで音をだすまでの過程

（１）オーディオコンテキストを作成する
（２）オシレーターなどのソースを作成する
（３）エフェクトノードを作成する　（本記事では割愛します）
（４）到達先を選択する
　　　　　ソース→エフェクト→到達先　という風につなげるものだそうです。

###オーディオコンテキストを作成する
new AudioContext() でオーディオコンテキストというオブジェクトを作ります。

```
var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContext();
```
１行目のところは、クロスブラウザに対応するためのコードだそうです。（古いwebkit/blinkブラウザではプレフィックスが必要らしいです。）

###オシレーターなどのソースを作成する
createOscillator()でオシレーターのオブジェクトを作ります。

```
var audioContext = destination.context;
var oscillator = audioContext.createOscillator();
```
####音符の長さと音程を使い分ける

このままでは、音符の長さと音程を指定できませんので、
以下の例のようにして音符の長さと音程を指定します。

```
var playbackTime = audioContext.currentTime;
var hz = 440;
oscillator.frequency.setValueAtTime(hz,playbackTime);
```
ところで、音を変えるにはhzのところに周波数を代入すればよいのですが、
以下のサイトにDTMerならばなじみのあるMIDIのノートナンバー（番号）と、
音程の一覧表がありました。
[音楽研究所　研究テーマ-&gt;コンピュータ・ミュージック (DTM)](http://www.asahi-net.or.jp/~HB9T-KTD/music/Japan/Research/DTM/freq_map.html)
このサイトを参考に鳴らす音程を周波数に計算しなおしてhzに代入することができました。

###到達先を選択する

標準的な記載方法は以下のようなものだそうです。
（ここは、ちょっと理解不足ですみません）

```
var audioContext = new AudioContext();
gainNode.connect(audioContext.destination);
```

###イベントを設定する
HTML上で何かしら音を鳴らすためのイベントを設定します。
クリックイベントの例です。

```
document.getElementById("hoge").addEventListener("click", function () {
  var destination = analyser;
  var playbackTime = audioContext.currentTime;
　music_on(destination, playbackTime);
}
```
##クリスマスソングをWebブラウザで

こうして、HTML上にイベントを発生させるものを記載して、
クリックすることでクリスマスソングを鳴らせるようにしてみました。
We Wish You a Merry Christmas（著作権フリーの楽曲です）

☆の部分をクリックすると、「We Wish You a Merry Christmas」の曲が流れます。下の緑色のBOXは、オシレータから接続したアナライザーを通して、可視化した波形になります。
今回は、矩形波を使ってのサンプルを作ったので、まるで櫛の歯のような形状をしています。１曲鳴り終わると、波形もただの一本の横棒となります。
クリスマスシーズン等に、紙製のカードを贈ったことはありませんか？まるで、そのクリスマスカードから音がでているかのような感じです。
お好みのメッセージを添えて、メールで送ってあげることもできますね。

![1224.png](https://qiita-image-store.s3.amazonaws.com/0/284547/b986b979-9538-f30c-d095-65d32e88eb27.png)

~~音をお聞かせできないのが残念です・・・（本当にちゃんと作ったんですよ～、参考文献をかなり真似して・・・）~~

↓先輩から、「動画〜動画〜」と催促されたので、これ用のアカウント作って録画しました。

<blockquote class="twitter-tweet" data-lang="en"><p lang="und" dir="ltr"><a href="https://t.co/kDoHhghgmv">pic.twitter.com/kDoHhghgmv</a></p>&mdash; cassetteTape (@cassetteTape3) <a href="https://twitter.com/cassetteTape3/status/1076290981413085184?ref_src=twsrc%5Etfw">December 22, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##参考文献
なお、記事を作成するにあたり、以下の文献からほとんどの情報を得ています。
素晴らしい記事をありがとうございます。
特に、WebAudioAPIでコインの音を作るのサイトのサンプルが初めて画面で音が出せた時の感動はひとしおでした～。（普段Programingしないもので・・・）

[g200kg Music Software](https://www.g200kg.com/)
[Web Audio APIでコインの音を作る](https://qiita.com/mohayonao/items/c506f7ddcaac63694eb9)

##最後に
実際に作ってみて音を鳴らしてみた時の感動は何ものにも代えがたいものでした。趣味の知識を活かして、これからもちょっとした効果音や音楽等、作ってみたいと思いました。