Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
API XAPO предоставляет интерфейс IXAPO и класс CXAPOBase для создания новых типов XAPO. Интерфейс IXAPO содержит все методы, которые необходимо реализовать для создания нового XAPO. Класс CXAPOBase предоставляет базовую реализацию интерфейса IXAPO. CXAPOBase реализует все методы интерфейса IXAPO IXAPO за исключением метода IXAPO::P rocess, который является уникальным для каждого XAPO.
Чтобы создать новый статический XAPO
Произведите наследование нового класса XAPO от базового класса CXAPOBase.
Заметка
XAPOs реализуют интерфейс IUnknown. Интерфейсы IXAPO и IXAPOParameters включают три метода IUnknown: QueryInterface, AddRefи Release. CXAPOBase предоставляет реализации всех трех методов IUnknown. Новый экземпляр CXAPOBase будет иметь счетчик ссылок, равный 1. Он будет уничтожен, когда его число ссылок становится 0. Чтобы разрешить XAudio2 уничтожить экземпляр XAPO, если он больше не нужен, вызовите IUnknown::Release в XAPO после добавления в цепочку эффектов XAudio2. Дополнительные сведения об использовании XAPO с XAudio2 см. в статье . Более подробную информацию о применении XAPO с XAudio2 см. в разделе.
Переопределите реализацию метода IXAPO::LockForProcess в классе CXAPOBase.
Переопределение LockForProcess позволяет хранить сведения о формате звуковых данных для использования в IXAPO::Process.
Реализуйте метод IXAPO::Process.
XAudio2 вызывает метод IXAPO::P rocess всякий раз, когда XAPO должен обрабатывать звуковые данные. процесс содержит большую часть кода для XAPO.
Реализация метода Process
Метод IXAPO::P rocess принимает буферы потока для входных и выходных звуковых данных. Обычно XAPO ожидает один входной буфер потока и один выходной буфер потока. Обработка данных из буфера входного потока должна основываться на формате, указанном в функции LockForProcess и на любых флагах, переданных функции Process вместе с буфером входного потока. Скопируйте обработанные входные данные буфера потока в буфер выходного потока. Задайте параметр BufferFlags буфера выходного потока как XAPO_BUFFER_VALID или XAPO_BUFFER_SILENT.
В следующем примере показана реализацияLockForProcessи Process, которая просто копирует данные из входного буфера в выходной буфер. Однако обработка не производится, если входной буфер помечен 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
}
При написании метода процесса важно отметить, что аудиоданные XAudio2 являются перемежающимися. Это означает, что данные из каждого канала находятся рядом с определенным числом выборки. Например, если имеется 4-канальная волна, которая воспроизводится в XAudio2, звуковые данные представляют собой образец канала 0, образец канала 1, образец канала 2, образец канала 3, а затем следующий образец каналов 0, 1, 2, 3 и так далее.
Связанные разделы