How to: Create an Effect Chain

This topic shows you how you can apply an effect chain to a voice to allow custom processing of the audio data for that voice. This topic describes how to use the reverb effect, which is one of the built-in XAudio2 effects.

To create a basic effect chain that applies an effect to a voice

  1. Create the effect.

    In this example, the XAudio2CreateReverb function creates a reverb effect. See XAudio2 Audio Effects for a list of possible sources of effects for use with XAudio2.

    IUnknown * pXAPO;
    hr = XAudio2CreateReverb(&pXAPO);
    
  2. Populate an XAUDIO2_EFFECT_DESCRIPTOR structure with data.

    If there are multiple effects in the chain, each effect will need a XAUDIO2_EFFECT_DESCRIPTOR structure.

    XAUDIO2_EFFECT_DESCRIPTOR descriptor;
    descriptor.InitialState = true;
    descriptor.OutputChannels = 1;
    descriptor.pEffect = pXAPO;
    
  3. Populate an XAUDIO2_EFFECT_CHAIN structure with data. In this case, the chain only has one effect. If the chain has more than one effect, the EffectCount member will contain the count of effects, and the pEffectDescriptors member will point to an array of XAUDIO2_EFFECT_DESCRIPTOR structures.

    XAUDIO2_EFFECT_CHAIN chain;
    chain.EffectCount = 1;
    chain.pEffectDescriptors = &descriptor;
    
  4. Apply the effect chain to a voice with the SetEffectChain function.

    You can apply effect chains to master voices, source voices, and submix voices.

    pVoice->SetEffectChain(&chain);
    
  5. Release the effect with IUnknown::Release.

    When you create an XAPO, it will have a reference count of 1. When the XAPO is passed to XAudio2 with SetEffectChain, XAudio2 increments the reference count on the XAPO. Releasing the client's reference to the XAPO allows XAudio2 to take ownership of the XAPO. If XAudio2 has the only reference to the XAPO, it will be disposed of when it is no longer being used by XAudio2. If the client code needs to maintain a reference to the XAPO—for example for later reuse—you should skip this step.

    pXAPO->Release();
    
  6. Populate the parameter structure, if any, associated with the effect. The reverb effect uses an XAUDIO2FX_REVERB_PARAMETERS structure.

    XAUDIO2FX_REVERB_PARAMETERS reverbParameters;
    reverbParameters.ReflectionsDelay = XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_DELAY;
    reverbParameters.ReverbDelay = XAUDIO2FX_REVERB_DEFAULT_REVERB_DELAY;
    reverbParameters.RearDelay = XAUDIO2FX_REVERB_DEFAULT_REAR_DELAY;
    reverbParameters.PositionLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION;
    reverbParameters.PositionRight = XAUDIO2FX_REVERB_DEFAULT_POSITION;
    reverbParameters.PositionMatrixLeft = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX;
    reverbParameters.PositionMatrixRight = XAUDIO2FX_REVERB_DEFAULT_POSITION_MATRIX;
    reverbParameters.EarlyDiffusion = XAUDIO2FX_REVERB_DEFAULT_EARLY_DIFFUSION;
    reverbParameters.LateDiffusion = XAUDIO2FX_REVERB_DEFAULT_LATE_DIFFUSION;
    reverbParameters.LowEQGain = XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_GAIN;
    reverbParameters.LowEQCutoff = XAUDIO2FX_REVERB_DEFAULT_LOW_EQ_CUTOFF;
    reverbParameters.HighEQGain = XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_GAIN;
    reverbParameters.HighEQCutoff = XAUDIO2FX_REVERB_DEFAULT_HIGH_EQ_CUTOFF;
    reverbParameters.RoomFilterFreq = XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_FREQ;
    reverbParameters.RoomFilterMain = XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_MAIN;
    reverbParameters.RoomFilterHF = XAUDIO2FX_REVERB_DEFAULT_ROOM_FILTER_HF;
    reverbParameters.ReflectionsGain = XAUDIO2FX_REVERB_DEFAULT_REFLECTIONS_GAIN;
    reverbParameters.ReverbGain = XAUDIO2FX_REVERB_DEFAULT_REVERB_GAIN;
    reverbParameters.DecayTime = XAUDIO2FX_REVERB_DEFAULT_DECAY_TIME;
    reverbParameters.Density = XAUDIO2FX_REVERB_DEFAULT_DENSITY;
    reverbParameters.RoomSize = XAUDIO2FX_REVERB_DEFAULT_ROOM_SIZE;
    reverbParameters.WetDryMix = XAUDIO2FX_REVERB_DEFAULT_WET_DRY_MIX;
    
  7. Pass the effect parameter structure to the effect by calling the SetEffectParameters function on the voice to which the effect is attached.

    hr = pVoice->SetEffectParameters( 0, &reverbParameters, sizeof( reverbParameters ) );
    
  8. Disable or enable the effect, whenever appropriate.

    You can use DisableEffect at any time to turn an effect off.

    pVoice->DisableEffect(0);
    

    You can turn on an effect again with EnableEffect.

    pVoice->EnableEffect(0);
    

    The parameters for DisableEffect and EnableEffect specify which effect in the chain to enable or disable.

Audio Effects

XAudio2 Programming Guide

How to: Build a Basic Audio Processing Graph

XAPO Overview

How to: Use XAOPFX in XAudio2

How to: Use an XAOP in XAudio2