Воспроизведение WAVS на Java - PullRequest
1 голос
/ 15 марта 2012

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

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

public class BGMusicPlayer implements Runnable {

File file;
AudioInputStream in;
SourceDataLine line;
int frameSize;
byte[] buffer = new byte [32 * 1024]; 
Thread player;
boolean playing = false;
boolean fileNotOver = true;

public BGMusicPlayer (File inputFile){
    try{
        file = inputFile;
        in = AudioSystem.getAudioInputStream (inputFile);
        AudioFormat format = in.getFormat();

        frameSize = format.getFrameSize(); 

        DataLine.Info info =new DataLine.Info (SourceDataLine.class, format); 
        line = (SourceDataLine) AudioSystem.getLine (info);

        line.open(); 

        player = new Thread (this);       
        player.start();
    }
    catch(Exception e){
        System.out.println("That is not a valid file. No music for you.");
    }
}


public void run() {
    int readPoint = 0;
    int bytesRead = 0;
    player.setPriority(Thread.MIN_PRIORITY);

        while (fileNotOver) {
            if (playing) {
                try {
                    bytesRead = in.read (buffer, 
                            readPoint, 
                            buffer.length - readPoint);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                if (bytesRead == -1) { 
                    fileNotOver = false; 
                    break;
                }

                int leftover = bytesRead % frameSize;

                // send to line
                line.write (buffer, readPoint, bytesRead-leftover);

                // save the leftover bytes
                System.arraycopy (buffer, bytesRead,
                        buffer, 0, 
                        leftover); 
                readPoint = leftover;
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

} 

public void start() {
    playing = true;
    if(!player.isAlive())
    player.start();
    line.start();
}

public void stop() {
    playing = false;
    line.stop();
}

}

1 Ответ

1 голос
/ 16 марта 2012

Вы довольно близки, но есть несколько необычных вещей, которые, возможно, способствуют проблеме производительности.

Прежде всего, если вы просто воспроизводите .wav, на самом деле не должно быть необходимости иметь дело с какой-либо «точкой чтения», а значением 0, и на самом деле не должно быть необходимости в «остатке вычисление. Когда вы выполняете запись, это должно быть просто число байтов, которые были прочитаны (возвращаемое значение метода read ()).

Мне также неясно, почему вы делаете ArrayCopy. Вы можете это потерять?

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

Мне любопытно, откуда твой аудиофайл. Вы не транслируете его через Интернет, не так ли?

Кстати, способ получения входных данных из файла и помещения его в InputStream, скорее всего, не будет работать с Java7. Многие люди сообщают об ошибке с этим. Оказывается, правильнее и эффективнее сгенерировать URL из файла, а затем получить AudioInputStream, используя URL в качестве аргумента, а не файла. Ошибка, которая может появиться, является ошибкой «Mark / Reset». (Поиск по нему покажет, что он появляется несколько раз.)

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