inglow Blog

Tech Blog
エンジニアブログ

コーディングした鍵盤をシンセサイザーにする

2020.05.19

このエントリーをはてなブックマークに追加

ここ数年で人気が高まっているvue.jsを試しながら
前回コーディングしたピアノで音が出せるようにしてみました。
プログラムの考え方も交えながら紹介していきたいと思います。

前回記事

▼実物コーディングチャレンジ -第2回目-
https://inglow.jp/techblog/challenge-htmlcoding-02/

今回使った技術は下記です。
・HTML5
・CSS3
・javascript
 ・vue.js
 ・web audio api

鍵盤を動的に描画する

前回コーディングをしたときには、鍵盤一つずつを、button要素で作成しました。
が…鍵盤がたくさんあるので、1つのオクターブ(ラ~ソ#の塊)をコピペして、
音域名(low等)を変更していました。正直面倒な作業です。

そこで、まずは鍵盤をvueを使って動的に描画していきたいと思います。
まずは、下記のようにループの入れ子にして、鍵盤の描画の設定をobjectで定義していきます。

1)描画用objectの定義

いくつか同じ繰り返しのものが出てきます。
ポイントは、
・A(ラ)~gSh(ソのシャープ)までは同じ繰り返し
・白鍵と黒鍵はA~gShの間であるところと無いところがある
 →「Sh」がついている音は「bl」クラス、ついていない音は「wh」クラスをつける

以上を踏まえて、まず、keysの中身のベースを作成します。

音を鳴らすときのことを想定して、あらかじめ音の周波数を求めておこうと思います。

(音楽理論的な話なってしまいますが…)
半音の幅は、それぞれ「12√2倍(12回かけたら2になる数字)」となっているので、計算式で表すことができます。
基準のラが「440」と定義しておいて、他の音は計算式でまとめてみましょう。

計算式でまとめてみると、2→3→4→…
となっている部分があります。


半音進むごとに1しているので、音名だけの配列を作り、for文でkeysの中身が生成できるようにしてみます。

これでラ~ソ#までのデータが生成できるようになったので、オクターブ毎のオブジェクトを生成します。
今回は少なかったので、静的に記述しましたが、scaleを生成した処理を応用すれば、ここも動的に生成するようにできます。

2)HTMLでvue.jsによって描画されるようにする

「v-for:」で動的に描画するために鍵盤描画用のobjectを定義します。
「v-bind」で属性に対して動的に値が入れられます。この内容は、処理の中で更新されたらすぐに反映されます。

これでHTMLにたくさん記述をしなくても、キーボードが表示されるようになりました!

鍵盤を押した時に処理が動くようにする

まずは前準備で、鍵盤を押したときに処理がうごくようにしてみましょう。
属性にイベントを設定する
 →buttonに「v-on:mousedown=”keydown” v-on:mouseup=”keyup”」を追記する
 mousedown:マウスで左クリックを開始したら処理をする
 mouseup:マウスで左クリックを話したら処理をする

押したら鳴る / 離すまで鳴りっぱなし

'keydown':function(){ console.log('鍵盤を押したよ') }

離したら止まる

'keyup':function(){ console.log('鍵盤を話したよ') }

鍵盤ごとに音階が割り振られるようにする

ボタンが押されたときにどんな音をだしたらいいのか計算をします。
v-forであらかじめ音程やオクターブの掛け率を属性で定義してあるので、属性を取得して計算をしていきます。

まず、関数の引数(e)でクリックされた対象のobjeceを取得しておきます。
「e.target」でクリックされた要素を取得することができるので、ここから下記の属性を取得していきます。

・v-bind:hz
var hz = e.target.getAttribute('hz');

・v-bind:range
var range = e.target.getAttribute('range');

実際に出力する周波数は下記のように算出できます。
hz × rate

web audio apiで音が再生されるようにする

ここまでくればあともう一息です!
今回はweb audio apiの詳しい説明は省きます。また機会があればブログ記事にしたいと思います。
「AudioContext」クラスで発音します。

このまま実行しても特になにもならないと思います。
また、ウィンドウが描画されたときに実行するようにすると、一瞬だけ音が鳴ってすぐ止まってしまうと思います。
それぞれの処理を、それぞれの動作(mousedown・mouseup)の中に記述していきます。

これで「押したら鳴らす・話したら止める」の処理ができました!!!

余談ですが……
楽器をチューニングする際、室外の演奏では「442Hz」に合わせてチューニングをするときがあります。
基準の周波数が変わるときがあるので、基準の周波数が変更できるようにしてみました!
「442Hz」だと違いがほぼ判らないのですが、「523.2511306011974」を入力すると、「ラ」の鍵盤の音が変わると思います。
試してみてください。

さいごに

ずっと前からブラウザでDTMアプリとかできないかな…と気になっていたので、少し近づいたような気がします!!
MIDIの扱いについては別途勉強が必要ですが、音色が変更できるシンセサイザー等も作ってみたいですね。
音楽理論が意外と数学的なので、プログラムでの計算も考えやすいです。
実装してみたい機能がまだまだあるので、機会があればこのブログでどんどん改造していけたらと思っています。

Related Blog
関連記事

2020.05.23
【PHP入門】演算子の使い方
2020.05.21
CakePHP(3.x)におけるHtmlHelperの使い方
2020.05.14
レスポンシブサイトを作る(実例)
2020.05.09
初学者のためのHTML/CSS
2020.05.08
bakeしよう!その2bake