Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "_sfx.hpp"
- int _sfx_auxCallbackHandler(void* data){
- sfx_class* sfx = (sfx_class*)data;
- std::vector<char>* _stream = sfx->_getAuxStream();
- sfx_auxCallback callback = sfx->getAuxCallback();
- void* userdata = sfx->_getAuxUserdata();
- void* _stream_data = (void*)_stream->data();
- int _stream_size = (int)_stream->size();
- callback(userdata, _stream_data, _stream_size);
- return 0;
- }
- //workaround for having _sfx_callback pause the device,
- //without having to call SDL_PauseAudioDevice inside the callback itself
- int _sfx_pauseThread(void* data){
- sfx_class* sfx = (sfx_class*)data;
- if(sfx->isClosing()) return 0;
- sfx->lockDevice(true);
- //might cause problems if sfx is dangling for whatever reason
- try {
- sfx->lock(true);
- } catch(...){
- sfx->lockDevice(false);
- sfx->_getFadeInDelay() = 0xffffffff; //this should work, right?
- return -1;
- }
- //make sure current buffer finishes playing
- float bufferLengthSeconds = (float)sfx->getBufferLength() / sfx->getSampleRate();
- SDL_Delay(bufferLengthSeconds*1000 + 10); //+10ms just to be sure
- SDL_PauseAudioDevice(sfx->getDeviceID(),1);
- sfx->_setPlaying(false);
- sfx->lockDevice(false);
- sfx->lock(false);
- return 0;
- }
- void _sfx_callback(void* userdata, Uint8* _stream, int size){
- sfx_class* sfx = (sfx_class*)userdata;
- sfx_f32s* stream = (sfx_f32s*)_stream;
- int len = size/sizeof(sfx_f32s);
- size_t numTracks = sfx->getNumTracks();
- std::vector<sfx_track>& tracks = sfx->_getTracks();
- Uint64 timeStampEnd = sfx->getTimeStampEnd();
- SDL_Thread* auxCallbackThread = nullptr;
- sfx->_setTimeStampStart();
- SDL_memset(stream,0,size); //stream must be filled no matter what
- if(sfx->isClosing()) goto _skip_everything_; //if device is closing, exit early
- //if previous attempt to pause sfx failed, exit early
- try {
- sfx->lock(true);
- } catch(...){
- sfx->_getFadeInDelay() = 0xffffffff;
- goto _skip_everything_;
- }
- if(sfx->_getFadeInDelay() == 0xffffffff) goto _unlock_device_;
- if(sfx->_getTracksPtr() == nullptr) goto _unlock_device_;
- //start auxillary callback handler thread, if aux callback is present
- if(sfx->getAuxCallback() != nullptr){
- auxCallbackThread = SDL_CreateThread(_sfx_auxCallbackHandler, "auxCH_Th", sfx);
- //if(auxCallbackThread == nullptr) SDL_LogError()
- }
- //mix sound effect tracks
- for(size_t ti=0; ti<numTracks; ++ti){
- if(tracks[ti].pcm != nullptr){
- _sfx_mixTrack(tracks[ti],
- timeStampEnd,
- stream, len);
- }
- }
- //wait for auxCallbackThread to finish
- //(passing auxCallbackThread as nullptr is safe here)
- SDL_WaitThread(auxCallbackThread, nullptr);
- //mix output of auxillary callback, if enabled
- if(auxCallbackThread != nullptr){
- std::vector<char>* auxStream = sfx->_getAuxStream();
- SDL_AudioFormat auxFormat = sfx->getAuxFormat();
- Uint16 auxChannels = sfx->getAuxChannels();
- if(auxStream != nullptr){
- _every_sample_type auxSmp = { .data = auxStream->data() };
- if(( auxStream->size()/((auxFormat&255)/8)/auxChannels ) == (unsigned)len){
- switch(_FORMAT_SWITCH(auxChannels,auxFormat)){ //convert format and data type when mixing
- case fmt_u8 : for(int i=0; i<len; ++i) stream[i] += auxSmp.u8 [i]; break;
- case fmt_i16 : for(int i=0; i<len; ++i) stream[i] += auxSmp.i16 [i]; break;
- case fmt_f32 : for(int i=0; i<len; ++i) stream[i] += auxSmp.f32 [i]; break;
- case fmt_u8s : for(int i=0; i<len; ++i) stream[i] += auxSmp.u8s [i]; break;
- case fmt_i16s: for(int i=0; i<len; ++i) stream[i] += auxSmp.i16s[i]; break;
- case fmt_f32s: for(int i=0; i<len; ++i) stream[i] += auxSmp.f32s[i]; break;
- default: ;//SDL_LogError();
- }
- } //else SDL_LogError();
- } //else SDL_LogError();
- }
- //apply linear fade to reduce popping when pausing and unpausing the device
- //(also apply global volume, hard clipping, and pan)
- _sfx_globalFade(sfx, stream, len);
- _unlock_device_ : try { sfx->lock(false); } catch(...){} //just in case
- _skip_everything_: sfx->_setTimeStampEnd();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement