質問

Java はリアルタイム オーディオ処理に C/C++ の代替として適していますか?

ディレイライン(48khzで30秒)、フィルタリング(512ポイントFIR​​?)、および各トラックで同時に発生するその他のDSPタイプの操作を備えた、最大100トラックのオーディオを持つアプリを検討しています。

演算は変換されて浮動小数点で実行されます。

システムはおそらくクアッドコア 3GHz と 4GB RAM で、Ubuntu を実行します。

Java が以前よりもはるかに高速になり、C / C++ に近づき、リアルタイム拡張機能も追加されたという記事を見たことがあります。これは現実ですか?一部の仕様で指定されている C の %50 ~ %100 のパフォーマンスを達成するには、ハードコアなコーディングとチューニングが必要ですか?

これが可能かどうか、そして問題点に注意してください。

役に立ちましたか?

解決

オーディオ アプリケーションの場合、ほとんどの時間が費やされるのは、コードの非常に小さな部分だけであることがよくあります。

Java では、いつでも JNI (Java ネイティブ インターフェイス) を使用して、計算量の多いコードを C モジュール (または、本当に能力が必要な場合は SSE を使用したアセンブリ) に移動できます。したがって、Java を使用してコードを動作させることをお勧めします。パフォーマンス目標を達成できないことが判明した場合は、JNI を使用してください。

いずれにせよ、コードの 90% はおそらくグルー コードとアプリケーション関連のものになるでしょう。ただし、そのようにするとクロスプラットフォーム機能の一部が失われることに注意してください。JNI を使用できる場合は、ネイティブ コードのパフォーマンスに対する扉が常に開かれたままになります。

他のヒント

Java は多くのオーディオ アプリケーションに適しています。他の投稿者とは対照的に、私は Java オーディオを扱うのが楽しいと感じています。利用可能な API とリソースを、ほとんど文書化されていない恐ろしい考えである CoreAudio と比較すれば、あなたもきっと信じられるでしょう。Java オーディオには遅延の問題がいくつかありますが、多くのアプリではこれは無関係であり、コーデックが不足しています。また、時間をかけて優れたオーディオ再生エンジンを作成しようとはせず (ヒント、SourceDataLine を決して閉じず、代わりにゼロを書き込む)、結果的に問題の原因を Java のせいにする人もたくさんいます。API の観点から見ると、Java オーディオは非常に単純で使いやすく、非常に多くのガイダンスがあります。 jsresources.org.

もちろん?

重要な質問は次のとおりです (言語とは関係なく、これはキュー理論からのものです)。

  • 処理する必要がある最大スループットはどれくらいですか (100 x 48kHz を指定しました。それはモノラルですか、ステレオですか。その周波数で何ビットに相当しますか?)
  • あなたの Java ルーチンは平均してこの速度に追いつくことができますか?
  • 最大許容遅延はどれくらいですか?

プログラムが平均のスループットに追いつくことができ、待ち時間に対して十分な余裕がある場合は、入力と出力にキューを使用できるはずです。タイミングにとって重要なプログラムの部分は、データを入力キューに入れ、出力キューから取り出して、DAC/スピーカーなどに送信します。

遅延線の計算負荷は低く、必要なのは十分なメモリ (+ メモリ帯域幅) だけです。実際には、おそらく入力/出力キューを使用するだけでよいでしょう。すぐに入力キューへのデータの投入を開始し、30 秒後に出力キューからのデータの取り出しを開始します。そこにない場合は、プログラムが遅すぎます...)。

FIR はより高価であり、他の醜い厄介な操作を念頭に置いていない限り、それがおそらくボトルネック (および最適化したいもの) になるでしょう。

レイテンシーが大きな問題になると思います。最新の OS 上の C/C++ ではすでにレイテンシーを維持するのは非常に困難であり、Java は確実に問題をさらに増大させます (ガベージ コレクター)。「リアルタイム」オーディオ処理の一般的な設計では、処理スレッドをリアルタイム スケジューリング (Linux カーネルの SCHED_FIFO、他の OS で同等) で実行し、それらのスレッドがブロックされることはありません。これは、システムコール、malloc、IOなどがないことを意味します...ページングですら問題があるため (ディスクからメモリにページを取得するのに数ミリ秒かかる場合があります)、一部のページをロックして、ページが決してスワップアウトされないようにする必要があります。

これらのことは Java でも実行できるかもしれませんが、Java ではそれが簡単ではなく、より複雑になります。必要に応じて、コアが C で残りの部分 (GUI など) が Java になる混合設計を検討します。

あなたの質問で分からなかったのは、これらの処理されたサンプルを再生する必要があるのか​​、それともそれらを使って何か他のことをしているのか(たとえば、ファイルにエンコードするなど)です。私は、JVM がサンプルをどれだけ速く処理できるかよりも、Java のサウンド エンジンの状態のほうを心配しています。

私は数年前に javax.sound.sampled にかなり熱心に取り組みましたが、あまり感銘を受けませんでした。OpenAL や Mac/iPhone の Core Audio などの同等のフレームワークとは比較になりません (どちらも私は同様のレベルで使用しました)強度)。javax.sound.sampled では、期間が不明な不透明なバッファにサンプルをプッシュする必要があるため、同期はほぼ不可能になります。また、文書化が不十分であり(メモリ内クリップの簡単な例とは対照的に、ラインを介して不定長のオーディオをストリーミングする例を見つけるのは非常に困難です)、実装されていないメソッド(DataLine.getLevel()...)があります。実装されていないことは文書化されていません)、おまけに、Sun は数年前に最後の JavaSound エンジニアを解雇したと思います。

もし私が 持っていた サウンドのミキシングと出力に Java エンジンを使用する場合、少なくともエンジンが現在サポートされており、非常に低レイテンシであることがわかっているので、OpenAL への JOAL バインディングを最初の選択肢として使用しようとすると思います。ただし、長期的には Nils が正しく、最終的には JNI を使用してネイティブ サウンド API を呼び出すことになるのではないかと思います。

はい、Java はオーディオ アプリケーションに最適です。Java を使用し、Asio 経由でオーディオ レイヤーにアクセスでき、Windows プラットフォームではレイテンシーが非常に低くなります (64 サンプルのレイテンシーはほぼゼロです)。これは、ビデオ/映画でリップシンクができることを意味します。Mac では、OS X と「Java をトップ」の組み合わせを「ショートカット」する Asio がないため、レイテンシがさらに高くなりますが、それでも問題ありません。Linux もそうですが、私はもっと無知です。Java と Asio が完全に調和して動作する実践的な (そして世界初の) 例については、soundpimp.com を参照してください。sw mp3 デコーダ (Java から) を含む NRK Radio&tv Android アプリもご覧ください。ほとんどのオーディオ処理は Java で行うことができ、時間がさらに必要な場合はネイティブ レイヤーを使用します。

Jsyn というライブラリを調べてください。

http://www.softsynth.com/jsyn/

1 日かけて最小限の処理を行う単純な Java アプリケーションを作成し、パフォーマンスが適切かどうかを検証してみてはいかがでしょうか。

から http://www.jsresources.org/faq_performance.html#java_slow

永遠の知恵を集めてみましょう。

  • 地球は平らです。

  • そして忘れてはいけないのは、Javaは遅いです。

いくつかのアプリケーションが証明するように(リンクセクションを参照)、Javaはオーディオエディター、マルチトラックレコーディングシステム、MIDI処理ソフトウェアを構築するのに十分です。やってみて!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top