Как воспроизводить звуки в 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)


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

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

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

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

person Phil Freihofner    schedule 20.08.2011
comment
У меня проблемы. Я думаю, что мне, возможно, придется сделать то, что вы упомянули здесь. Можете ли вы опубликовать пример? Вот мой вопрос: stackoverflow.com/questions/ 20184650/ - person trusktr; 25.11.2013
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