Advertisement
Kitomas

_kit_w32_audioX2.cpp

Jul 21st, 2023
805
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.77 KB | Source Code | 0 0
  1. //link kernel32, Ole32, and xaudio2 to use
  2. #include <_kit_w32_audioX2.h>
  3.  
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7.  
  8. #include <stdio.h>
  9.  
  10. //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//
  11.  
  12. HRESULT _kit_audioX2_CreateVoice(_kit_audioX2_Engine* engine, const WAVEFORMATEX* source_format, unsigned int* index_p){
  13.   HRESULT returnStatus=S_OK; int locked=0, slot=-1;
  14.   _IF_ERROR(engine==NULL,E_INVALIDARG,;);
  15.   _IF_ERROR(source_format==NULL,E_INVALIDARG,;);
  16.   _IF_ERROR(index_p==NULL,E_INVALIDARG,;);
  17.   EnterCriticalSection(&engine->lock); locked=1;
  18.  
  19.   //if no voices have been added, then allocate space for first pointer
  20.   if(!engine->sources_len){
  21.     engine->sources=(IXAudio2SourceVoice**)CoTaskMemRealloc(engine->sources, sizeof(IXAudio2SourceVoice*));
  22.     _IF_ERROR(engine->sources==NULL,E_OUTOFMEMORY,;);
  23.     engine->sources[0]=NULL;
  24.     engine->sources_len=1;
  25.   }
  26.  
  27.   //try to find first free space
  28.   unsigned int sources_len=engine->sources_len;
  29.   for(unsigned int i=0; i<sources_len; ++i){
  30.     if(engine->sources[i]==NULL){
  31.       returnStatus=engine->object->CreateSourceVoice(&engine->sources[i], source_format);
  32.       _IF_GOTO_ERROR(FAILED(returnStatus),;);
  33.       slot=i; break;
  34.     }
  35.   }
  36.  
  37.   //if no free space was found, append new voice to source voice list
  38.   if(slot == -1){
  39.     engine->sources=(IXAudio2SourceVoice**)CoTaskMemRealloc(engine->sources, sources_len*sizeof(IXAudio2SourceVoice*));
  40.     _IF_ERROR(engine->sources==NULL,E_OUTOFMEMORY,;);
  41.     returnStatus=engine->object->CreateSourceVoice(&engine->sources[sources_len], source_format);
  42.     _IF_GOTO_ERROR(FAILED(returnStatus),;);
  43.     slot=engine->sources_len++;
  44.   }
  45.  
  46.   _error_:
  47.   if((engine!=NULL) && locked) LeaveCriticalSection(&engine->lock);
  48.   if(slot != -1) *index_p=slot;
  49.   return returnStatus;
  50. }
  51.  
  52.  
  53. HRESULT _kit_audioX2_DestroyVoice(_kit_audioX2_Engine* engine, unsigned int index){
  54.   HRESULT returnStatus=S_OK; int locked=0;
  55.   _IF_ERROR(engine==NULL,E_INVALIDARG,;);
  56.   EnterCriticalSection(&engine->lock); locked=1;
  57.   _IF_ERROR(index>=engine->sources_len,E_INVALIDARG,;);
  58.   _IF_GOTO_ERROR(engine->sources[index]==NULL,;); //returnStatus=S_OK here
  59.  
  60.   //destroy source voice at index
  61.   engine->sources[index]->DestroyVoice();
  62.  
  63.   //reallocate if index was the last element
  64.   unsigned int last_source=engine->sources_len-1;
  65.   if(index==last_source && last_source!=0){
  66.     engine->sources=(IXAudio2SourceVoice**)CoTaskMemRealloc(engine->sources, last_source*sizeof(IXAudio2SourceVoice*));
  67.     _IF_ERROR(engine->sources==NULL,E_OUTOFMEMORY,;);
  68.     --engine->sources_len;
  69.   } else engine->sources[index]=NULL;
  70.  
  71.   _error_:
  72.   if((engine!=NULL) && locked) LeaveCriticalSection(&engine->lock);
  73.   return returnStatus;
  74. }
  75.  
  76.  
  77.  
  78. //--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//--//
  79.  
  80. HRESULT _kit_audioX2_CreateEngine(_kit_audioX2_Engine** engine_p,
  81.                                   const WAVEFORMATEX* source_format,
  82.                                   const wchar_t* deviceID){
  83.   HRESULT returnStatus=S_OK; ULONG numRefs=1; int critical_section=0;
  84.   _kit_audioX2_Engine* engine=NULL;
  85.   _IF_ERROR(engine_p==NULL,E_INVALIDARG,;);
  86.   _IF_ERROR(source_format==NULL,E_INVALIDARG,;);
  87.  
  88.   //allocate memory for struct
  89.   engine=(_kit_audioX2_Engine*)CoTaskMemAlloc(sizeof(_kit_audioX2_Engine));
  90.   _IF_ERROR(engine==NULL,E_OUTOFMEMORY,;);
  91.   for(char i=0,*ch_p=(char*)engine; i<sizeof(_kit_audioX2_Engine); ++i) ch_p[i]=0;
  92.  
  93.   //initialize mutex
  94.   InitializeCriticalSection(&engine->lock); critical_section=1;
  95.  
  96.   //create xaudio2 object
  97.   returnStatus=XAudio2Create(&engine->object, 0, XAUDIO2_DEFAULT_PROCESSOR);
  98.   _IF_GOTO_ERROR(FAILED(returnStatus),;);
  99.  
  100.   //create mastering voice
  101.   LPWSTR _deviceID=(LPWSTR)deviceID;
  102.   returnStatus=engine->object->CreateMasteringVoice(&engine->master,
  103.                                                     XAUDIO2_DEFAULT_CHANNELS,
  104.                                                     XAUDIO2_DEFAULT_SAMPLERATE,0,
  105.                                                     _deviceID);
  106.   _IF_GOTO_ERROR(FAILED(returnStatus),;);
  107.  
  108.   //create the first source voice
  109.   unsigned int slot;
  110.   returnStatus=_kit_audioX2_CreateVoice(engine, source_format, &slot);
  111.   _IF_GOTO_ERROR(FAILED(returnStatus),;);
  112.  
  113.   _error_:
  114.   if(SUCCEEDED(returnStatus)) *engine_p=engine;
  115.   else if(engine != NULL){
  116.     if(engine->sources != NULL){
  117.       _KIT_COM_CALL_S(engine->sources[slot],DestroyVoice);
  118.       CoTaskMemFree(engine->sources);
  119.     }
  120.     _KIT_COM_CALL_S(engine->master,DestroyVoice);
  121.     _KIT_COM_RELEASE_S(engine->object);
  122.     if(critical_section) DeleteCriticalSection(&engine->lock);
  123.     CoTaskMemFree(engine); engine=NULL;
  124.   }
  125.   return returnStatus;
  126. }
  127.  
  128.  
  129. HRESULT _kit_audioX2_DestroyEngine(_kit_audioX2_Engine** engine_p){
  130.   HRESULT returnStatus=S_OK; ULONG numRefs=1; int locked=0;
  131.  
  132.   _kit_audioX2_Engine* engine=NULL;
  133.   _IF_ERROR(engine_p==NULL,E_INVALIDARG,;);
  134.   _IF_ERROR((engine=*engine_p)==NULL,E_INVALIDARG,;);
  135.   EnterCriticalSection(&engine->lock); locked=1;
  136.  
  137.   //halt audio
  138.   _KIT_COM_CALL_S(engine->object,StopEngine);
  139.  
  140.   //destroy source voices
  141.   unsigned int sources_len=engine->sources_len;
  142.   for(unsigned int i=0; i<sources_len; ++i)
  143.     _KIT_COM_CALL_S(engine->sources[i],DestroyVoice);
  144.  
  145.   _KIT_COM_CALL_S(engine->master,DestroyVoice);
  146.  
  147.   //release actual XAudio2 object before deleting mutex and freeing memory
  148.   _KIT_COM_RELEASE_S(engine->object);
  149.   LeaveCriticalSection(&engine->lock); locked=0;
  150.   DeleteCriticalSection(&engine->lock);
  151.   CoTaskMemFree(engine); *engine_p=NULL; //also make sure the pointer is null
  152.  
  153.   _error_:
  154.    //(should never be true if destroyed successfully)
  155.   if((engine!=NULL) && locked) LeaveCriticalSection(&engine->lock);
  156.   return returnStatus;
  157. }
  158.  
  159.  
  160.  
  161. #ifdef __cplusplus
  162. }
  163. #endif
  164.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement