Advertisement
Kitomas

_kit_kmixerDevicePrivate.h as of 2023-10-05

Oct 6th, 2023
1,436
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.65 KB | None | 0 0
  1. #ifndef _KIT_KMIXERDEVICEPRIVATE_H
  2. #define _KIT_KMIXERDEVICEPRIVATE_H
  3.  
  4.  
  5. #include "../../include/kit_sdl2/kit_kmixer.h"
  6. #include "_kit_privmacro.h"
  7. #include "_kit_kmixerVoicePrivate.h"
  8.  
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12.  
  13.  
  14.  
  15.  
  16. #define _DEV_MAGIC_NUM (0x0076654472786D6B) //="kmxrDev\x00"
  17. #define _CHECK_IF_DEVICE_IS_VALID_R(_value) \
  18.   _IF_SDLERR_R(device->_magic.num!=_DEV_MAGIC_NUM, \
  19.                _value,;,"device is invalid")
  20.  
  21.  
  22.  
  23. //minimum amplitude needed to halt a fade in/out (0.0 -> 1.0)
  24. #define fadeCutoff 0.0002
  25.  
  26.  
  27.  
  28.  
  29. extern int _kit_kmixerDevicePauseThread(void* data);
  30.  
  31. extern void _kit_kmixerDeviceCallback(void* userdata, Uint8* _stream, int len);
  32.  
  33.  
  34.  
  35.  
  36. //assumes device is already locked
  37. static inline void _kit_kmixerDeviceStereoFade(kit_kmixerDevice* device,
  38.                                                _stereo_samples_f32* stream,
  39.                                                int len)
  40. {
  41.   //get values from voice 0
  42.   _kit_kmixerVoice* voice0 = device->_voices.raw->data;
  43.   float volL = (voice0->volL >= 0) ? voice0->volL : 1.0f;
  44.   float volR = (voice0->volR >= 0) ? voice0->volR : volL;
  45.  
  46.   //get values from device itself
  47.   float fadeMultiplier = device->_fadeMultiplier;
  48.   float fadeVolume     = device->_fadeVolume;
  49.   Uint32 fadeInDelay   = device->_fadeInDelay;
  50.  
  51.   Uint32 i = 0; //this index is shared, as the loops can jump to others at will
  52.  
  53.  
  54.   //FADING OUT
  55.   if(device->_fadeOut){
  56.     _do_fade_out_stereo: //kit_coreLog("stereo fade out");
  57.     for(; i<len; ++i){
  58.       if(!device->_fadeOut){ fadeVolume = 1-fadeVolume; goto _do_fade_in_stereo; }
  59.       stream[i].l *= fadeVolume*volL;
  60.       stream[i].r *= fadeVolume*volR;
  61.       fadeVolume *= fadeMultiplier;
  62.     }
  63.     if(fadeVolume<fadeCutoff){
  64.       SDL_Thread* pauseThread = SDL_CreateThread(_kit_kmixerDevicePauseThread,"_PauseTh", device);
  65.       //setting _fadeInDelay to -1 will make further calls to the device callback
  66.        //to simply memset 0 until kit_kmixerDevicePlay is called again
  67.       if(pauseThread == NULL) device->_fadeInDelay = -1; //0xffffffff
  68.       else SDL_DetachThread(pauseThread); //make sure thread cleans up when finished
  69.     }
  70.   //NORMAL; JUST APPLY VOLUME
  71.   } else if(!fadeInDelay){
  72.     _do_normal_stereo: //kit_coreLog("stereo normal");
  73.     for(; i<len; ++i){
  74.       if(device->_fadeOut){ goto _do_fade_out_stereo; }
  75.       stream[i].l *= volL;
  76.       stream[i].r *= volR;
  77.     }
  78.   //FADING IN
  79.   } else { //let device warm up before fading in
  80.     for(; (fadeInDelay)&&(i<len); ++i){ //write 0s for fadeInDelaySeconds
  81.       stream[i].l=stream[i].r = 0; --fadeInDelay;
  82.     }
  83.     _do_fade_in_stereo: //kit_coreLog("stereo fade in");
  84.     for(; i<len; ++i){
  85.       if(device->_fadeOut){ fadeVolume = 1-fadeVolume; goto _do_fade_out_stereo; }
  86.       else if(fadeVolume < fadeCutoff){ fadeVolume = 1; goto _do_normal_stereo; }
  87.       stream[i].l *= (1-fadeVolume)*volL;
  88.       stream[i].r *= (1-fadeVolume)*volR;
  89.       fadeVolume *= fadeMultiplier;
  90.     }
  91.  
  92.   }
  93.  
  94.  
  95.   //update device struct to any relevant new values
  96.   device->_fadeVolume  = fadeVolume;  //update fade volume
  97.   device->_fadeInDelay = fadeInDelay; //update fade in delay
  98. }
  99.  
  100.  
  101.  
  102. //also assumes device is already locked
  103. static inline void _kit_kmixerDeviceMonoFade(kit_kmixerDevice* device,
  104.                                              float* stream, int len)
  105. {
  106.   //get values from voice 0
  107.   _kit_kmixerVoice* voice0 = device->_voices.raw->data;
  108.   float volL = (voice0->volL >= 0) ? voice0->volL : 1.0f;
  109.   //float volR = (voice0->volR >= 0) ? voice0->volR : volL; (not used for mono)
  110.  
  111.   //get values from device itself
  112.   float fadeMultiplier = device->_fadeMultiplier;
  113.   float fadeVolume     = device->_fadeVolume;
  114.   Uint32 fadeInDelay   = device->_fadeInDelay;
  115.  
  116.   Uint32 i = 0; //this index is shared, as the loops can jump to others at will
  117.  
  118.  
  119.   if(device->_fadeOut){
  120.     _do_fade_out_mono: //SDL_Log("fade out mono");
  121.     for(; i<len; ++i){
  122.       if(!device->_fadeOut){ fadeVolume = 1-fadeVolume; goto _do_fade_in_mono; }
  123.       stream[i] *= fadeVolume*volL;
  124.       fadeVolume *= fadeMultiplier;
  125.     }
  126.     if(fadeVolume < fadeCutoff){
  127.       SDL_Thread* pauseThread = SDL_CreateThread(_kit_kmixerDevicePauseThread,"_PauseTh", device);
  128.       if(pauseThread==NULL) device->_fadeInDelay = -1; //0xffffffff
  129.       else SDL_DetachThread(pauseThread); //make sure thread cleans up when finished
  130.     }
  131.  
  132.   } else if(!fadeInDelay){
  133.     _do_normal_mono: //SDL_Log("normal mono");
  134.     for(; i<len; ++i){
  135.       if(device->_fadeOut){ goto _do_fade_out_mono; }
  136.       stream[i] *= volL;
  137.     }
  138.  
  139.   } else { //let device warm up before fading in
  140.     for(; (fadeInDelay)&&(i<len); ++i){ //write 0s for fadeInDelaySeconds
  141.       stream[i] = 0; --fadeInDelay;
  142.     }
  143.     _do_fade_in_mono: //SDL_Log("fade in mono");
  144.     for(; i<len; ++i){
  145.       if(device->_fadeOut){ fadeVolume = 1-fadeVolume; goto _do_fade_out_mono; }
  146.       else if(fadeVolume < fadeCutoff){ fadeVolume = 1; goto _do_normal_mono; }
  147.       stream[i] *= (1-fadeVolume)*volL;
  148.       fadeVolume *= fadeMultiplier;
  149.     }
  150.  
  151.   }
  152.  
  153.  
  154.   //update device struct to any relevant new values
  155.   device->_fadeVolume  = fadeVolume;  //update fade volume
  156.   device->_fadeInDelay = fadeInDelay; //update fade in delay
  157. }
  158.  
  159.  
  160.  
  161.  
  162. static inline SDL_AudioSpec _kit_kmixerDeviceVoiceToAudioSpec(kit_kmixerDevice* device,
  163.                                                               const kit_kmixerVoiceSpec* vspec)
  164. {
  165.   SDL_AudioSpec aspec;
  166.   SDL_bool success = SDL_FALSE;
  167.  
  168.   aspec.freq     = vspec->freq;
  169.   aspec.format   = AUDIO_F32;
  170.   aspec.channels = 1+(vspec->stereo&1);
  171.   aspec.samples  = vspec->samples;
  172.   aspec.callback = _kit_kmixerDeviceCallback;
  173.   aspec.userdata = device;
  174.  
  175.   //assuming 44.1kHz, <=16 sample frames would be well under 1ms lol
  176.    //(even at 8kHz, it would still only be 2ms)
  177.   _IF_SDLERR(aspec.samples<32,;,"samples < 32")
  178.   _IF_SDLERR(count_bits(aspec.samples)>1,;,"samples not a power of 2")
  179.  
  180.   success = SDL_TRUE;
  181.   _error_:
  182.   if(!success) aspec.format = 0; //used to check for failure inside DeviceOpen
  183.   return aspec;
  184. }
  185.  
  186.  
  187.  
  188.  
  189. static inline int _kit_kmixerDeviceFillVoice0(kit_kmixerDevice* device,
  190.                                               kit_kmixerVoiceSpec* vspec)
  191. {
  192.   _kit_kmixerVoice* raw = device->_voices.raw->data;
  193.   SDL_bool stereo = vspec->stereo&1;
  194.   Uint32 bufferSize = (sizeof(float)*vspec->samples)<<stereo;
  195.  
  196.  
  197.   raw->lock=SDL_CreateMutex();
  198.   if(raw->lock==NULL) return -1; //_IF_GOTO_ERROR isn't really necessary here
  199.  
  200.   raw->inputs    = NULL; //created when a voice gets added
  201.   raw->inputRefs = NULL; //also created when a voice gets added
  202.   raw->output    = NULL; //unused for voice 0
  203.  
  204.    //(voice 0's bufferInput is copied to device callback's _stream)
  205.   raw->bufferInput.v   = SDL_malloc(bufferSize);
  206.   raw->bufferUser.v    = NULL; //unused for voice 0
  207.   raw->bufferConvert.v = NULL; //unused for voice 0
  208.   raw->bufferOutput.v  = NULL; //unused for voice 0
  209.   _IF_SDLERR_R(raw->bufferInput.v==NULL,-1,;,"!voice 0 bufferInput")
  210.  
  211.  
  212.   //copy voice spec info
  213.   raw->spec        = *vspec;
  214.    //(these two members are exceptions)
  215.   raw->spec._size  = bufferSize;
  216.   raw->spec.format = AUDIO_F32;
  217.  
  218.  
  219.   raw->chainStage = 0;
  220.   raw->index      = 0;
  221.  
  222.   raw->volL = 1.0f;
  223.   raw->volR = (stereo) ? 1.0f : -1.0f;
  224.  
  225.   raw->applyVolume  = SDL_TRUE;
  226.   raw->stereoOutput = stereo;
  227.  
  228.  
  229.   //copy reference of voice 0 to ord
  230.   _kit_kmixerVoice* voice0_reference = &raw[0];
  231.   Uint32 newIndex = kit_coreVectorAppend(&device->_voices.ord, &voice0_reference, 0,0);
  232.   _IF_SDLERR_R(newIndex==U32_MAX,-1,;,"!append")
  233.  
  234.  
  235.   return 0;
  236. }
  237.  
  238.  
  239.  
  240.  
  241. #ifdef __cplusplus
  242. }
  243. #endif
  244.  
  245. #endif /* _KIT_KMIXERDEVICEPRIVATE_H */
  246.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement