The Xapo API allows the creation of cross-platform audio processing objects (XAPO) as well as the Microsoft cross-platform Audio creation tool (XACT) for XAudio2 use on Windows and Xbox 360.
The Xapo API provides IXAPO interfaces and Cxapobase classes that you can use to create new Xapo types. The Ixapo interface contains all the methods required to create a new Xapo. The simple inheritance of the Cxapobase class implements the Ixapo interface, except Ixapo::P rocess method, because this method is unique for each xapo.
The Xapo instance is passed to XAudio2 in the form of an IUnknown interface. XAudio2 uses QueryInterface to obtain the Ixapo interface and detects whether Ixapo inherits the Ixapoparameters interface.
Audio data uses Ixapo: The pinputprocessparameters parameter of the:P Rocess method is passed from voice to each audio effect. Then use Poutputprocessparameters to pass the processed data to voice.
To create a new static Xapo:
1. Derive a new Xapo class with Cxapobase as the base class;
2. Override the Ixapo::lockforprocess method implemented by the Cxapobase class: Override this method to allow format-related information for audio data to be used in the Ixapo::P rocess method.
3. Implement Ixapo::P Rocess Method:
Ixapo: A stream buffer that accepts input and output audio data:P the Rocess method. Typical xapo typically have only one input stream buffer and one output stream buffer.
The data that processes the input stream buffers needs to be based on the audio format given in the Lockforprocess function and any flags that are passed to the process function along with the input stream buffers.
The processed input stream buffer data needs to be copied to the output stream buffer. The bufferflags parameter of the output stream buffer can only be set to Xapo_buffer_valid or xapo_buffer_silent.
The following example simply makes a simple copy of the data from the input buffer to the output buffer, unless the input buffer's flag bit is xapo_buffer_silent.
Class Caudioxapo:public cxapobase{public:virtual HRESULT stdmethodcalltype 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);} virtual void Stdmethodcalltype 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 is legitimateassert (inflags = = Xapo_buffer_valid | | inflags = xapo_buffer_silent); as SERT (outflags = = Xapo_buffer_valid | | outflags = = xapo_buffer_silent);//Check input Apo_buffer_flagsswitch (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, needs to be-done for this case is setting the//output buffer flag to xapo_buffer_silent which was done below.break;}} Set destination valid frame count, and buffer flagspoutputprocessparameters[0]. Validframecount = Pinputprocessparameters[0]. Validframecount; Set destination frame count same as sourcepoutputprocessparameters[0]. Bufferflags = Pinputprocessparameters[0]. Bufferflags; Set destination buffer flags same as Source}private:int m_uchannels;int m_ubytespersample;};
when writing the process method, it is important to note that the XAudio2 audio data is interleaved, which means that the data for each channel is obtained using the adjacent specific sample number. For example, if you have a 4-channel waveform audio playing in XAudio2, the audio data will be channel 01 samples, channel 11 samples, channel 21 samples, channel 31 samples, then loop in turn.
The DirectX SDK provides examples:
Path on Windows:
SDK Root \samples\c++\xaudio2\xaudio2customapo
On the Xbox 360 path:
SDK Root \source\samples\audio\xaudio2customapo
Example Description:
The example creates a simple XAudio2 playback graph and adds a series of custom apos to play the source voice:
Simpleapo applies a simple gain factor by multiplying it with the processed sample data.
Monitorapo transmits audio data to the main thread by means of a lock-independent communication channel that is initialized by the application.
Comp1apo shows a typical dynamic-change compression effect.
These apos are implemented using a helper template class Sampleapobase, which can handle shared registrations, class factories, and parameter handling operations. It is not necessary to use this template class, but it can be used to simplify this example.
AC qq:1245178753
This address: http://blog.csdn.net/u011417605/article/details/51193156
XAudio2 Learning Custom Audio effects