wav ファイルの「ループ」を含む一時ファイルを作成することはできますか?
または、ストリーム リーダー/ライターに送信されたストリームを操作することは可能ですか?
基本的に、ある期間 wav ファイルを再生したいのですが、その時間が wav ファイルが提供する時間の長さよりも長い場合は、ループしたいと思います。
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
clip.loop((int)(Math.ceil(timeRequested / audioIn.getFrameLength())));
これを理解するために、1秒あたりのフレーム数とオーディオ入力ストリームのフレームサイズ情報を使用すると思います。その他の有用な情報は、SourceDataLineオブジェクトのgetMicrosecondPosition()メソッドにあり、これまでに再生された時間/期間を判別します。
これは、オーディオ入力ストリームのマークおよびリセットメソッドとともに、おそらくすべてを処理します。
ソリューションを実装するための正確な制限を理解しているかどうかはわかりませんが、これを行う最もクリーンな方法は、ファイルを初めて再生するときにオーディオ データをバッファに保存することです。次に、ユーザーが必要とする反復 (完全または部分的) がさらにある場合は、キャッシュしたデータを必要な回数だけ SourceDataLine に書き直します。
サンプルのサウンド ファイル プレーヤー (PCM) へのリンクを次に示します。このコードには、非常に簡単に変更 (または学習) する必要があります。また、上で説明したロジックを示すだけの (注: テストされていない) コードをいくつかハックしました:フレームサイズです。)
public void playSoundFile(SourceDataLine line, InputStream inputStream, AudioFormat format, long length, float times)
{
int index = 0;
int size = length * format.getFrameSize();
int currentSize = 0;
byte[] buffer = new byte[size];
AudioInputStream audioInputStream = new AudioInputStream(inputStream, format, length);
while (index < size)
{
currentSize = audioInputStream.read(buffer, index, size - index);
line.write(buffer, index, currentSize);
index += currentSize;
}
float currentTimes = 1.0;
while (currentTimes < times)
{
float timesLeft = times - currentTimes;
int writeBlockSize = line.available();
index = 0;
if (timesLeft >= 1.0)
{
while (index < size)
{
currentSize = ((size - index) < writeBlockSize) ? size - index : writeBlockSize;
line.write(buffer, index, currentSize);
index += currentSize;
}
currentTimes += 1.0;
}
else
{
int partialSize = (int)(timesLeft * ((float) size) + 0.5f);
while (index < partialSize)
{
currentSize = ((partialSize - index) < writeBlockSize) ? partialSize - index : writeBlockSize;
line.write(buffer, index, currentSize);
index += currentSize;
}
currentTimes += timesLeft;
}
}
}
それが役立つことを願っています!