Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //link kernel32, Ole32, and xaudio2 to use
- #include <_kit_w32_audioX2.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <stdio.h>
- //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//
- HRESULT _kit_audioX2_CreateVoice(_kit_audioX2_Engine* engine, const WAVEFORMATEX* source_format, unsigned int* index_p){
- HRESULT returnStatus=S_OK; int locked=0, slot=-1;
- _IF_ERROR(engine==NULL,E_INVALIDARG,;);
- _IF_ERROR(source_format==NULL,E_INVALIDARG,;);
- _IF_ERROR(index_p==NULL,E_INVALIDARG,;);
- EnterCriticalSection(&engine->lock); locked=1;
- //if no voices have been added, then allocate space for first pointer
- if(!engine->sources_len){
- engine->sources=(IXAudio2SourceVoice**)CoTaskMemRealloc(engine->sources, sizeof(IXAudio2SourceVoice*));
- _IF_ERROR(engine->sources==NULL,E_OUTOFMEMORY,;);
- engine->sources[0]=NULL;
- engine->sources_len=1;
- }
- //try to find first free space
- unsigned int sources_len=engine->sources_len;
- for(unsigned int i=0; i<sources_len; ++i){
- if(engine->sources[i]==NULL){
- returnStatus=engine->object->CreateSourceVoice(&engine->sources[i], source_format);
- _IF_GOTO_ERROR(FAILED(returnStatus),;);
- slot=i; break;
- }
- }
- //if no free space was found, append new voice to source voice list
- if(slot == -1){
- engine->sources=(IXAudio2SourceVoice**)CoTaskMemRealloc(engine->sources, sources_len*sizeof(IXAudio2SourceVoice*));
- _IF_ERROR(engine->sources==NULL,E_OUTOFMEMORY,;);
- returnStatus=engine->object->CreateSourceVoice(&engine->sources[sources_len], source_format);
- _IF_GOTO_ERROR(FAILED(returnStatus),;);
- slot=engine->sources_len++;
- }
- _error_:
- if((engine!=NULL) && locked) LeaveCriticalSection(&engine->lock);
- if(slot != -1) *index_p=slot;
- return returnStatus;
- }
- HRESULT _kit_audioX2_DestroyVoice(_kit_audioX2_Engine* engine, unsigned int index){
- HRESULT returnStatus=S_OK; int locked=0;
- _IF_ERROR(engine==NULL,E_INVALIDARG,;);
- EnterCriticalSection(&engine->lock); locked=1;
- _IF_ERROR(index>=engine->sources_len,E_INVALIDARG,;);
- _IF_GOTO_ERROR(engine->sources[index]==NULL,;); //returnStatus=S_OK here
- //destroy source voice at index
- engine->sources[index]->DestroyVoice();
- //reallocate if index was the last element
- unsigned int last_source=engine->sources_len-1;
- if(index==last_source && last_source!=0){
- engine->sources=(IXAudio2SourceVoice**)CoTaskMemRealloc(engine->sources, last_source*sizeof(IXAudio2SourceVoice*));
- _IF_ERROR(engine->sources==NULL,E_OUTOFMEMORY,;);
- --engine->sources_len;
- } else engine->sources[index]=NULL;
- _error_:
- if((engine!=NULL) && locked) LeaveCriticalSection(&engine->lock);
- return returnStatus;
- }
- //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//
- HRESULT _kit_audioX2_CreateEngine(_kit_audioX2_Engine** engine_p,
- const WAVEFORMATEX* source_format,
- const wchar_t* deviceID){
- HRESULT returnStatus=S_OK; ULONG numRefs=1; int critical_section=0;
- _kit_audioX2_Engine* engine=NULL;
- _IF_ERROR(engine_p==NULL,E_INVALIDARG,;);
- _IF_ERROR(source_format==NULL,E_INVALIDARG,;);
- //allocate memory for struct
- engine=(_kit_audioX2_Engine*)CoTaskMemAlloc(sizeof(_kit_audioX2_Engine));
- _IF_ERROR(engine==NULL,E_OUTOFMEMORY,;);
- for(char i=0,*ch_p=(char*)engine; i<sizeof(_kit_audioX2_Engine); ++i) ch_p[i]=0;
- //initialize mutex
- InitializeCriticalSection(&engine->lock); critical_section=1;
- //create xaudio2 object
- returnStatus=XAudio2Create(&engine->object, 0, XAUDIO2_DEFAULT_PROCESSOR);
- _IF_GOTO_ERROR(FAILED(returnStatus),;);
- //create mastering voice
- LPWSTR _deviceID=(LPWSTR)deviceID;
- returnStatus=engine->object->CreateMasteringVoice(&engine->master,
- XAUDIO2_DEFAULT_CHANNELS,
- XAUDIO2_DEFAULT_SAMPLERATE,0,
- _deviceID);
- _IF_GOTO_ERROR(FAILED(returnStatus),;);
- //create the first source voice
- unsigned int slot;
- returnStatus=_kit_audioX2_CreateVoice(engine, source_format, &slot);
- _IF_GOTO_ERROR(FAILED(returnStatus),;);
- _error_:
- if(SUCCEEDED(returnStatus)) *engine_p=engine;
- else if(engine != NULL){
- if(engine->sources != NULL){
- _KIT_COM_CALL_S(engine->sources[slot],DestroyVoice);
- CoTaskMemFree(engine->sources);
- }
- _KIT_COM_CALL_S(engine->master,DestroyVoice);
- _KIT_COM_RELEASE_S(engine->object);
- if(critical_section) DeleteCriticalSection(&engine->lock);
- CoTaskMemFree(engine); engine=NULL;
- }
- return returnStatus;
- }
- HRESULT _kit_audioX2_DestroyEngine(_kit_audioX2_Engine** engine_p){
- HRESULT returnStatus=S_OK; ULONG numRefs=1; int locked=0;
- _kit_audioX2_Engine* engine=NULL;
- _IF_ERROR(engine_p==NULL,E_INVALIDARG,;);
- _IF_ERROR((engine=*engine_p)==NULL,E_INVALIDARG,;);
- EnterCriticalSection(&engine->lock); locked=1;
- //halt audio
- _KIT_COM_CALL_S(engine->object,StopEngine);
- //destroy source voices
- unsigned int sources_len=engine->sources_len;
- for(unsigned int i=0; i<sources_len; ++i)
- _KIT_COM_CALL_S(engine->sources[i],DestroyVoice);
- _KIT_COM_CALL_S(engine->master,DestroyVoice);
- //release actual XAudio2 object before deleting mutex and freeing memory
- _KIT_COM_RELEASE_S(engine->object);
- LeaveCriticalSection(&engine->lock); locked=0;
- DeleteCriticalSection(&engine->lock);
- CoTaskMemFree(engine); *engine_p=NULL; //also make sure the pointer is null
- _error_:
- //(should never be true if destroyed successfully)
- if((engine!=NULL) && locked) LeaveCriticalSection(&engine->lock);
- return returnStatus;
- }
- #ifdef __cplusplus
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement