Воспроизведение файла WAV в Java - как расширить или объединить воспроизводимый звук? - PullRequest
1 голос
/ 21 марта 2009

Можно ли создать временный файл, содержащий "цикл" файла WAV?

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

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

Ответы [ 3 ]

4 голосов
/ 27 марта 2009
     AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
     Clip clip = AudioSystem.getClip();
     clip.loop((int)(Math.ceil(timeRequested / audioIn.getFrameLength())));
0 голосов
/ 25 марта 2009

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

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

0 голосов
/ 23 марта 2009

Я не уверен, что понимаю точные ограничения, которые у вас есть для реализации решения, но кажется, что самый простой способ сделать это - сохранить аудиоданные в буфере при первом воспроизведении файла. Затем, если пользователю требуется больше итераций (полных или частичных), просто переписайте данные, которые вы кэшировали, обратно в 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;
        }
    }
}

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

...