다음을 통해 공유


방법: XAPO 만들기

XAPO API는 새 XAPO 형식을 빌드하기 위한 IXAPO 인터페이스 및 CXAPOBase 클래스를 제공합니다. IXAPO 인터페이스에는 새 XAPO를 만들기 위해 구현해야 하는 모든 메서드가 포함되어 있습니다. CXAPOBase 클래스는 IXAPO 인터페이스의 기본 구현을 제공합니다. CXAPOBase 각 XAPO에 고유한 IXAPO::P rocess 메서드를 제외한 모든 IXAPO 인터페이스 메서드를 구현합니다.

새 정적 XAPO를 만들려면

  1. CXAPOBase 기본 클래스에서 새 XAPO 클래스를 파생합니다.

    메모

    XAPO는 IUnknown 인터페이스를 구현합니다. IXAPOIXAPOParameters 인터페이스에는 QueryInterface, AddRef릴리스세 가지 IUnknown 메서드가 포함됩니다. CXAPOBase 세 가지 IUnknown 메서드의 구현을 제공합니다. CXAPOBase 새 인스턴스의 참조 수는 1입니다. 참조 수가 0이 되면 제거됩니다. XAudio2가 더 이상 필요하지 않을 때 XAPO 인스턴스를 삭제할 수 있도록 하려면 XAudio2 효과 체인에 추가된 후 XAPO에서 IUnknown::Release 호출합니다. XAudio2와 함께 XAPO를 사용하는 방법에 대한 자세한 내용은 XAudio2에서 XAPO 사용 방법을 참조하십시오.

     

  2. IXAPO::LockForProcess 메서드의 CXAPOBase 클래스 구현을 재정의합니다.

    LockForProcess 재정의하면 오디오 데이터 형식에 대한 정보를 IXAPO::Process에서 사용할 수 있도록 저장할 수 있습니다.

  3. IXAPO::P rocess 메서드를 구현합니다.

    XAudio2는 XAPO가 오디오 데이터를 처리해야 할 때마다 IXAPO::P rocess 메서드를 호출합니다. 프로세스 XAPO에 대한 코드의 대부분을 포함합니다.

프로세스 메서드 구현

IXAPO::P rocess 메서드는 입력 및 출력 오디오 데이터에 대한 스트림 버퍼를 허용합니다. 일반적인 XAPO에는 하나의 입력 스트림 버퍼와 하나의 출력 스트림 버퍼가 예상됩니다. 입력 스트림 버퍼의 데이터 처리는 LockForProcess 함수에 지정된 형식 및 입력 스트림 버퍼를 사용하여 Process 함수에 전달된 플래그를 기반으로 해야 합니다. 처리된 입력 스트림 버퍼 데이터를 출력 스트림 버퍼에 복사합니다. 출력 스트림 버퍼의 BufferFlags 매개 변수를 XAPO_BUFFER_VALID 또는 XAPO_BUFFER_SILENT설정합니다.

다음 예제에서는 입력 버퍼에서 출력 버퍼로 데이터를 복사하는 LockForProcessProcess 구현을 보여 줍니다. 그러나 입력 버퍼가 XAPO_BUFFER_SILENT표시되어 있으면 처리가 없습니다.

STDMETHOD(LockForProcess) (UINT32 InputLockedParameterCount,
          const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pInputLockedParameters,
          UINT32 OutputLockedParameterCount,
          const XAPO_LOCKFORPROCESS_BUFFER_PARAMETERS* pOutputLockedParameters)
{
    assert(!IsLocked());
    assert(InputLockedParameterCount == 1);
    assert(OutputLockedParameterCount == 1);
    assert(pInputLockedParameters != NULL);
    assert(pOutputLockedParameters != NULL);
    assert(pInputLockedParameters[0].pFormat != NULL);
    assert(pOutputLockedParameters[0].pFormat != NULL);


    m_uChannels = pInputLockedParameters[0].pFormat->nChannels;
    m_uBytesPerSample = (pInputLockedParameters[0].pFormat->wBitsPerSample >> 3);

    return CXAPOBase::LockForProcess(
        InputLockedParameterCount,
        pInputLockedParameters,
        OutputLockedParameterCount,
        pOutputLockedParameters);
}
STDMETHOD_(void, Process)(UINT32 InputProcessParameterCount,
           const XAPO_PROCESS_BUFFER_PARAMETERS* pInputProcessParameters,
           UINT32 OutputProcessParameterCount,
           XAPO_PROCESS_BUFFER_PARAMETERS* pOutputProcessParameters,
           BOOL IsEnabled)
{
    assert(IsLocked());
    assert(InputProcessParameterCount == 1);
    assert(OutputProcessParameterCount == 1);
    assert(NULL != pInputProcessParameters);
    assert(NULL != pOutputProcessParameters);


    XAPO_BUFFER_FLAGS inFlags = pInputProcessParameters[0].BufferFlags;
    XAPO_BUFFER_FLAGS outFlags = pOutputProcessParameters[0].BufferFlags;

    // assert buffer flags are legitimate
    assert(inFlags == XAPO_BUFFER_VALID || inFlags == XAPO_BUFFER_SILENT);
    assert(outFlags == XAPO_BUFFER_VALID || outFlags == XAPO_BUFFER_SILENT);

    // check input APO_BUFFER_FLAGS
    switch (inFlags)
    {
    case XAPO_BUFFER_VALID:
        {
            void* pvSrc = pInputProcessParameters[0].pBuffer;
            assert(pvSrc != NULL);

            void* pvDst = pOutputProcessParameters[0].pBuffer;
            assert(pvDst != NULL);

            memcpy(pvDst,pvSrc,pInputProcessParameters[0].ValidFrameCount * m_uChannels * m_uBytesPerSample);
            break;
        }

    case XAPO_BUFFER_SILENT:
        {
            // All that needs to be done for this case is setting the
            // output buffer flag to XAPO_BUFFER_SILENT which is done below.
            break;
        }

    }

    // set destination valid frame count, and buffer flags
    pOutputProcessParameters[0].ValidFrameCount = pInputProcessParameters[0].ValidFrameCount; // set destination frame count same as source
    pOutputProcessParameters[0].BufferFlags     = pInputProcessParameters[0].BufferFlags;     // set destination buffer flags same as source

}

Process 메서드를 작성할 때 XAudio2 오디오 데이터가 인터리브되어 있다는 점에 유의해야 합니다. 즉, 각 채널의 데이터가 특정 샘플 번호에 인접합니다. 예를 들어 XAudio2 원본 음성으로 재생되는 4개 채널 웨이브가 있는 경우 오디오 데이터는 채널 0 샘플, 채널 1 샘플, 채널 2 샘플, 채널 3 샘플 및 채널 0, 1, 2, 3 등의 다음 샘플입니다.

오디오 효과

XAPO 개요