В новой версии Dagon будет встроенный звуковой движок на основе SoLoud — расширение dagon:audio. Поясню для тех, кто не знает: SoLoud — это библиотека-микшер с поддержкой 3D-звука и базовых потоковых форматов (WAV, MP3, OGG, FLAC), а также трекерных форматов через OpenMPT. Есть частотные фильтры и встроенные синтезаторы — в частности, текстово-речевой преобразователь, SFXR, эмулятор VIC-20 и генератор разных видов шума. SoLoud поддерживает множество бэкендов, и по дефолту работает на основе SDL2, как и сам Dagon (пользователь, однако, может выбрать конкретный бэкенд через опцию audio.backend в settings.conf). Короче говоря, это своего рода «FMOD от мира OpenSource». Особо отмечу удобный API и, более того, прямо из коробки — обертка для D, позволяющая писать в объектно-ориентированном стиле.

SoLoud можно было и раньше использовать в приложениях Dagon с использованием BindBC-SoLoud, но dagon:audio упрощает работу со звуком в играх еще больше, предоставляя удобный механизм привязки 3D-слушателя и пространственных звуков SoLoud к объектам движка. Для этого я ввел менеджер AudioManager и компонент SoundComponent:

class MyGame: Game
{
    AudioManager audioManager;

    this(uint windowWidth, uint windowHeight, bool fullscreen, 
        string title, string[] args)
    {
        super(windowWidth, windowHeight, fullscreen, title, args);
        audioManager = New!AudioManager(this);
        currentScene = New!TestScene(this);
    }
}

class TestScene: Scene
{
    AudioManager audio;
    SoundComponent cubeSpeaker;
    WavStream music;

    this(MyGame game)
    {
        super(game);
        this.audio = game.audioManager;
    }

    override void afterLoad()
    {
        Camera camera = addCamera();
        camera.position = Vector3f(0.0f, 1.8f, 5.0f);
        game.renderer.activeCamera = camera;

        audio.listener = camera;

        auto eCube = addEntity();
        eCube.position = Vector3f(0, 1, 0);

        cubeSpeaker = audio.addSoundTo(eCube);
        music = audio.loadMusic("data/music/song.mp3");
        cubeSpeaker.play(music);
    }

    override void onUpdate(Time t)
    {
        audio.update(t);
    }
}

Позиция и ориентация слушателя и позиция источника звука обновляются автоматически в update.

Есть также класс PlaylistPlayer для управления плейлистами. Он упрощает загрузку множества аудиофайлов из папки и переключение между ними — полезно для автоматического воспроизведения фоновых мелодий одну за другой.

PlaylistPlayer pl = audio.addPlaylistPlayer();
pl.addTracksFromDirectory("data/music");
pl.play(0);

SoundComponent и PlaylistPlayer совместимы между собой:

cubeSpeaker.playlistPlayer = pl;
cubeSpeaker.play(0);

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *