JDKバージョン8アップデート201を使用して、リアルタイムで(または少なくとも可能な限りリアルタイムに近い)オーディオを記録および分析するアプリケーションを実装しています。アプリケーションの一般的な使用例をシミュレートするテストを実行しているときに、数時間連続してオーディオを録音した後、1秒から2秒の間の突然の遅延が発生しました。この時点まで、顕著な遅延はありませんでした。この遅延が発生し始めたのは、この数時間の記録の重要なポイントの後だけでした。
オーディオサンプルの録音をタイミングするためのコードが間違っているかどうかを確認するために、タイミングに関連するすべてのものをコメント化しました。これにより、オーディオサンプルが準備ができるとすぐにフェッチする更新ループが本質的に残りました(注:Kotlinコード)。
while (!isInterrupted) {
val audioData = read(sampleSize, false)
listener.audioFrameCaptured(audioData)
}
これは私の読み取りメソッドです:
fun read(samples: Int, buffered: Boolean = true): AudioData {
//Allocate a byte array in which the read audio samples will be stored.
val bytesToRead = samples * format.frameSize
val data = ByteArray(bytesToRead)
//Calculate the maximum amount of bytes to read during each iteration.
val bufferSize = (line.bufferSize / BUFFER_SIZE_DIVIDEND / format.frameSize).roundToInt() * format.frameSize
val maxBytesPerCycle = if (buffered) bufferSize else bytesToRead
//Read the audio data in one or multiple iterations.
var bytesRead = 0
while (bytesRead < bytesToRead) {
bytesRead += (line as TargetDataLine).read(data, bytesRead, min(maxBytesPerCycle, bytesToRead - bytesRead))
}
return AudioData(data, format)
}
しかし、私の側からのタイミングがなくても、問題は解決されませんでした。したがって、少し実験を続けて、さまざまなオーディオ形式を使用してアプリケーションを実行すると、非常に混乱する結果になります(リトルエンディアンと44100.0 HzのサンプルレートのPCM署名付き16ビットステレオオーディオ形式を使用します)特に指定がない限り、デフォルトとして):
これらの結果から、この問題が発生する前にオーディオを録音できる時間は、アプリケーションを実行しているマシンと、アプリケーションのバイトレート(フレームサイズとサンプルレート)に依存しているという結論に達しました。オーディオ形式。これはseemsを保持するためです(現時点ではこれを完全に確認することはできません)。2と3で行った変更を組み合わせると、オーディオサンプルを長い(これは26〜27時間の間です)、遅延が表示され始める前に「デフォルト」のオーディオ形式を使用する場合と同様アプリケーションをこれほど長く実行する時間を見つけられなかったので、私の側の時間の制約のため、アプリケーションを停止するまでに約15時間問題なく実行できたことがわかりました。したがって、この仮説はまだ確認または否定されています。
箇条書き13の結果によると、問題はWindowsを使用している場合にのみ発生するようです。したがって、私はthinkそれがmightであることをjavax.sound.sampled APIのプラットフォーム固有の部分のバグであると考えています。
この問題が発生し始めたときに変更する方法を見つけたかもしれませんが、結果には満足できません。この問題がまったく発生し始めるのを回避するために、定期的にラインを閉じて再度開くことができました。ただし、これを行うと、オーディオサンプルをキャプチャできない任意の短い時間が発生します。さらに、Javadocは、閉じた後、一部の行をまったく再び開くことができないと述べています。したがって、これは私の場合には良い解決策ではありません。
理想的には、この問題全体がまったく発生しないはずです。 javax.sound.sampled APIで何ができるのか、完全に欠けているものや制限があるのでしょうか?この問題を完全に取り除くにはどうすればよいですか?
編集:Xtreme Bikerとgiddsの提案により、小さなサンプルアプリケーションを作成しました。この Githubリポジトリ の中にあります。
私は(かなり)Javaオーディオインターフェイスとの)経験を豊富に持っています。適切な解決策に導くのに役立つかもしれないいくつかのポイントを次に示します。