Comment ne pas développer des moteurs sonores



Lors de la programmation du son dans des applications et des jeux, je devais souvent réécrire toute la base de code des modules de son, car beaucoup d'entre eux avaient une architecture trop compliquée ou, au contraire, ne pouvaient rien faire d'autre que de simples jouer des sons.



L'analogie avec le rendu des images dans les jeux fonctionne bien avec les moteurs sonores: si vous avez un pipeline trop simple avec un grand nombre d'abstractions, vous pouvez difficilement programmer quelque chose de plus compliqué qu'un cube avec des engrenages. D'un autre côté, si tout votre code se compose d'appels directs OpenGL ou D3D, vous ne pouvez pas mettre à l'échelle votre code spaghetti sans douleur.



Quelle est la pertinence de la comparaison avec le rendu graphique?



Dans le rendu sonore, les mêmes processus se produisent que dans le rendu graphique: mise à jour des ressources de la logique du jeu, traitement des données sous une forme digestible, post-traitement, sortie du résultat final. Tout cela peut prendre beaucoup de temps, donc dans un souci d'illustration, j'utilise ma bibliothèque audio pour tester les performances de rendu.



SSD , Opus , , DSP (, ), . , : Inte Core i9 9900 4.5GHz, 32GB RAM, SSD 480GB SATA. 48000 44100.



    FRESPONZE_BEGIN_TEST
    if (!pFirstListener) return false;
    //      - 
    if (RingBuffer.GetLeftBuffers()) return false;
    RingBuffer.SetBuffersCount(RING_BUFFERS_COUNT);
    RingBuffer.Resize(Frames * Channels);
    OutputBuffer.Resize(Frames * Channels);
    tempBuffer.Resize(Channels, Frames);
    mixBuffer.Resize(Channels, Frames);

    for (size_t i = 0; i < RING_BUFFERS_COUNT; i++) {
        tempBuffer.Clear();
        mixBuffer.Clear();
        pListNode = pFirstListener;
        while (pListNode) {
            /*       */
            EmittersNode* pEmittersNode = nullptr;
            if (!pListNode->pListener) break;
            pListNode->pListener->GetFirstEmitter(&pEmittersNode);
            while (pEmittersNode) {
                tempBuffer.Clear();
                pEmittersNode->pEmitter->Process(tempBuffer.GetBuffers(), Frames);
                //  
                for (size_t o = 0; o < Channels; o++) {
                    MixerAddToBuffer(mixBuffer.GetBufferData((fr_i32)o), tempBuffer.GetBufferData((fr_i32)o), Frames);
                }

                pEmittersNode = pEmittersNode->pNext;
            }

            pListNode = pListNode->pNext;
        }

        /*         */
        PlanarToLinear(mixBuffer.GetBuffers(), OutputBuffer.Data(), Frames * Channels, Channels);
        RingBuffer.PushBuffer(OutputBuffer.Data(), Frames * Channels);
        RingBuffer.NextBuffer();
    }
    FRESPONZE_END_TEST("Audio render")


[00:00:59:703]: 'Audio render' operation passed: 551 microseconds
[00:00:59:797]: 'Audio render' operation passed: 512 microseconds
[00:00:59:906]: 'Audio render' operation passed: 541 microseconds
[00:01:00:000]: 'Audio render' operation passed: 583 microseconds


, , , . , , .



?



, . — -, C++, SoLoud OpenAL. , — . API , OpenAL Wwise.



. — ref_sound ISoundManager, , , , , . — , UAudioComponent Unreal Engine.



void Class::Function()
{
    //        
    snd.play_at_pos(0, Position(), false);

    //  
    if (IsHappened())
    {
        // ...
    }

    // ...
}


, — CSoundRender_Target, API OpenAL DirectSound, CSoundRender_Cache — Vorbis . target — , source + emitter.







, Core (FMOD Wwise), API (PortAudio).





,





, — (hardware) (mixer). , , API. .



:



void GameScheduler::Update() {
    // ...    

    // ,     .
    //    ,    
    //    .
    SoundManager::StopSound(id);

    // ...
}

// ...

void AudioHardware::Update() {
    // ...    

    //     : 
    //   ,    
    //      .
    AudioMixer::Render(input, frames);
    memcpy(output, input, frames * channels * frame_size);

    // ...
}


- . AudioHardware PortAudio, Windows Audio Session API. SoundManager — FMOD Wwise. AudioHardware , .



: routing emitters-source . DAW, , . , side-chain , . , - .







— emitters-source. 2 — (source), , , (emitter) — , , -. emitters-source ( Wwise FMOD virtual emitters), .



emitters-source . miniaudio, .




All Articles