エレクトロニカっぽい曲を自動生成&展開し続けるリズムマシンのWebアプリ試作 #javascript #webaudioapi #React
— Kurene (@_kurene) 2022年8月21日
Electronica Machine v0.1https://t.co/HiqdWvGV7d pic.twitter.com/zjsJosajte
当初は単純なドラムマシンを作っていましたが、いろいろ触っているうちに自動作曲と人による入力制御が共存するような自動演奏/作曲支援アプリの方が面白いと感じたため今回のようなアプリになりました。
音楽系Webアプリ開発の参考になるように、工夫した点や参考文献を残したいと思います。
WebアプリのURL
Electronica Machine v0.1- wizard-notes.com
特徴
- リアルタイム実行中もノート入力・BPMを変更可能
- ユーザが素早くリズムを入力できるボタン
- 4つ打ちなら"4-Down"、8ビード裏拍なら"8-Up"ボタンを押せば一発で指定のリズムを入力できます
- 音楽的に調和するようにノートを自動生成する機能
- 自動生成機能をリアルタイムに繰り返すことでモチーフを自動展開しながら再生する自動再生機能
ドラムマシンとしてみると、2の機能はソフトウェアドラムマシンとしては便利な機能であることに気づきました。
ただし、現状ではボタンを並べているためスペースが広くなりすぎています。そのため、UIはコントロールノブを採用するなど改善方法があると思います
上記の特徴により、人と計算機(AI)が協調することで素早く新しいアイディアを積み立てられる音楽創作が可能となっています。
WebAudioAPI について
基本的にはWeb上の WebAudioAPI の記事を参考にして作成しました。
ドラムマシンは基本的にはサンプラーなので短い音源ファイルの再生に適したAudioBufferSourceNode
を利用しています。今回はエフェクトを利用せず、単に鳴らすだけのプログラムなので音声信号処理として難しいところはありません。
BaseAudioContext.createBufferSource() - Web API | MDN
ただし、近年のWeb Audio APIの注意点としてボタンクリック等のユーザー操作でAudio Contextを生成したり再生を実行する必要があります。
iOSでもAudio Contextの取り扱いにはくせがあり、下記記事のパターン2-2のように Audio Context 生成時に無音を鳴らすことで自動再生等を実現しています。
ドラムマシンの作成について
リアルタイムのドラムマシン/シーケンサの実装で難しいのは発音タイミングの制御です。
単純に考えるとsetTimeout
やsetInterval
で定期実行で良さそうですが、リアルタイムの音楽Webアプリではそう上手くいきません。
今回の実装では上の画像のようにsetTimeout
でリズムマシンの解像度よりも短い時間間隔でsetTimeout
を仕掛けて置き、各ノートの発音を制御しています。
詳しくは A tale of two clocks を読んでみてください。
自動作曲(自動生成・自動展開)について
楽曲構造・リズム
作曲において重要なのは周期構造と時間経過による展開です。今回は特に後者を意識して設計実装しました。
ミニマルミュージックとして考えると、時間経過で少しずつメロディやリズムが変化すると仮定できます。
そこで、リズムマシン上で1小節ごとに各トラック・各ノートを一定確率でOn/Offする実装としました。
ただし、一様乱数でOn/Offするだけだと音楽的ではないので、以下のルールに基づいてOn/Offを制御しています。
小節番号 % 4
の値によって変化の大きさが変わる- 4の倍数の小節が終わるとメロディやリズムが大きく変化する
- ある確率で特定の列・行がすべて消える
- 特定の音高やタイミングを除去することで和声的なまとまりやグルーブが生まれる
音高・スケール・コード
今回は試作と割り切り、音高・スケール・コードは適当に与えています。
ただし、調性をC/Amと仮定し、ベースや細かいリズムを担当する音域は和声的に調和しやすいようにAとCの音高のみとしています。