multiple effects in XAudio2 voice chain

Last post 05-08-2008, 1:15 PM by bino,. 3 replies.
Sort Posts: Previous Next
  •  04-23-2008, 1:57 PM

    multiple effects in XAudio2 voice chain

    I'm trying to get a reverb effect on every source voice in addition to having a reverb effect on a master Submix, whenever I have both running the audio is garbage.  Is it possible to do this?

    I've tried a couple things: Below is setting up the sumix master with its reverb effect

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
      // Reverb effect in XAudio2 currently only supports mono channel count
      const XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { pReverbEffect, TRUE, 1 } };
      const XAUDIO2_EFFECT_CHAIN effectChain = { 1, effects };

      // Create our submix voices
      if( FAILED(hr = pXAudio2->CreateSubmixVoice( &pSubmixMaster, 1,
              details.OutputFormat.Format.nSamplesPerSec, 0, 1, NULL, &effectChain ) ) )
      {
        pXAudio2->Release();
        pReverbEffect->Release();
        pReverbEffect=NULL;
        pXAudio2=NULL;
        Debug::Notify("Failed CreateSubmixVoice");
        return;
      }

      // Set default FX params
      XAUDIO2FX_REVERB_PARAMETERS native;
      ReverbConvertI3DL2ToNative( &PRESET_EFX[0], &native );
      pSubmixMaster->SetEffectParameters( 0, &native, sizeof(native) );

    1. Each SourceVoice gets routed to a SubmixVoice (which has a reverb effect) which then gets routed to the master Sumix (which also has a reverb effect).  This clips the audio extremely badly.  Below shows what I'm doing

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
      IUnknown* tempEfx;
      // Create reverb effect
      if ( FAILED(hr = XAudio2CreateReverb( &tempEfx, flags ) ) )
      {
        pXAudio2->Release();
        pXAudio2=NULL;
        Debug::Notify("Failed XAudio2CreateReverb");
        return;
      }
      g_XA2BuffersIdea.m_ReverbEfx = tempEfx;

      const IXAudio2Voice* voices[] = { pMasteringVoice, pSubmixMaster };
      const XAUDIO2_VOICE_SENDS sendList = { 2, (IXAudio2Voice**)voices };

      const XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { tempEfx, TRUE, 1 } };
      const XAUDIO2_EFFECT_CHAIN effectChain = { 1, effects };

      IXAudio2SubmixVoice* tempMixer;
      if( FAILED(hr = pXAudio2->CreateSubmixVoice( &tempMixer, 1,
          details.OutputFormat.Format.nSamplesPerSec, 0, 0, &sendList, &effectChain ) ) )
      {
        pXAudio2->Release();
        pReverbEffect->Release();
        pReverbEffect=NULL;
        pXAudio2=NULL;
        Debug::Notify("Failed CreateSubmixVoice");
        return;
      }
      tempMixer->SetEffectParameters( 0, &native, sizeof(native) );
      g_XA2BuffersIdea.m_EfxMixer = tempMixer;

      const IXAudio2Voice* voices[] = { pMasteringVoice, pSubmixMaster, (IXAudio2SubmixVoice*)m_EfxMixer };
      const XAUDIO2_VOICE_SENDS sendList = { 3, (IXAudio2Voice**)voices };
      IXAudio2SourceVoice* tmpBuff;
      if (FAILED(hr= pXAudio2->CreateSourceVoice( &tmpBuff, wavformat, 0,
                        XAUDIO2_DEFAULT_FREQ_RATIO, NULL, &sendList ) ))
      {
        Debug::Notify("Failed CreateSourceVoice");
        return;
      }
     
    2. Each SourceVoice gets a reverb effect using the effect chain param in CreateSourceVoice(..) and is then send to the master Submix (which has its own reverb effect).  This yields silence.
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

    const IXAudio2Voice* voices[] = { pMasteringVoice, pSubmixMaster };

    const XAUDIO2_VOICE_SENDS sendList = { 2, (IXAudio2Voice**)voices };

    // Create reverb effect
    IUnknown* tempReverb=NULL;
    int flags = 0;
    #ifdef _DEBUG
    flags = XAUDIO2_DEBUG_ENGINE;
    #endif
    if ( FAILED(hr = XAudio2CreateReverb( &tempReverb, flags ) ) )
    {
      Debug::Notify("Failed XAudio2CreateReverb");
    }

    // Create the source voice
    IXAudio2SourceVoice* tmpBuff;
    if (tempReverb)
    {

      const XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { tempReverb, TRUE, 1 } };
      const XAUDIO2_EFFECT_CHAIN effectChain = { 1, effects };

      if (FAILED(hr= pXAudio2->CreateSourceVoice( &tmpBuff, wavformat, XAUDIO2_VOICE_USEFILTER,
                 XAUDIO2_DEFAULT_FREQ_RATIO, NULL, &sendList, &effectChain ) ))
      {
        Debug::Notify("Failed CreateSourceVoice");
        return;
      }
      XAUDIO2FX_REVERB_PARAMETERS native;
      ReverbConvertI3DL2ToNative( &PRESET_EFX[0], &native );
      tmpBuff->SetEffectParameters( 0, &native, sizeof(native) );
      m_ReverbEfx = tempReverb;
    }
    else
    {
      if (FAILED(hr= pXAudio2->CreateSourceVoice( &tmpBuff, wavformat, 0,
                 XAUDIO2_DEFAULT_FREQ_RATIO, NULL, &sendList ) ))
      {
        Debug::Notify("Failed CreateSourceVoice");
        return;
      }
    }

    I basically need the ability to have an effect on any source voice in addition to having an effect running on the submix master.

    Any advice on what I'm doing wrong or a method to do this would be great.

    Bino

  •  04-23-2008, 6:24 PM

    Re: multiple effects in XAudio2 voice chain

    So i found some strange results looking deeper into this:

    the noise went completely away when i didn't use the XAUDIO2_DEBUG_ENGINE flag when creating the XAudio2 device.

    if using the XAUDIO2_DEBUG_ENGINE flag when creating the XAudio2 device, the noise was not present if i used less than 23 SourceVoices (each voice has its own SubmixVoice).   note - there are never more than 10 or so voices playing at a time, the noise just when away if i didn't allocate the voices.

  •  05-04-2008, 12:37 AM

    Re: multiple effects in XAudio2 voice chain

    Well, the reverb is very CPU-intensive - that's why it sounds so good  :-)

    You could simply be running low on CPU.  We only envisioned a small number of reverbs being used at a time.  Typically it would be applied to one submix, or perhaps several if you're crossfading across different environments with different reverb characteristics.

    You could try calling SetPerformanceData() to make sure your CPU usage is well below 90%.  If it isn't, calling SetDebugConfiguration() with the XAUDIO2_LOG_TIMING flag will tell you where all that time is being spent - very likely in the reverb.

    By the way, the debug XAudio2 binaries in the June release will be a lot faster than the ones from March.  Not as fast as retail, of course, but hopefully fast enough to repro real-world bugs involving hundreds of voices without glitching.

    Dugan Porter [MS]
    Game Audio Team


    Dugan Porter [MS]
    Game Audio Team
  •  05-08-2008, 1:15 PM

    Re: multiple effects in XAudio2 voice chain

    Thanks for the reply Dugan.

     

    One thing that still seems odd to me is that it seems to be spending more CPU time when I allocate more voices (even if they aren't playing and the reverb is off).  When I get some time(could be a while. . . always so busy :S) I'll try to dig into this a little more so I can give you some more info.

     

    Bino

View as RSS news feed in XML
©2007 Microsoft Corporation. All rights reserved. Privacy Statement Terms of Use Code of Conduct Feedback