WebAudio界隈とWebAudio.tokyo

この記事はIT勉強会/コミュニティ運営 Advent Calendar 2016の15日目です。

WebAudio.tokyoは今年の9月に第1回を迎えたばかりの勉強会です。
今回はどういった思いでWebAudio.tokyoというコミュニティを作り、
今後どのようにWebAudio界隈と関わっていきたいかを書こうと思います。
始めたばかりの勉強会が他のコミュニティとどのように関わり、どういった助けを得ているかといった、
これから勉強会やってみようという人向けの話になります。

どのように始めたか


WebAudio.tokyoはWeb Audio APIのための勉強会です。
Web Audio APIとはブラウザ上で音声の信号処理を可能にするAPIで、
audioタグとは違って音を鳴らすだけでなく、その場で音を生成したり音にエフェクトをかけたりといったことが可能です。
そのためWeb Audio APIの他にもWeb MIDI API, WebRTCなども組み合わせてシンセやエフェクターを作ろうといった活動は活発で、
Web Music Developers JPという大きなコミュニティもすでに存在します。

そんな中で、Web Audio APIに特化して、Web Audio APIの新たな使い道を探っていきたいという気持ちで始めたのが、
このWebAudio.tokyoです。

WebAudio.tokyoとWeb Music Developers JP


WebAudio.tokyoのできる前、今年の7月にWeb Music ハッカソン #5に参加しました。
これは先のWeb Music Developers JPが主催されたイベントで、Webと音楽をテーマにしたハッカソンです。
私自身、今年の春に初めてWeb Audio APIを触り、これがWeb Audio APIに関係するコミュニティへの初めての参加でした。
当日は実際にmidiキーボードなどの機材も用意され、Web Audio APIだけでなくその他のブラウザ技術も取り入れられた作品はどれも大変刺激的でした。
このハッカソンに参加したことで、音声の信号処理や波形のビジュアライズ、音楽をする上での時間の管理などWeb Audio APIの奥深さに触れ、Web Audio APIに特化したコミュニティを作ろうと思った大きなきっかけとなりました。

そして、WebAudio.tokyoの第1回から2ヶ月後、Web Music Developers JPの代表である河合良哉さんが主催されたWeb Audio API 初心者向けハンズオンにメンターとして参加させていただきました。
ここでもWeb Music Developers JPの方々にお世話になった他、WebAudio.tokyoの#1, #2共にLTをして頂いたり、
Web Audio API 初心者向けハンズオンからも次回#3にて初心者向けLTとして出て頂いたりと、技術面、運営面共に大きくお世話になっています。

WebAudio.tokyoとJS勉強会


Web Audio APIもJavaScriptの技術の一つです。
そのため、JSのコミュニティでもWeb Audio APIの話題が上がることがあります。
私もMeguro.esの運営に携わっており、毎回Web Audio APIの話をしていますが、
何回か繰り返して気づいたのがJS勉強会でWeb Audio APIの話をしても内容によってはよくわからない…
といった空気になってしまうということです。
Web Audio API 初心者向けハンズオンでも感じたことですが、
JSは書けても音声信号処理となると音楽、数学、ちょこっと物理あたりの知識も必要になり始め、専門性はかなり高くなります。

そこで、私が外のJS勉強会でWeb Audio APIの話をする際には、できるだけ音楽のことも説明するように心がけています。
たとえJSっぽい話が少なくなってしまっても、音楽の用語の説明に時間を割くこともあります。
幸い、見映え(聴映え?)のいいDEMOができるのがWeb Audio APIの強みでもあるので、
説明した音楽がブラウザ上でできればそれだけでWeb Audio APIすごい! とわかってもらえます。

そして、こうした勉強会でWeb Audio APIに興味を持ってもらえたら、WebAudio.tokyoに来て濃い話に花を咲かせてもらうといった魂胆です。
実際、参加したJS勉強会から参加してもらったり、JS界隈でコミュニティを運営している方にWebAudio.tokyoの運営を助けてもらったりもしています。

ニッチなジャンルだからこその良さ


WebAudio.tokyoでは、このように実際に私が足を運んだイベントから来てもらう人が多いです。
その他にも、Web Audio APIに関するブログを書いている人にtwitterで連絡を取ることも多いです。
JS技術の中でも専門性が高く分野もニッチなので、毎回多くの人が集まるわけではありませんが、懇親会は濃い話で盛り上がります。
まだまだ大きく広げられていないので、見知った顔も多く内輪ネタのような話で盛り上がっている節もありますが、
やはり既にできているコミュニティから顔を出してくださる方々の話は面白いです。
この界隈のコミュニティの数が多くないということもあり、まだ出来たばかりのコミュニティでもWeb Audio APIに強い方と交流できるのはニッチなジャンルの良さなのではないかと思います。

WebAudio.tokyoとこれから


JS勉強会で専門性を薄めて話をしても、やはりWebAudio.tokyoがニッチな分野の濃い話をする場所であるという部分は変えたくないです。
WebAudio.tokyoがWeb Audio APIの新たな使い道を探る場であるためには、少人数でも深い話ができる場でありたいと思っています。
しかし、音楽に興味はあるけれど専門性が高くて手が出せないという層が一定数いるのもまた事実です。
Web Audio API 初心者向けハンズオンのようなイベントには引き続き協力していきたいし、
そういった場を用意できるようにもなりたいと思っています。

そんな中で、WebAudio.tokyo #3では初心者向けLT枠を用意することにしました。
Web Audio API 初心者向けハンズオンの開催から2ヶ月と少し、ここでWeb Audio APIを触り始めた方々が何か出来たものを発表してくださればとても嬉しいです(もちろん、このイベント以外で触り始めた方のご参加もお待ちしております)。

WebAudio.tokyoの始まりの話ということもあり自分の話が多くなってしまって恐縮ですが、
これから勉強会をやってみたい人、始めたばかりの勉強会を運営している人の参考になれば幸いです。

WebAudioの基本機能でエフェクターを作ってみる

この記事はWebAudio Web MIDI API Advent Calendar 2016の10日目です。

今回はWeb Audio API | Codelabの内容を少しだけいじってエフェクターを作ってみたいと思います。
この半年ほどでWeb Audio APIの勉強会やハッカソン・ハンズオンなどに参加してきましたが、「音が鳴って楽しい!」「なんかいろいろできそう!」といったポジティブな意見を聞く反面、初心者には少し敷居が高い部分もあると感じています。
これは

  • 音楽の知識諸々が必要(楽器のことから音の波形とか信号制御といったことまで)
  • ノードグラフがピンとこないと何を実装すればいいか見えてこない

の2つが大きな原因であると思っています。
そこで、先のCodelabで作れるものから少しだけいじって、ノードグラフに何を足せば、音にどのような変化が出るのかといったことを実感してみます。

今回作るもの


エフェクターと一言で言っても本当にいろいろ種類があるので、今回は

  • Peak Filter
  • Flanger

の2種類のみを作っていきます。
この2つを選んだ理由としては、

  • Peak FilterはBiquadFilterだけで簡単に実装できるのに、DJっぽいエフェクトができて楽しい
  • FlangerはCodelabで実装するディレイを改造すれば作れる

からです。
また、今回の内容は先日のMeguro.esなる勉強会で発表したものの使い回しです。
その時はPeak Filterとは、Flangerとはなんぞや、という部分に焦点を当てたので、本記事ではその実装部分を見ていきます。
そのため、この2つのエフェクターが何であるかについては、当日の資料を参考にしていただきたいです。

Peak Filter


Peak FilterはWeb Audio APIのBiquadFilterを使うだけで実装できます。
BiquadFilterは特定の周波数より大きい(小さい)部分をカットする、特定の周波数より大きい(小さい)部分を増幅させる、などの全8種類の機能がありますが、その中のピーキングフィルターを使います。
これは特定の周波数の部分を増幅させるフィルターです。
音源に対してフィルターのノードを1つつけるだけなので非常に単純です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body>
<input type="range" min="100" max="10000" id="freq" size="10" value="5000" oninput="ChangeFrequency()"/>
</body>
<script>
var audioctx = new AudioContext();
var filter = audioctx.createBiquadFilter();
var src = audioctx.createBufferSource();
var buffer = null;
LoadSample(audioctx, "path/to/your/audio/file");
src.buffer = buffer;
src.connect(filter);
filter.connect(audioctx.destination);
src.start(0);
function ChangeFrequency() {
filter.gain.value = 50.0;
filter.frequency.value = parseFloat(document.getElementById("freq").value);
}
document.onmouseup = function (event) {
filter.gain.value = 0;
}
</script>

LoadSampleは音楽ファイルを読み込むための関数ですが、この実装はCodelabを参照してください。
スライダーの部分は昨日紹介されていたWebAudio-Controlsを使うとそれっぽくなります。

Flanger


Flangerの実装はCodelabで作ったディレイを適用するオシレータを揺らしてみるの合わせ技となります。
再生部分やパラメーターの設定部分はそのまま使いまわせます。
以下のコードも重複している部分が多々ありますが、ノードグラフの部分は載せたかったのでご容赦ください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<body>
<table>
<tr><td>Bypass :</td><td><input id="bypass" type="checkbox"/></td></tr>
<tr><td>LFO Freq : </td><td><input type="text" size="10" id="lfofreq" value="5"/></td></tr>
<tr><td>Depth : </td><td><input type="text" size="10" id="depth" value="0.5"/></td></tr>
<tr><td>Time : </td><td><input type="text" size="8" id="time" value="0.005"/></td></tr>
<tr><td>Feedback : </td><td><input type="text" size="8" id="feedback" value="0.4"/></td></tr>
<tr><td>Mix : </td><td><input type="text" size="8" id="mix" value="0.4"/></td></tr>
</table>
</body>
<script>
var audioctx = new AudioContext();
var buffer = null;
var src = audioctx.createBufferSource();
var input = audioctx.createGain();
var delay = audioctx.createDelay();
var wetgain = audioctx.createGain();
var drygain = audioctx.createGain();
var feedback = audioctx.createGain();
var lfo = audioctx.createOscillator();
var depth = audioctx.createGain();
input.connect(delay);
input.connect(drygain);
delay.connect(wetgain);
delay.connect(feedback);
feedback.connect(delay);
wetgain.connect(filter);
drygain.connect(filter);
lfo.connect(depth);
depth.connect(delay.delayTime);
src.buffer = buffer;
src.connect(input);
src.start(0);
lfo.start(0);
document.onkeydown = function (event) {
if (event.keyCode==70) {
lfo.frequency.value = parseFloat(document.getElementById("lfofreq").value);
depthRate = parseFloat(document.getElementById("depth").value);
wetgain.gain.value = mix;
drygain.gain.value = 1 - mix;
depth.gain.value = delay.delayTime.value * depthRate;
}
}
document.onkeyup = function (event) {
if (event.keyCode==70) {
wetgain.gain.value = 0;
drygain.gain.value = 1;
depth.gain.value = 0;
}
}
</script>

flangerなのでfのキーを押したらエフェクトがかかるようになっています。
オシレータを揺らしてみるではオシレーターのfrequencydepthを繋いでいたのですが、flangerではディレイノードのdelayTimeに繋いでいるのがポイントです。
ちなみに綺麗にパラメーターをセットするとジェット機のような音が音源に重なって聞こえるそうですが、どうやれば綺麗にかかるのかは勉強不足でわかりませんでした…

さいごに


Web Audioちょっと触ったことがある人なら理解に苦しむところはないと思います。
音楽の知識がないと何やってるのかわかりにくいかもしれませんが、僕もコードを書きながら音がこんな風に変わるんだろうなぁと明確にわかっているわけではありません。
今回も実装よりもパラメーターの設定の方が時間使ったんじゃないかと思うくらいです。
簡単なものから書いてみて、実際にどんな効果がかかるのかを聞いてみて、Web Audioに興味を持ってもらえたらと思います。

WebAudio.tokyo 公式ページ開設

WebAudio.tokyoの公式ページを開設しました

WebAudio.tokyoはWeb Audio APIのための勉強会です。
Web Audio APIでの音楽作成から新しい使い道の研究まで、
作ったものやできることの共有ができる場を求めて始まりました。

9月6日に第1回を迎えたばかりのコミュニティですが、
Web Audio界隈の活性化の一助になれたらと思います。