5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

KDDIテクノロジーAdvent Calendar 2023

Day 6

(小ネタ)Tone.jsでタイトなリズムを刻む

Last updated at Posted at 2023-12-05

Tone.js は、Web Audio API を簡単に扱うためのライブラリです。

UIに関する機能は持たずに完全に音を出すことに特化しており、サンプルプレイバックや簡単なシンセサイザーも扱えるので、Webアプリに効果音をつけるだけでなく、これ1つで複数の楽器を使ったアンサンブル音源を構成することも可能です。

また、BPMでテンポ指定可能なスケジューラーも用意されているので、シーケンサー的なものも簡単に作れます。

今回は、Tone.jsのスケジューラーのちょっとした小ネタを紹介したいと思います。(ホント小ネタですいません)

リズムがバタつく!?(→正しくコードが書けてないだけ)

下記のようなコードを書いたところリズムがめちゃくちゃバタつきました。

.js
const sampler = new Tone.Sampler({...}); // ← wavデータなどを読み込んでサンプラーを作成。詳細は割愛。

Tone.Transport.scheduleRepeat((time) => {
  sampler.triggerAttackRelease("C1","1n");
},"16n");

(デモ)バタついている様子

上記コードでは、コールバックが一定のインターバルで正確に呼び出されないと、正確なリズムを刻むことはできませんが、上記コードを書いた時の私は「コールバックは正確なインターバルで呼び出されるだろう。」という勝手な幻想を抱いていたようです。

実際には、コールバックはタイマー割り込みのように一定のインターバルで正確に呼び出されるわけではない! ということのようです。

そういえば、そうでした。

どうすれば正確になる?

コールバックのタイミングは正確ではありませんので、コールバックから即時再生するような音源呼び出しをするのではなく、「音を鳴らすタイミングを予約する」 機能を使って、近い未来の時間へ再生を予約する必要があるようです。

Tone.js では、xxx.triggerAttackRelease() の第3パラメータに(今より未来の)時刻を設定すれば、その時に音を鳴らしてくれます。この機能を使えば解決です!

そして、実は Tone.Transport.scheduleRepeat()に設定したコールバック関数のパラメータとして、次のTick時刻が渡されますので、この時刻をxxx.triggerAttackRelease() の第3パラメータに設定すれば良いだけです。

というわけで、下記のように修正してみました。

.js
const sampler = new Tone.Sampler({...}); // ← wavデータなどを読み込んでサンプラーを作成。詳細は割愛。

Tone.Transport.scheduleRepeat((time) => {
  sampler.triggerAttackRelease("C1","1n",time);
},"16n");

(デモ)バタつきが治った様子

簡単でしたね!

まとめ

Tone.js でタイトなリズムを刻むには、xxx.triggerAttackRelease() の第3パラメータをちゃんと設定しましょう。というお話でした。

参考情報

(tone.jsの Transport もおそらく内部で利用しているであろう)setIntervalrequestAnimationFrame などを使ったスケジューラが一定のインターバルで発火されない状況や、そうした状況を前提として AudioContext.currentTime などを用いた正確なリズムを刻む方法については @toyoshim さんが 丁寧に解説してくれていますので、ぜひ参考にしてください。

例えば、Web Audio と Web MIDI を同期させたい、といったユースケースを実現しようとすると必須の内容が解説されています。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?