2009-03-21 2 views
1

Возможно ли создать временный файл, содержащий «цикл» wav-файла?воспроизведение wav-файла в java - как мне продлить или объединить звук?

Или можно управлять потоком, отправленным в устройство чтения/записи потока?

В принципе, я хочу воспроизвести некоторый wav-файл в течение определенного периода времени, и если это время больше, чем время, которое предоставляет wav-файл, я хочу, чтобы цикл.

ответ

4
 AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); 
    Clip clip = AudioSystem.getClip(); 
    clip.loop((int)(Math.ceil(timeRequested/audioIn.getFrameLength()))); 
+0

I есть несколько вопросов - как мне «привязать» цикл к моей существующей DataLine, которую я использую? Что делать с клипом? - как отправить это в SourceDataLine? – Tim

+0

Он будет автоматически присоединен к вашей текущей активной DataLine, клип будет похож на экземпляр другого игрока, вы можете начать или остановить его всякий раз, когда захотите. Вы можете запросить кепки, чтобы увидеть, сколько из них может быть воспроизведено одновременно. При необходимости вы можете определить очередь. Но я не рекомендую смешивать себя. –

+0

Я попробую, но не уверен, что он будет работать с dataline, как мой код существует. благодаря – Tim

0

Я не уверен, что я понимаю точные ограничения, которые у вас есть для реализации решения, но кажется, что самый чистый способ сделать это - сохранить аудиоданные в буфере при первом воспроизведении файла. Затем, если для пользователя требуется больше итераций (полных или частичных), просто перепишите данные, которые вы кэшировали обратно в SourceDataLine, необходимое количество раз.

link Образец звукового файла (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; 
     } 
    } 
} 

Надеюсь, что это поможет!

+0

, что это возможно, но это не совсем то, что я ищу - данные передаются асинхронно игроку и вызывающий поток не имеет ни малейшего представления о том, как долго файл/звук. – Tim

+0

Не могли бы вы дать немного больше информации о специфике ситуации? Есть несколько вещей, которые не указаны (например, кто знает длину файла/звука и как долго он должен воспроизводиться? Если это игрок, то игрок может выполнить метод кеширования, описанный выше.) –

0

Я думаю, что я буду использовать кадры в секунду и оцифровать информацию в потоке аудио входа, чтобы понять это. Другая полезная информация заключается в методе getMicrosecondPosition() объекта SourceDataLine, чтобы определить время/продолжительность, которые были сыграны до сих пор.

это наряду с методами маркировки и сброса в потоке входного аудиосигнала, вероятно, позаботится обо всем этом.