プログラミング言語で FizzBuzz を実装できるのは当たり前じゃないですか。ということで、音楽制作ソフトウェアである Ableton Live で FizzBuzz を実装してみました。
デモ動画
Ableton Live で FizzBuzz が実装できた pic.twitter.com/jOVx4njgDg
— Akinori Tomita (@__tmy) 2017年12月4日
Ableton Live について
Ableton Live は、DAW という音楽を制作するためのジャンルに属するソフトウェアです。
通常の DAW が曲を制作するために作られているのに対し、Ableton Live は名前の通りライブでの使用も想定されて作られているのが特徴です。このため、音楽の演奏を録音・記録された通りに再生するだけではなく、曲の展開をその場でコントロールできるようにセッションビューという画面を備えているのが最大の特徴です。
この特徴のため、Ableton Live は純粋な音楽制作だけでなく、MIDI 信号出力による照明のリアルタイム制御やインスタレーションのシステムの制御といった分野にも使われているそうです。
セッションビューには、即興的な操作をサポートするために、簡単な自動化の機能が備わっています。今回はこれを活用して FizzBuzz の挙動を再現します。
なお、Ableton Live には、MAX/MSP という本物のビジュアルプログラミング環境と連携する Max for Live というオプション機能がありますが、今回は使用しません。なぜならプログラミング環境で FizzBuzz を実装できるのは当たり前だからです。
要件
今更ですがおさらいしておきます。
- 1 から 99 まで数え上げる
- 3 で割り切れる時は「fizz」と数える
- 5 で割り切れる時は「buzz」と数える
- 15 で割り切れる時は「fizz buzz」と数える
オーディオを扱うソフトなので、出力は音声とします。
また、今回は日本語で出力するものとします。
動作環境
Ablenton Live 9 (Suite 推奨)
音ネタの準備
まずは音声が必要です。Mac の場合は say
コマンドを使うと簡単に用意できます。
$ say 1 -o 1.aiff
こんな感じで、1〜9, 10〜90, fizz, buzz, fizzbuzz の音声ファイルを作成しておきます。
プロジェクトの基本設定
1 小節で 1 つカウントすることにします。また、2 桁の数値を発音させるので、2 拍子に設定しておくと打ち込みが見やすくなります。
テンポは何でもいいんですが、say
コマンドが出力する音声のスピード感だと、だいたい BPM=90 くらいが適当なようです。デモ動画では時間短縮のために BPM=180 に設定してありますが、この場合音声ファイルをタイムストレッチして早口に加工する必要があります(今回は説明しません)。
拍子とテンポを設定するとこうなります。
また、前述の通り以下のすべての操作はセッションビューで行います。
1 から 99 までカウントする
初めに、fizzbuzz 抜きで数値を「1」から「99」まで順番にカウントすることを考えます。幸運なことにループ再生機能があるので、1 の桁と 10 の桁をそれぞれ別々のトラックでループ再生させることにします。
全体設定で 2 拍子に設定したので、10 の桁を 1 拍目に再生し、続けて 1 の桁を 2 拍目に再生させれば、一応 2 桁の数値を読み上げているように聞こえるはずです。
1 の桁
「1 の桁」は MIDI トラックにして、「1」,「2」, ...,「9」,「0」の数え上げをループ再生させます。全部で 10 小節でループすることになります。
実際には「0」は発音しないので、最後の 1 小節は無音になります。
トラックビューに Drum Rack デバイスを配置し、パッドに「1」から「9」の音声ファイルを設定します。
そしてセッションビューで、各小節の 2 拍目で「1」から「9」まで順番に再生する MIDI クリップを作れば良いわけです。前述の通り最後の 1 小節は無音になります。
ただ、これだとカウントが 10 に満たない時、すなわち「1」から「9」をカウントする時も 2 拍目に発音し、1 拍目は無音になるため、実際に聞くと少々気持ち悪く感じます。聴感上は 1 拍目に発音した方が自然に聞こえます。
このため、10 未満をカウントする用にもう一つ MIDI クリップを作ります。
セッションビュー上で 2 つのクリップは以下のように配置します。一番上に 10 未満をカウントするためのクリップを置き、その下に 10 以上をカウントするためのクリップを置きます。
こうして作った 2 つのクリップを再生途中で切り替えるために、Follow Action 機能を使います。10 未満用クリップは 10 小節再生したら次のクリップを再生する設定に、10 以上用クリップは 89 小節再生 (合計で 99 小節再生) したら停止する設定にします。
10 の桁
「10 の桁」も MIDI トラックにします。「1 の桁」と同様に、トラックビューに Drum Rack デバイスを配置し、パッドに「10」から「90」の音声ファイルを設定します。
「10 の桁」全体では、以下のシーケンスで再生をすることになります。
- 最初の 9 小節は無音
- 次の 10 小節は毎小節「10」を再生
- 次の 10 小節は毎小節「20」を再生
- (以下「90」まで繰り返し)
「1 の桁」と異なり、一つのクリップではひたすら同じ数字をループ再生させます。例えば「21」,「22」, ... を読み上げている間は毎小節ひたすら「20」を再生させます。よってクリップの長さは 1 小節です。
セッションビューには先頭に無音のクリップを、あとは「10」から「90」のクリップを順に並べます。
これらクリップも Follow Action 機能で連結します。先頭の無音クリップは 9 小節で次のクリップを再生する設定に、中間のクリップは 10 小節で次のクリップを再生する設定に、最後の「90」のクリップは 10 小節で停止する設定にします。
ここまで出来た状態で先頭のシーンを再生開始すると、「1」から「99」まで読み上げてくれるはずです。
Fizz, Buzz, FizzBuzz を再生する
次に、Fizz, Buzz, FizzBuzz をそれぞれ適切なタイミングで再生することを考えます。
まず「Fizz」はカウントが 3 の倍数の時に再生させるのですが、これは単純に長さ 3 小節で 3 小節目に「Fizz」を再生する MIDI クリップを作ってループ再生させれば良いです。
「Fizz」用に新たに MIDI トラックを作成し、カウント用トラックと同様に Drum Rack 内に「Fizz」の音声ファイルを配置します。
MIDI クリップは Follow Action で 99 小節再生したら止まるようにしておきます。
同様にして、「Buzz」は 5 小節目だけ再生するように、「FizzBuzz」は 15 小節目だけ再生するようにします。
不要な音をミュートする
ここまでで必要な音を全て鳴らすことができますが、このままでは複数の音が重なって再生されてしまうので余分な音が鳴らないようミュートする必要があります。
- 「Fizz」か「Buzz」が鳴っている間はカウントをミュート
- 「FizzBuzz」が鳴っている間は「Fizz」「Buzz」をミュート
サイドチェインコンプ
ミュートを実現するために、サイドチェインコンプというエフェクターを利用します。サイドチェインコンプの働きを雑にいうと、別のトラックで鳴っている音量分だけ音を小さくするというものです。
Ableton Live では、Compressor デバイスのオプションでサイドチェインの指定が行えます。
ただしサイドチェインコンプで音量が下がるのは、サイドチェインで音が鳴っている瞬間だけであることに注意が必要です。カウントに適用するサイドチェインの入力を「Fizz」に指定するだけだと、「Fizz」を再生し終わった瞬間に音量が元に戻ってしまいます。なので例えば「12」など「Fizz」より長い音については、後半の「2」の音が残ってしまいます。
これを防ぐために、該当する小節の間ずっとサイドチェインが反応するよう持続音が鳴り続けるトラックを用意し、それをサイドチェインの入力に指定します。かなり富豪的な方法ではありますが。
サイドチェインの入力を作る
「Fizz」「Buzz」「FizzBuzz」の各 MIDI クリップは既に 1 小節丸々持続して発音するパターンになっています。この MIDI クリップが出力する MIDI 信号は直接 Drum Rack に接続されていますが、これを分岐して元々ある Drum Rack と新たに追加する持続音のトラックの両方に分配します。
まず、MIDI クリップと Drum Rack は同じトラックに配置されていますが、これを別のトラックに分離しておきます。そして持続音のトラックを追加します。
持続音トラックには、ソフトウェア音源の Operator を配置します。1
サイドチェインの入力に使うだけなので、音色はなんでも良く、一定の音量で鳴るのが重要なので、エンベロープを以下のように設定します。
パラメーター | 値 |
---|---|
Attack | 0 ms |
Sustain | 0 dB |
Release | 1 ms (最短) |
これで分配元となる MIDI クリップのあるトラックと、分配先となる Drum Rack のあるトラック、Operator のあるトラックの 3 トラックが用意できたので、これらを接続します。1 つの MIDI 信号を複数のトラックに分配するには、トラックの入力/出力セクションで設定します。
| | 分配元トラック
(MIDI クリップを配置) | 分配先トラック
(音源を配置) |
| ---- | ---- | ---- | ---- |
| MIDI From | All Ins | 分配元トラック |
| Monitor | Auto | In |
| MIDI To | No Output | - |
これを Fizz, Buzz, FizzBuzz それぞれ 3 トラック作ります。また、Fizz と Buzz トラックの出力はグループトラックで一つにまとめます。
各トラックの出力セクションは以下のように設定して、マスター出力に音が流れないようにします。
Fizz,Buzz のグループ | Fizz | Buzz | FizzBuzz | |
---|---|---|---|---|
Audio To | Sends Only | Group | Group | Sends Only |
サイドチェインコンプの設定
- 「Fizz」か「Buzz」が鳴っている間はカウントをミュート
を設定します。まずカウントの 1 の桁と 10 の桁のトラックをグループトラックで一つにまとめます。
このトラックのトラックビューに Compressor デバイスを置き、以下のようにパラメーターを設定します。
パラメーター | 値 |
---|---|
Sidechain | ON |
Audio From | Fizz,Buzz のミュート用トラック (グループトラック) |
Ratio | inf : 1 |
Attack | 0.01 ms |
Release | 1.00 ms |
Thresh | -inf dB |
Knee | 0.0 dB |
これでミュート用トラックからオーディオ信号が来ている間、音量が最低に抑えられます。が、音量が完全にゼロになるわけではなく、微かに聞こえてしまいます。
微かに聞こえる音を完全に削るため、Gate デバイスを利用します。Gate デバイスは、一定以下の音量のオーディオ信号をカットするオーディオフィルターです。普通はノイズのカットなどの用途で使用します。
Compressor デバイスの後ろに Gate デバイスを置き、以下のようにパラメーターを設定します。
パラメーター | 値 |
---|---|
Threshold | 実際に音を聞いて余計な音だけ消えるポイントを探す |
Return | 0.00 dB |
Lookahead | 0 ms |
Attack | 0.02ms (最短) |
Floor | -inf dB |
- 「FizzBuzz」が鳴っている間は「Fizz」「Buzz」をミュート
も同様に「Fizz」「Buzz」のグループトラックを作り、
作成したトラックのトラックビューに Compressor と Gate を配置します。サイドチェインの Audio From パラメーターには FizzBuzz のミュート用トラックを指定します。
これで完成です!
トラック全体のルーティング
このプロジェクト内のルーティングを図示すると、以下のようになります。
プロジェクトファイルダウンロード
-
Ableton Live Standard 版には付属していないので、代わりに何か無料ので良いのでソフトウェアシンセを使ってください。 ↩