Ich bin mir nicht sicher, ob ich die genauen Einschränkungen für die Implementierung einer Lösung verstehe, aber es scheint, als wäre die sauberste Methode, die Audiodaten beim ersten Durchspielen der Datei in einem Puffer zu speichern. Wenn es weitere Iterationen (ganz oder teilweise) gibt, die vom Benutzer gewünscht werden, überschreiben Sie einfach die Daten, die Sie zurückgespeichert haben, so oft wie gewünscht in die SourceDataLine.
Hier ist ein link zu einem Beispiel-Sound-Datei-Player (PCM), der Code hat, der sehr einfach zu ändern (oder nur von lernen) sein sollte. Ich habe auch ein paar (ungeprüften) Code gehackt, der nur die Logik zeigt, die ich oben beschrieben habe: (Sie wollen wahrscheinlich auch das, was ich unten habe, ändern, um den Regeln zu entsprechen, die nur Stücke von Daten mit einer Größe multiplizieren der Rahmengröße.)
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;
}
}
}
Hoffnung, die hilft!
I habe ein paar Fragen - wie "anhefte" ich die Schleife an meine bestehende DataLine, die ich verwende? Was macht man mit dem Clip? - Wie sende ich das an eine SourceDataLine? – Tim
Es wird automatisch an Ihre aktuelle aktive DataLine angehängt, Clip ist wie eine andere Player-Instanz, Sie können starten oder stoppen, wann immer Sie wollen.Sie können abfragen, um zu sehen, wie viele von ihnen gleichzeitig gespielt werden können, bei Bedarf können Sie Definieren Sie eine Warteschlange. Aber ich empfehle nicht, sich selbst zu mischen. –
Ich werde es ausprobieren, aber nicht sicher, ob es mit der Dataline funktioniert, so wie mein Code existiert. Vielen Dank – Tim