Определите, когда закрыть звуковую нить в Java - PullRequest
0 голосов
/ 08 мая 2009

Я играю звуковой файл на Java и ищу простой способ определить, когда звуковой файл закончился, чтобы я мог прервать поток. Есть ли простой способ сделать это?

Ответы [ 4 ]

4 голосов
/ 13 сентября 2009

Извините, это немного поздно, но сегодня я столкнулся с проблемой, которая звучит подозрительно знакомой. В некотором игровом коде, я использую javax.sound.sampled.Clip для воспроизведения различных звуков, я обнаружил, что если я не буду явно вызывать line.close (), как только он будет закончен, счетчик собственных потоков в профилировщике будет просто -рокет до тех пор, пока я не получу ошибку OutOfMemory.

// this just opens a line to play the sample
Clip clip = AudioSystem.getClip();
clip.open( audioFormat, sounddata, 0, sounddata.length);
clip.start();

// at this point, there is a native thread created 'behind the scenes'
// unless I added this, it never goes away:
clip.addLineListener( new LineListener() {
  public void update(LineEvent evt) {
    if (evt.getType() == LineEvent.Type.STOP) {
      evt.getLine().close();
    }
  }
});

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

Надеюсь, это кому-нибудь пригодится.

1 голос
/ 05 июля 2009

Комментарии

Вы воспроизводите звук синхронно или асинхронно.

Если вы воспроизводите его синхронно (блокируя вызывающую нить), вы знаете, когда закончится воспроизведение звука - тогда ваш код получает контроль усиления.

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

приписка

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

0 голосов
/ 03 сентября 2010

Я не использую клипы, загрузка памяти занимает больше времени в зависимости от размера файла, который вы читаете. Я предпочитаю читать байты и использую этот метод, который я создал:

public void play(File file) throws UnsupportedAudioFileException, IOException, LineUnavailableException, InterruptedException
{

    AudioInputStream encoded = AudioSystem.getAudioInputStream(file);
    AudioFormat encodedFormat = encoded.getFormat();
    AudioFormat decodedFormat = this.getDecodedFormat(encodedFormat);

    line = AudioSystem.getSourceDataLine(decodedFormat);
    currentDecoded = AudioSystem.getAudioInputStream(decodedFormat, encoded);
    line.open(decodedFormat);
    line.start();
    byte[] b = new byte[this.bufferSize];
    int i = 0;
    synchronized(lock){
        while(true)
        {
            i = currentDecoded.read(b, 0, b.length);
            if(i == -1)
                break;

            line.write(b, 0, i);
            if(paused == true)
            {
                line.stop();
                lock.wait();
                line.start();
            }
        }
    }
    line.drain();
    line.stop();
    line.close();
    currentDecoded.close();
    encoded.close();
}

он использует этот метод:

protected AudioFormat getDecodedFormat(AudioFormat format)
{
    AudioFormat decodedFormat = new AudioFormat(
            AudioFormat.Encoding.PCM_SIGNED,  // Encoding to use
            format.getSampleRate(),           // sample rate (same as base format)
            16,               // sample size in bits (thx to Javazoom)
            format.getChannels(),             // # of Channels
            format.getChannels()*2,           // Frame Size
            format.getSampleRate(),           // Frame Rate
            false                 // Big Endian
    );
    return decodedFormat;    
}
0 голосов
/ 08 мая 2009

Почему вы хотите убить нить? Он исчезнет сам по себе, как только прекратит работу.

Если вы настаиваете, установите синхронизированный метод, который вы можете вызвать, чтобы установить флаг «умри сейчас»; периодически проверяйте этот флаг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...