LibGDX: AudioFlinger не может создать трек, статус -12 - PullRequest
1 голос
/ 09 марта 2019

Я недавно добавил звуки в свою игру LibGDX.Он настроен таким образом, что все нужные мне звуки загружаются в AssetManager, и я извлекаю их, когда мне нужно воспроизвести их, методом getSound(String name).

Он отлично работает, когда вы немногоиграть, но в конце концов он перестает играть некоторые, а иногда и большинство из них.Я бы хорошо расставил приоритеты по тем, которые воспроизводились последними, и по необходимости остановил те, что старше, но LibGDX, похоже, не дает вам такого большого контроля над ними.

Ошибка журналаЯ понимаю, когда это происходит E/AudioTrack: AudioFlinger could not create track, status: -12 E/SoundPool: Error creating AudioTrack.

Обычно он воспроизводит довольно много одновременно, вероятно, около 10-20 маленьких звуков за раз, в зависимости от ситуации, поэтому я почти уверен, что это проблема,Я читал здесь о выпуске звука после его воспроизведения с использованием SoundPool, но я не совсем уверен, как это сделать с LibGDX, или, если это возможно, потому что я не видел такого класса, когда смотрел.

Кроме того, я использую файлы ogg для всех звуков, и ни один из них не очень большой.Спасибо!

1 Ответ

1 голос
/ 11 марта 2019

Решено! Создав свой собственный (своего рода псевдо) класс Sound и загрузчик для него, который будет использоваться с AssetManager с использованием assetManager.setLoader(). В пользовательском классе Sound я устанавливаю каждый звук для отслеживания их soundId s в Array<Long>, затем каждый раз, когда он воспроизводится, я проверяю размер массива по переменной limit, останавливая самый старый звук в массиве. 0 означает, что можно играть только по одному, до тех пор, пока я решу, что это необходимо. Возможно, это не идеальное решение, но, похоже, оно работает довольно хорошо.

Критика приветствуется.

Мой созданный класс "Sound":

public class MySound {

    private Sound sound;
    private Array<Long> ids;
    private int limit;

    public MySound(Sound sound) {
        this.sound = sound;
        ids = new Array<Long>();
        limit = 0;
    }

    public long play() {
        limitSounds();
        long id = sound.play();
        ids.add(id);

        return id;
    }

    public long play(float volume) {
        limitSounds();
        long id = sound.play(volume);
        ids.add(id);

        return id;
    }

    public long play(float volume, float pitch, float pan) {
        limitSounds();
        long id = sound.play(volume, pitch, pan);
        ids.add(id);

        return id;
    }

    public long loop() {
        limitSounds();
        long id = sound.loop();
        ids.add(id);

        return id;
    }

    public long loop(float volume) {
        limitSounds();
        long id = sound.loop(volume);
        ids.add(id);

        return id;
    }

    public long loop(float volume, float pitch, float pan) {
        limitSounds();
        long id = sound.loop(volume, pitch, pan);
        ids.add(id);

        return id;
    }

    public void stop() {
        ids.clear();
        sound.stop();
    }

    public void pause() {
        sound.pause();
    }

    public void resume() {
        sound.resume();
    }

    public void dispose() {
        sound.dispose();
    }

    public void stop(long soundId) {
        if (ids.contains(soundId, true)) {
            ids.removeValue(soundId, true);
        }
        sound.stop(soundId);
    }

    public void pause(long soundId) {
        sound.pause(soundId);
    }

    public void resume(long soundId) {
        sound.resume(soundId);
    }

    public void setLooping(long soundId, boolean looping) {
        sound.setLooping(soundId, looping);
    }

    public void setPitch(long soundId, float pitch) {
        sound.setPitch(soundId, pitch);
    }

    public void setVolume(long soundId, float volume) {
        sound.setVolume(soundId, volume);
    }

    public void setPan(long soundId, float pan, float volume) {
        sound.setPan(soundId, pan, volume);
    }

    private void limitSounds () {
        if (ids.size > limit) {
            sound.stop(ids.get(0));
            ids.removeIndex(0);
        }
    }

    public void setLimit (int limit) {
        this.limit = limit;
    }
}

MySoundLoader класс, для AssetManager:

public class MySoundLoader extends AsynchronousAssetLoader<MySound, MySoundLoader.SoundParameter> {

    private MySound sound;

    public MySoundLoader(FileHandleResolver resolver) {
        super(resolver);
    }

    @Override
    public Array<AssetDescriptor> getDependencies(String fileName, FileHandle file, SoundParameter parameter) {
        return null;
    }

    @Override
    public void loadAsync(AssetManager manager, String fileName, FileHandle file, SoundParameter parameter) {
        sound = new MySound(Gdx.audio.newSound(file));
    }

    @Override
    public MySound loadSync(AssetManager manager, String fileName, FileHandle file, SoundParameter parameter) {
        MySound sound = this.sound;
        this.sound = null;
        return sound;
    }

    static public class SoundParameter extends AssetLoaderParameters<MySound> {
    }
}
...