Как воспроизводить звуки в Java-играх?

Я успешно воспроизвожу звуки в апплетной игре Java (1.5), используя следующий код:

// get an available clip to play it
Clip clip = null;
for (Clip clipTemp : players) {
    if (!clipTemp.isOpen()) {
    clip = clipTemp;
        break;
    }
}
if (clip == null) {
    // no available player found, don't play
    return;
}

clip.open(audioFormat, audioByteData, 0, audioByteData.length);

clip.start();

(Игроки — это список клипов, которые я открываю в начале с целью уменьшить задержку, слушатель линии закрывает линию, когда извлекается событие остановки.)

Проблема, с которой я сталкиваюсь, - это периодические задержки до 1 секунды при воспроизведении звука. Это довольно плохо.

Есть ли способ улучшить это? Стоит ли рассматривать SourceDataLines?


person Pool    schedule 11.02.2010    source источник


Ответы (2)


arrow_upward
2
arrow_downward

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

Прошло некоторое время с тех пор, как я занимался программированием апплетов Java, но я помню, что раньше я предварительно загружал все свои клипы, а затем последующие вызовы воспроизведения не открывали файлы повторно.

Вот код из одного из моих старых проектов

Clip shoot;

private loadShootWav()
{
    AudioInputStream sample;
    sample = AudioSystem.getAudioInputStream(this.getClass().getResource("shoot.wav"));
    shoot = AudioSystem.getClip();
    shoot.open(sample);
}

public void playShootSFX()
{
    shoot.stop();
    shoot.setFramePosition(0);
    shoot.start();
}
person JSmyth    schedule 12.02.2010
comment
Привет - спасибо за ваш ответ. Один и тот же звук может потребоваться воспроизвести несколько раз. Не могли бы вы предложить какое-то объединение нескольких клипов для каждого звукового эффекта заранее? - person Pool; 15.02.2010
comment
Да, я обычно реализую одноэлементный класс SoundManager, который загружает все клипы. Приведенный выше код будет воспроизводить звук несколько раз, но каждый раз сбрасывать клип. Если вы хотите сказать, воспроизведите 5 одинаковых звуков, но микшируйте их с немного разными интервалами, я бы предложил попробовать загрузить 5 клипов, а затем, когда вы вызываете playSFX(), увеличить счетчик, указывающий на то, какой следующий клип будет воспроизводиться. . - person JSmyth; 16.02.2010
comment
@JSmyth Я делаю что-то подобное, но если я открываю несколько AudioInputStream одного и того же звукового файла, я начинаю получать LineUnavailableException. Вы можете взглянуть на мой вопрос? stackoverflow.com/questions/20184650/ - person trusktr; 25.11.2013

arrow_upward
0
arrow_downward

Если я правильно читаю ваш код, вы находите неоткрытый клип и открываете его перед воспроизведением. Быстрее было бы взять открытые клипы и перезапустить их. Возможно, вам придется сначала остановиться и сбросить их позиции, как показано JSmyth в примере playShootSFX().

Я получаю довольно хороший ответ с SourceDataLines. Приятно то, что они запускаются быстрее, чем неоткрытый клип, поскольку они запускаются сразу, а не ждут, пока ВСЕ данные для звука будут загружены в ОЗУ (что происходит каждый раз, когда вы «открываете» клип).

Но да, если у вас есть много маленьких звуков, которые часто воспроизводятся, пул клипов — это то, что вам нужно. Если вы хотите, чтобы они перекрывались или всегда воспроизводились до конца, вам нужно несколько копий. Если нет, то остановитесь, сбросьте на 0 и перезапустите. Но не продолжайте открываться! Если вы делаете это, вы также можете использовать SourceDataLine.

person Phil Freihofner    schedule 20.08.2011
comment
Глядя на ваш связанный пост, кажется, что вы уже решили проблему. Очень хороший! Сама бусы не пробовала, но выглядит интересно. Я также слышал хорошие отзывы о библиотеке TinySound, поддерживающей множественное воспроизведение. В основном, хотя я использовал свой собственный код. - person Phil Freihofner; 25.11.2013
comment
Сладкий. Я должен проверить TinySound. Beads хорош тем, что дает вам машины (как я их называю), к которым вы можете подключать входы и подключать выходы к входам внешней машины. Вы можете фильтровать звук с помощью эффектов и т. д. Самое интересное, что он автоматически обрабатывает строки данных, складывая вместе значения всех ваших одновременных звуков для получения окончательного результата. - person trusktr; 27.11.2013
comment
Круто, я только что проверил TinySound. Это красиво и просто. Простые варианты использования Beads такие же простые, как и TinySound, но Beads позволяет вам усложнить его, если вы хотите (где TinySound не может). Спасибо, что показали мне TinySound! - person trusktr; 27.11.2013