Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef _KIT_KMIXERVOICEPRIVATE_H
- #define _KIT_KMIXERVOICEPRIVATE_H
- #include "../../include/kit_sdl2/kit_core.h"
- #include "_kit_kmixerPrivate.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- typedef union {
- void* v;
- _mono_samples m;
- _stereo_samples s;
- } _kit_kmixerVoiceBuffer;
- typedef union {
- void* v;
- float* m;
- _stereo_samples_f32* s;
- } _kit_kmixerVoiceBufferF;
- typedef struct _kit_kmixerVoice _kit_kmixerVoice;
- struct _kit_kmixerVoice { //128B
- //(lock is compared with NULL to check if voice is valid)
- SDL_mutex* lock; //to make sure a voice doesn't get deleted while it's processing
- kit_coreVector* inputs; //list of input voice indexes, if any (can be NULL)
- kit_coreVector* inputRefs; //list of input voice references, if any (can be NULL)
- _kit_kmixerVoice* output; //reference to output voice struct
- _kit_kmixerVoiceBufferF bufferInput; //input buffer (aka the mixing stage's output)
- _kit_kmixerVoiceBuffer bufferUser; //buffer to be filled in or modified by the user
- _kit_kmixerVoiceBufferF bufferConvert; //sometimes used for buffer conversion (always stereo size)
- _kit_kmixerVoiceBufferF bufferOutput; //final output buffer (aka a mixing stage input)
- kit_kmixerVoiceSpec spec; //contains info for bufferUser, given by the user
- Uint32 chainStage; //the voice's current position in the processing chain
- Uint32 index; //index of this specific voice in the device's voice list
- //volume can actually be <0, but for volL it will override applyVolume to SDL_FALSE,
- //and for volR, volR would then be set to volL
- float volL; //left ear volume (or total volume if mono); 0.0 -> 1.0
- float volR; //right ear volume (ignored if mono); 0.0 -> 1.0
- SDL_bool applyVolume; //if SDL_TRUE, apply volume when mixing voice's output
- SDL_bool stereoOutput; //output is mono if SDL_FALSE, stereo if SDL_TRUE
- };
- extern int _kit_kmixerVoiceProc(void* data);
- extern void _kit_kmixerVoiceMix(_kit_kmixerVoice* voiceO);
- extern SDL_bool _kit_kmixerDeviceOrdUnitCallback(void* unit, Uint32 size);
- //output voice is locked here
- static inline int _kit_kmixerVoiceRemoveInput(_kit_kmixerVoice* voiceO,
- Uint32 indexI)
- {
- _IF_GOTO_ERROR(SDL_LockMutex(voiceO->lock),;)
- Uint32* oinputs = voiceO->inputs->data;
- _kit_kmixerVoice** oinputRefs = voiceO->inputRefs->data;
- Uint32 oinputs_len = voiceO->inputs->x;
- //remove input from output voice's input list
- for(Uint32 i=0; i<oinputs_len; ++i){
- if(oinputs[i] == indexI){
- oinputs[i] = 0;
- oinputRefs[i] = NULL;
- break;
- }
- }
- //trim input list(s) to make sure only active inputs are included
- _IF_GOTO_ERROR(kit_coreVectorTrim(&voiceO->inputs,'x',NULL),;)
- _IF_GOTO_ERROR(kit_coreVectorTrim(&voiceO->inputRefs,'x',NULL),;)
- if(!voiceO->inputs->lens[0]){ //destroy input(Ref)s if all inputs have been removed
- kit_coreVectorDestroy(&voiceO->inputs);
- kit_coreVectorDestroy(&voiceO->inputRefs);
- }
- _IF_GOTO_ERROR(SDL_UnlockMutex(voiceO->lock),;)
- /*!err*/ return 0;
- _error_: return -1;
- }
- //output is also locked here
- static inline int _kit_kmixerVoiceAddInput(_kit_kmixerVoice* voiceO,
- _kit_kmixerVoice* voiceI)
- {
- _IF_GOTO_ERROR(SDL_LockMutex(voiceO->lock),;)
- if(voiceO->inputs == NULL){ //if inputs == NULL, inputRefs should also be NULL
- voiceO->inputs = kit_coreVectorCreate(1,1,1, sizeof(Uint32),0);
- voiceO->inputRefs = kit_coreVectorCreate(1,1,1, sizeof(_kit_kmixerVoice*),0);
- _IF_GOTO_ERROR(voiceO->inputs==NULL,;)
- _IF_GOTO_ERROR(voiceO->inputRefs==NULL,;)
- }
- //insert the input's index and reference into output
- Uint32 indexI = voiceI->index;
- _IF_GOTO_ERROR(kit_coreVectorInsert(&voiceO->inputs, &indexI, 0,0, NULL)==U32_MAX,;)
- _IF_GOTO_ERROR(kit_coreVectorInsert(&voiceO->inputRefs, &voiceI, 0,0, NULL)==U32_MAX,;)
- _IF_GOTO_ERROR(SDL_UnlockMutex(voiceO->lock),;)
- /*!err*/ return 0;
- _error_: return -1;
- }
- static inline int _kit_kmixerVoiceAddFillSpec(kit_kmixerDevice* device,
- kit_kmixerVoiceSpec* vspec)
- {
- _kit_kmixerVoice* voice0 = device->_voices.raw->data;
- vspec->freq = voice0->spec.freq;
- vspec->samples = voice0->spec.samples;
- vspec->_size = voice0->spec.samples<<vspec->stereo;
- switch(vspec->format){
- case AUDIO_F32: SDL_FALLTHROUGH;
- case AUDIO_S32: vspec->_size *= 2; SDL_FALLTHROUGH;
- case AUDIO_S16: vspec->_size *= 2; SDL_FALLTHROUGH;
- case AUDIO_U8 : break;
- default: _IS_SDLERR(;,"spec's format is invalid"); }
- /*!err*/ return 0;
- _error_: return -1;
- }
- static inline int _kit_kmixerVoiceAddFillVoice(kit_kmixerVoiceSpec* vspec,
- _kit_kmixerVoice* voiceO,
- _kit_kmixerVoice* voiceI)
- {
- kit_coreMemset(voiceI, 0, sizeof(_kit_kmixerVoice));
- Uint32 stereo_f32_size = sizeof(float)*vspec->samples*2;
- Uint32 bufferUser_size = vspec->_size;
- Uint32 bufferOutput_size = (sizeof(float)*vspec->samples)<<voiceO->spec.stereo;
- voiceI->lock = SDL_CreateMutex();
- _IF_GOTO_ERROR(voiceI->lock==NULL,;)
- voiceI->inputs = NULL; //created when the first input is added
- voiceI->inputRefs = NULL;
- voiceI->output = voiceO;
- voiceI->bufferInput.v = SDL_malloc(stereo_f32_size);
- voiceI->bufferUser.v = SDL_malloc(bufferUser_size);
- voiceI->bufferConvert.v = SDL_malloc(stereo_f32_size);
- voiceI->bufferOutput.v = SDL_malloc(bufferOutput_size);
- voiceI->spec = *vspec;
- //set chain processing stage one higher,
- //to ensure this voice is processed before the output
- voiceI->chainStage = voiceO->chainStage+1;
- //(voiceI->index is handled later inside VoiceAdd)
- voiceI->volL = 1.0f;
- voiceI->volR = (voiceI->spec.stereo) ? 1.0f : -1.0f;
- voiceI->applyVolume = SDL_TRUE;
- voiceI->stereoOutput = voiceO->spec.stereo;
- /*!err*/ return 0;
- _error_: return -1;
- }
- static inline void _kit_kmixerVoiceRemoveFromOrd(kit_kmixerDevice* device,
- _kit_kmixerVoice* voiceI)
- {
- kit_coreVector** ord_p = &device->_voices.ord;
- Uint32 index = voiceI->index;
- Uint32 chainStage = voiceI->chainStage;
- _kit_kmixerVoice** chainRefs = &VECTOR_INDEX_A(_kit_kmixerVoice*, *ord_p, 0,chainStage,0);
- Uint32 stageLen = VECTOR_LENS_A(*ord_p, chainStage,0);
- //do a linear search through the voice's chain stage...
- for(Uint32 i=0; i<stageLen; ++i){
- if(chainRefs[i]->index == index){
- chainRefs[i] = NULL; //...setting the reference to NULL if found
- break;
- }
- }
- }
- static inline int _kit_kmixerVoiceAddToOrd(kit_kmixerDevice* device,
- _kit_kmixerVoice* voiceI)
- {
- Uint32 chainStage = voiceI->chainStage;
- kit_coreVector** ord_p = &device->_voices.ord;
- if(chainStage >= (*ord_p)->y){ //extend ord to accomodate new chain stage
- _IF_GOTO_ERROR(kit_coreVectorSet(ord_p, 0,chainStage+1,0),;)
- }
- _IF_GOTO_ERROR(kit_coreVectorInsert(ord_p, &voiceI, chainStage,0,
- _kit_kmixerDeviceOrdUnitCallback)==U32_MAX,;)
- /*!err*/ return 0;
- _error_: return -1;
- }
- #ifdef __cplusplus
- }
- #endif
- #endif /* _KIT_KMIXERVOICEPRIVATE_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement