音楽用低遅延リモートコミュニケーションサービス - レイテンシー撲滅委員会
このプロダクトを考えるにあたって、まず一番の敵を知らなければならない。戦う理由は何で、なぜそれが生じていて、どうやってそれを解決するのか。
プロダクト構想はこれ
レイテンシーとの闘い
「レイテンシー」= latency (遅延)とは、使われる場所によって意味が異なることもありますが、このプロダクトの開発で解決しようとしているレイテンシーとは、
インターネット経由で二人の演奏者がアンサンブルしようとしたときに、片方の演奏者が出した音がもう片方の演奏者に届くまでの時間
と考えてください。
たとえば演奏者が隣にいるとこれはゼロ(厳密にはゼロじゃないけど、でもまあ感じない)。で、これがホールとかになると場合によっては数10ミリ(ミリは1,000分の1)秒となることもありますが、プロの演奏者は慣れてるのでなんとか合わせられる。
なぜホールだと数10ミリ秒かかるとかというと...音は1秒に340メートル(気温20℃の大気中)しか進まないからですね!つまり3.4メートルで10ミリ秒、34メートルではなんと100ミリ秒もかかってしまうから。大きなホールだと舞台の端から端まで20メートル近くあるので、60ミリ秒とかかかります。
ただ、これがインターネット経由で、となると、たとえば50ミリ秒でも、50ミリ秒後に相手が反応して、演奏して、それがまた50ミリ秒かかって「返ってくる」ので、片方の演奏者から見ると、もう片方は100ミリ秒遅れて演奏しているように聞こえる。実際100ミリ秒かかると、もうアンサンブルするにはきついのです。例えば♩=120のテンポの曲だと、♩が0.5秒=500ミリ秒だから、100ミリ秒というと16分音符一つ分に匹敵します。それが聞こえてくるのを待って合わせていくと、どんどんテンポが遅れてくることになります。
どこでレイテンシーがかかるのか
「だってインターネットって電気信号でしょ?電気は光と同じで、一秒に30万キロ進むんじゃないの?」
正しい理解です。その通りです。ただ、その電気信号は、まずマイクで拾ったアナログ信号がデジタルに変換され、とても微細な回路の中の何十メートルもの配線を潜り抜け、さらに家から外のネットワークに出て行ってからもあちこちいっぱい回り道して、同じように相手の家の中の機会の中の配線を潜り抜けてからアナログ音声信号に変換されて、スピーカーまたはヘッドフォンから音となって届きます。
そして、ちゃんとデータをもれなく受け渡しするために「バッファリング」という技術が使われています。詳しい説明は省きますが、要は「ため込んで、データがそろってから次に送り出す」ことです。たまるまで待つわけですから、その分遅れていくわけです。
[4/23/2020 図を追加]
主なサービスのレイテンシー
会議サービスのレイテンシーについては、こちらにまとめました。
ZOOMが一番小さい。175ミリ秒。ZOOMが人気があるのは実はこういうところかもしれない。セキュリティはズタボロだけれどw。
ただ速いといっても175ミリ秒だと音楽を一緒に演奏するには遅すぎるのです。往復すると350ミリ秒ですから。
YAMAHAの新プロダクトSyncRoomについて
ものすごーくいいタイミングでYAMAHAから発表になったこれ
もともとはだいぶ前から NETDUETTO というプロダクト名でベータリリースされていたものらしい。それが正式に?YAMAHAから製品orサービスとしてリリースされることが決まったと。
からベータ版をダウンロードできます。
で、早速試してみました。本当のポテンシャルを知りたかったので、
・ユーザーA : Windows 10/Surface Book 2(Core i5) + TASCAM US-20x20 オーディオインターフェース、「ぷらら」に有線接続 (IPv4)
・ユーザーB : Windows 10/自作機 Core i7/ TASCAM US-366、「インターリンク」に有線接続(IPv4)
で、Aのほうはレイテンシー0.7mSecのASIO接続、Bにはレイテンシー1.4mSecのASIO接続としています。これはそこそこ音楽をやってる人の標準的環境といっていいでしょう。で、いつものようにデジタルストレージオシロスコープをAのモニター出力とBのモニター出力に接続し、手をたたいてレイテンシーを測定。
いつものひとマス20mSecのレンジで測ると
なに!? 20mSec以下!
レンジを短くして再度測定
12mSec !マジすか。そりゃすごい!(ひとマス2mSec)
確かに、入力側のマイクにしゃべりながら出力側のヘッドフォンで聞いても、ほんのわずか遅れて聞こえるだけで、ほとんど同時。これならアンサンブルも可能なんじゃないかなとか。
画面はこんな感じ。
ルームをまずユニークな名前で作り、参加する人は同じ名前のルームで「ログイン」する感じ。パスワードも一応付けられるから総当たりではいってこられる危険性はないかな。
なぜレイテンシーが小さいのか
ここはまあ類推にはなりますが、わたしもだてにプログラマー20年やってるわけじゃないので、だいたい合ってると思います。詳しい解説はそのうち書きます。
・peer to peer 通信である
・ネットワークをとことん効率化して使っている
・できるだけ低レイヤでオーディオデバイスにアクセスしている
・データをほとんど圧縮していない
・アプリの中での時間がかかる処理を全部省いている
足りないものはなんだ?
正直なかなかよくできている(ちょっとまだ雑なところもあるけど)し、商用サービス・プロダクトに移行したら本気のフィードバックが入ってくるから、飛躍的に改善されることも多いだろうし、期待したいです。というか、そうなると作る理由がなくなっちゃうかな(苦笑)。
ただ、実際に使う現場の声として、必要になる・なりそうなのは
・動画
・レコーディング
でしょう。やはり音だけでアンサンブルするのはなかなかしんどい。目に見える情報もかなり重要で、音だけ聴きながら合わせているわけではないと。まあフルHDで自然な動画、まではきっと必要なくて、アイコンタクトできるぐらいの品質があればいいのかなと。
レコーディング機能は、きっと商用化したらつく(それもクライアント側、クラウド側両方?)と思われます。
それ以外にも、機能概要で書きだしたようなものはサポートされていないし、今後付加されるとしてもまだ先かなー。ということで、気を取り直して(笑)、引き続き開発可能かどうかを考えていきたい。
YAMAHAのサービスが有償でもいいから機能・APIとして使えるようになって、それに追加する形で機能を拡充できればいいんだけどなー。それこそインターネット上のDAW (Digital Audio Workstation) としてプラットフォーム化できそうな気がするのだけれど。そこまで考えていないかしら。クラウド Protoolsみたいな。
Experimentals ... (実験室だより)
ffmpeg の実験
ffmpegとは
相当歴史も古いオープンソースの動画・音声用エンコーダー・デコーダーです。Linux版をベースとしてWindows、MacOSはもとよりRaspberry Piとかいろんなプラットフォームに移植されている、デファクトといっていいエンコーディングツールです。
もともとの基本機能としては、あるエンコーディング(=圧縮アルゴリズム、MP3とかAACとかFLACとか)で圧縮されたものを再生するとか、もともと圧縮されてないデータ・ファイルを圧縮して別のファイルにする(=サイズが小さくなる)とか、おもにファイルを操作するものでしたが、音声や映像入力から流れてくるデータ(ストリーム)を圧縮してネットワーク上に流す(ストリーミング)機能も付加されています。ここでは、その中でも最もシンプルな、 RTP という方法で、ネットワーク越しのレイテンシーを測ってみました。いろいろ制限があるので、うちのローカルネットワークの中だけで、隣のPCで測定しています。
実験結果
ダメですねー、レイテンシー1秒超える。いくつかエンコードも換えて試したけれど、ほぼ無圧縮(=時間がかからない)はずのpcm_mulawでも1秒前後!遅れる。LAN上なのに!
一応試した送り側コマンドラインとその出力はこちら(自分用メモ)。これはAACですが、結果は一緒です。オシロスコープで測るまでもない。
D:\bin>ffmpeg -f dshow -i audio="Line In (TASCAM US-366)" -ar 44100 -ac 2 -vn -c:a aac -f rtp rtp://224.0.0.255:30005 -sdp_file stream.sdp
ffmpeg version git-2020-04-03-52523b6 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9.3.1 (GCC) 20200328
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 42.102 / 56. 42.102
libavcodec 58. 77.101 / 58. 77.101
libavformat 58. 42.100 / 58. 42.100
libavdevice 58. 9.103 / 58. 9.103
libavfilter 7. 77.101 / 7. 77.101
libswscale 5. 6.101 / 5. 6.101
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, dshow, from 'audio=Line In (TASCAM US-366)':
Duration: N/A, start: 161638.771000, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
Output #0, rtp, to 'rtp://224.0.0.255:30005':
Metadata:
encoder : Lavf58.42.100
Stream #0:0: Audio: aac (LC), 44100 Hz, stereo, fltp, 128 kb/s
Metadata:
encoder : Lavc58.77.101 aac
size= 4192kB time=00:04:23.99 bitrate= 130.1kbits/s speed= 1x
video:0kB audio:4119kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.773871%
再生側はこちら
D:\bin>ffplay -protocol_whitelist "file,udp,rtp" stream.sdp
まだ送り出しと再生とどちらに時間がかかっているかは調べていないですが、ffmpegのコンセプトとして、基本的にリアルタイムを目指していないような気もする。気軽にストリーミングできるのはとてもありがたいのだけれど、ハードウェアもOSもネットワークも使い切っていないような気もする。バッファサイズなどをいじれば、もう少し速くできそうな気もするけれど...。
次のステップ
ということで、SyncRoomを評価しつつ、当初の
・Opus エンコード + WebRTCの可能性の検証
に加え、無圧縮(もしくはロスレス圧縮)の伝送についても、プロトタイプレベルで技術的可能性の検証を続けます。