Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "../include/kit_sdl2/kit_kmixer.h"
- #include "../_private/include/_kit_privmacro.h"
- #include "../_private/include/_kit_kmixerPrivate.h"
- //include intrinsic functions
- #include <immintrin.h>
- //for debug testing
- #define _ENABLE_SSE SDL_TRUE
- #define _ENABLE_SSE2 SDL_TRUE
- #define _ENABLE_SSE3 SDL_TRUE
- #define _ENABLE_SSE41 SDL_TRUE
- #define _ENABLE_AVX SDL_TRUE
- #define _ENABLE_AVX2 SDL_TRUE
- //bitmasks for _kit_kmixerGlobals.capabilities
- #define _SSE_MASK (1<<5)
- #define _SSE2_MASK (1<<4)
- #define _SSE3_MASK (1<<3)
- #define _SSE41_MASK (1<<2) //(SSE4.1)
- #define _AVX_MASK (1<<1)
- #define _AVX2_MASK (1<<0)
- //for visual clarity during ProcChannels
- //(this could also just be an enum probably, but w/e)
- #define _M_to_M (0) // mono->mono
- #define _M_to_S (1) // mono->stereo
- #define _S_to_M (2) //stereo->mono
- #define _S_to_S (3) //stereo->stereo
- #define _MM256_SHUFFLE(c7,c6,c5,c4,c3,c2,c1,c0) \
- ((_MM_SHUFFLE(c7,c6,c5,c4)<<8)|_MM_SHUFFLE(c3,c2,c1,c0))
- #define _MN(a,b) ( ((a)<(b))?(a):(b) )
- #define _MX(a,b) ( ((a)>(b))?(a):(b) )
- #define _CLMP(n, m,x) _MN(_MX(n, m),x)
- //used to multiply an int by the inverse of an int to get a normalized float
- //(input 8-bit samples will be unsigned, so +=0x80 to convert them to signed first)
- const float invi_8=1.0f/0x7f; //=0.007874015748031496062992125984251968503937
- const float invi16=1.0f/0x7fff; //=0.000030518509475997192297128208258308664204
- const float invi32=1.0f/0x7fffffff; //=0.000000000465661287524579692410575082716799
- //converts u8, i16, and i32 samples to f32 samples
- static inline void _kit_kmixerVoiceProcFromTypeFallback(void* _dataIn, float* dataOut,
- Uint32 numSamples, SDL_AudioFormat typeIn)
- { //if nothing else works
- _mono_samples dataIn={.ptr=_dataIn};
- float rawSample; //used for max(original_sample,-1) basically
- switch(typeIn){
- case AUDIO_U8 : for(Uint32 i=0; i<numSamples; ++i){ rawSample=(float)(dataIn.u_8[i]-0x80)*invi_8;
- dataOut[i]=(rawSample>=-1.0f)?rawSample:-1.0f; } break;
- case AUDIO_S16: for(Uint32 i=0; i<numSamples; ++i){ rawSample=(float) dataIn.i16[i] *invi16;
- dataOut[i]=(rawSample>=-1.0f)?rawSample:-1.0f; } break;
- case AUDIO_S32: for(Uint32 i=0; i<numSamples; ++i){ rawSample=(float) dataIn.i32[i] *invi32;
- dataOut[i]=(rawSample>=-1.0f)?rawSample:-1.0f; } break;
- case AUDIO_F32: for(Uint32 i=0; i<numSamples; ++i){ dataOut[i]= dataIn.f32[i]; } }
- }
- void _kit_kmixerVoiceProcFromType(void* dataIn, void* dataOut,
- Uint32 sampleFrames, SDL_AudioFormat typeIn, SDL_bool isStereo)
- {
- Uint32 numSamples=sampleFrames<<isStereo;
- _kit_kmixerVoiceProcFromTypeFallback(dataIn,dataOut,numSamples,typeIn);
- }
- //converts f32 samples to u8, i16, and i32 samples
- static inline void _kmixerVoiceProcToTypeFallback(float* dataIn, void* _dataOut,
- Uint32 numSamples, SDL_AudioFormat typeOut)
- { //if nothing else works
- _mono_samples dataOut={.ptr=_dataOut};
- float rawSample, rawSampleB;
- switch(typeOut){
- case AUDIO_U8 : for(Uint32 i=0; i<numSamples; ++i){ rawSample =dataIn[i];
- rawSampleB =(rawSample>=-1.0f)?rawSample:-1.0f;
- dataOut.u_8[i]=(rawSampleB<=1.0f)?rawSampleB*0x7f+0x80:0x7f; } break;
- case AUDIO_S16: for(Uint32 i=0; i<numSamples; ++i){ rawSample =dataIn[i];
- rawSampleB =(rawSample>=-1.0f)?rawSample:-1.0f;
- dataOut.i16[i]=(rawSampleB<=1.0f)?rawSampleB*0x7fff:0x7fff; } break;
- case AUDIO_S32: for(Uint32 i=0; i<numSamples; ++i){ rawSample =dataIn[i];
- rawSampleB =(rawSample>=-1.0f)?rawSample:-1.0f;
- dataOut.i32[i]=(rawSampleB<=1.0f)?rawSampleB*0x7fffffff:0x7fffffff; } break;
- case AUDIO_F32: for(Uint32 i=0; i<numSamples; ++i){ rawSample =dataIn[i];
- rawSampleB =(rawSample>=-1.0f)?rawSample:-1.0f;
- dataOut.f32[i]=(rawSampleB<=1.0f)?rawSampleB:1.0f; } }
- }
- void _kit_kmixerVoiceProcToType(void* dataIn, void* dataOut,
- Uint32 sampleFrames, SDL_AudioFormat typeOut, SDL_bool isStereo)
- {
- Uint32 numSamples=sampleFrames<<isStereo;
- _kmixerVoiceProcToTypeFallback(dataIn,dataOut,numSamples,typeOut);
- }
- //assumes samples are f32
- static inline void _kit_kmixerVoiceProcChannelsFallback(float* dataInM, float* dataOutM,
- Uint32 sampleFrames, int channelInfo)
- { //if nothing else works
- _stereo_samples_f32* dataInS =(void*)dataInM;
- _stereo_samples_f32* dataOutS=(void*)dataOutM;
- switch(channelInfo){
- case _M_to_S: for(Uint32 i=0; i<sampleFrames; ++i){ dataOutS[i].l=dataOutS[i].r=dataInM[i]; } break;
- case _S_to_M: for(Uint32 i=0; i<sampleFrames; ++i){ dataOutM[i]=(dataInS[i].l+dataInS[i].r)*.5f; } break;
- case _S_to_S: sampleFrames<<=1; SDL_FALLTHROUGH; //multiply mono by 2 to make length of stereo
- case _M_to_M: for(Uint32 i=0; i<sampleFrames; ++i){ dataOutM[i]=dataInM[i]; }
- }
- }
- void _kit_kmixerVoiceProcChannels(void* dataIn, void* dataOut, Uint32 sampleFrames, int channelInfo){
- _kit_kmixerVoiceProcChannelsFallback(dataIn,dataOut, sampleFrames,channelInfo);
- }
- //assumes samples are f32
- void _kit_kmixerVoiceProcCopy(void* dataIn, void* dataOut, Uint32 sampleFrames, int isStereo){
- SDL_memcpy(dataOut,dataIn, (sampleFrames*sizeof(float))<<isStereo);
- }
- #define _CH_INFO(a,b) (((a)<<1)|(b))
- //assumes input AND output samples are f32 (intermediate type is determined by the given voice)
- int _kit_kmixerVoiceProc(void* data){ //(this is an SDL_ThreadFunction)
- _kit_kmixerVoice* voice=data;
- SDL_LockMutex(voice->lock);
- void *ibuffer=voice->bufferInput.v, *ubuffer=voice->bufferUser.v, *obuffer=voice->bufferOutput.v;
- void *tbuffer=voice->bufferType.v, *cbuffer=voice->bufferChannel.v;
- void *userdata=voice->userdata, *_stream=ubuffer;
- //
- SDL_bool istereo=voice->stereoInput, ustereo=voice->stereoUser, ostereo=voice->stereoOutput;
- SDL_bool hasInput = voice->inputs!=NULL;
- //
- SDL_AudioFormat ifmt=voice->formatInput, ufmt=voice->formatUser, ofmt=voice->formatOutput;
- //
- Uint32 frames=voice->sampleFrames, ubuffer_size=voice->bufferUser_size;
- //convert input type & channels (if necessary) before calling the kit_kmixerVoiceCallback
- int sameChannels = (istereo==ustereo)<<4; //shift left by 1 nybble for case readability
- int sameType = ifmt==ufmt;
- SDL_bool skipUserBuffer = sameChannels&&sameType;
- switch(sameChannels|sameType){
- case 0x00: //convert channels and type before callback
- //(will change this if i add in the ability to do channel conversion on non-floats)
- SDL_FALLTHROUGH;
- case 0x01: //only convert channels before callback
- if(ufmt!=AUDIO_F32){
- _kit_kmixerVoiceProcChannels(ibuffer,cbuffer, frames,_CH_INFO(istereo,ustereo));
- _kit_kmixerVoiceProcToType(cbuffer,ubuffer, frames,ufmt,ustereo);
- } else _kit_kmixerVoiceProcChannels(ibuffer,ubuffer, frames,_CH_INFO(istereo,ustereo));
- goto voice_callback_case;
- case 0x10: //only convert type before callback
- _kit_kmixerVoiceProcToType(ibuffer, ubuffer, frames,ufmt,istereo);
- SDL_FALLTHROUGH; //goto voice_callback_case;
- case 0x11: voice_callback_case: //feed input directly to callback
- if(skipUserBuffer) _stream=ibuffer; //will only be true on case 0x11
- voice->callback(userdata, _stream, ubuffer_size, hasInput);
- }
- //convert user type & channels (if necessary), outputting to bufferOutput
- sameChannels = (ustereo==ostereo)<<4; //shift left by 1 nybble for case readability
- sameType = ufmt==ofmt;
- switch(sameChannels|sameType){
- case 0x00: //convert channels & type
- //(will change this if i add in the ability to do channel conversion on non-floats)
- SDL_FALLTHROUGH;
- case 0x01: //convert channels
- if(ufmt!=AUDIO_F32){
- _kit_kmixerVoiceProcFromType(_stream,tbuffer, frames,ufmt,ustereo);
- _kit_kmixerVoiceProcChannels(tbuffer,obuffer, frames,_CH_INFO(ustereo,ostereo));
- } else _kit_kmixerVoiceProcChannels(_stream,obuffer, frames,_CH_INFO(ustereo,ostereo));
- break;
- case 0x10: //convert type
- _kit_kmixerVoiceProcFromType(_stream,tbuffer, frames,ufmt,ustereo);
- _kit_kmixerVoiceProcToType(tbuffer,obuffer, frames,ofmt,ostereo);
- break;
- case 0x11: //just copy contents of _stream to output
- _kit_kmixerVoiceProcCopy(_stream, obuffer, frames, ostereo);
- }
- SDL_UnlockMutex(voice->lock);
- return 0;
- }
- //assumes all samples are f32
- static inline void _kit_kmixerVoiceMixFallback(_kit_kmixerVoice* ovoice,
- _kit_kmixerVoice* ivoices, Uint32 ivoices_len)
- { //if nothing else works
- Uint32 frames=ovoice->sampleFrames;
- memset(ovoice->bufferInput.v, 0, (frames*sizeof(float))<<ovoice->stereoInput);
- _stereo_samples_f32* osamples=ovoice->bufferInput.s;
- Uint32 samples_len=frames>>(!ovoice->stereoInput);
- //do the mixing
- for(Uint32 vi=0; vi<ivoices_len; ++vi){
- _kit_kmixerVoice* ivoice=&ivoices[vi];
- _stereo_samples_f32* isamples=ivoice->bufferOutput.s;
- float volL=ivoice->volL, volR=ivoice->volR;
- volL=_MN(volL,1.0f); volR=_MN(volR, 1.0f);
- if(!ivoice->stereoOutput) volR=volL;
- if(volL==0 && volR==0) continue; //if volume is effectively muted, then skip the voice
- else if(volL==1.0f && volR==1.0f) goto _do_not_apply_volume;
- else if((volL>=0)&&ivoice->applyVolume){
- if(volR<0) volR=volL;
- for(Uint32 i=0; i<samples_len; ++i){
- osamples[i].l += isamples[i].l*volL;
- osamples[i].r += isamples[i].r*volR;
- }
- } else { _do_not_apply_volume:
- for(Uint32 i=0; i<samples_len; ++i){
- osamples[i].l += isamples[i].l;
- osamples[i].r += isamples[i].r;
- }
- }
- }
- //hard clip output samples to between -1.0f and 1.0f
- for(Uint32 i=0; i<samples_len; ++i){
- float sampleL=osamples[i].l;
- osamples[i].l=_CLMP(sampleL, -1.0f,1.0f);
- float sampleR=osamples[i].r;
- osamples[i].r=_CLMP(sampleR, -1.0f,1.0f);
- }
- }
- void _kit_kmixerVoiceMix(_kit_kmixerVoice* ovoice,
- _kit_kmixerVoice* ivoices, Uint32 ivoices_len)
- {
- _kit_kmixerVoiceMixFallback(ovoice, ivoices,ivoices_len);
- }
- #ifdef _KIT_KMIXER_DEBUG
- extern int printf(const char*,...);
- void _kit_kmixerVoiceTestCallback(void* userdata, void* _stream, int size, SDL_bool hasInput){
- }
- #define _F32_EQUAL(a,b) ( (a)>((b)-0.000001) && (a)<((b)+0.000001) )
- int kit_kmixerVoiceTest(){
- float bufferInputA[16], bufferTypeA[16], bufferChannelA[16], bufferUserA[16], bufferOutputA[16];
- float bufferInputB[16], bufferTypeB[16], bufferChannelB[16], bufferUserB[16], bufferOutputB[16];
- float bufferInputC[16], bufferTypeC[16], bufferChannelC[16], bufferUserC[16], bufferOutputC[16];
- _kit_kmixerVoice voiceA={
- .bufferInput = { .v=bufferInputA },
- .bufferType = { .v=bufferTypeA },
- .bufferChannel = { .v=bufferChannelA },
- .bufferUser = { .v=bufferUserA },
- .bufferOutput = { .v=bufferOutputA },
- .lock = NULL,
- .callback = _kit_kmixerVoiceTestCallback,
- .userdata = NULL,
- .inputs = NULL,
- .index = 0,
- .sampleRate = 44100,
- .bufferUser_size = 16*sizeof(float),
- .volL = 1.0f,
- .volR = 1.0f,
- .applyVolume = SDL_TRUE,
- .stereoInput = SDL_FALSE,
- .stereoUser = SDL_FALSE,
- .stereoOutput = SDL_FALSE,
- .sampleFrames = 16,
- .formatInput = AUDIO_F32,
- .formatUser = AUDIO_F32,
- .formatOutput = AUDIO_F32
- };
- _kit_kmixerVoice voiceB={
- .bufferInput = { .v=bufferInputB },
- .bufferType = { .v=bufferTypeB },
- .bufferChannel = { .v=bufferChannelB },
- .bufferUser = { .v=bufferUserB },
- .bufferOutput = { .v=bufferOutputB },
- .lock = NULL,
- .callback = _kit_kmixerVoiceTestCallback,
- .userdata = NULL,
- .inputs = NULL,
- .index = 0,
- .sampleRate = 44100,
- .bufferUser_size = 16*sizeof(float),
- .volL = 1.0f,
- .volR = 1.0f,
- .applyVolume = SDL_TRUE,
- .stereoInput = SDL_FALSE,
- .stereoUser = SDL_FALSE,
- .stereoOutput = SDL_FALSE,
- .sampleFrames = 16,
- .formatInput = AUDIO_F32,
- .formatUser = AUDIO_F32,
- .formatOutput = AUDIO_F32
- };
- _kit_kmixerVoice voiceC={
- .bufferInput = { .v=bufferInputC },
- .bufferType = { .v=bufferTypeC },
- .bufferChannel = { .v=bufferChannelC },
- .bufferUser = { .v=bufferUserC },
- .bufferOutput = { .v=bufferOutputC },
- .lock = NULL,
- .callback = _kit_kmixerVoiceTestCallback,
- .userdata = NULL,
- .inputs = NULL,
- .index = 2,
- .sampleRate = 44100,
- .bufferUser_size = 16*sizeof(float),
- .volL = 1.0f,
- .volR = 1.0f,
- .applyVolume = SDL_TRUE,
- .stereoInput = SDL_FALSE,
- .stereoUser = SDL_FALSE,
- .stereoOutput = SDL_FALSE,
- .sampleFrames = 16,
- .formatInput = AUDIO_F32,
- .formatUser = AUDIO_F32,
- .formatOutput = AUDIO_F32
- };
- //example streams
- Uint8 u_8_A[16]={0x00,0x3F,0x10,0x80,0xFF,0x4E,0x24,0x6D,0x21,0xFE,0xED,0x86,0x3A,0xAB,0xDA,0x4C};
- Sint16 i16_A[16]={-32768,13106,-16384,6553,32767,2553,-26214,25937,22337,-13102,9553,-32467,-9830,0,-19661,-22938};
- Sint32 i32_A[16]={-2147483648,2147483647,2,547760950,-978102134,-1901782676,973752665,-2054956051,-1793070550,2100284199,1386177656,-70287364,-799099289,-594127329,1025429360,-570645197};
- float f32_A[16]={ 0.8,-0.2, 0.0,-0.6,-0.6, 0.4, 1.0, 2.0, 0.6, 0.9, 0.8, 0.3, 0.6,-1.4,-0.1, 0.1};
- float f32_B[16]={-0.1,-0.4, 0.1, 0.3,-0.6, 0.6, 0.6,-0.6,-0.1, 0.2,-0.2, 0.8, 0.4, 0.8, 0.4, 0.7};
- //test to and from type conversion
- //u_8
- SDL_memcpy(voiceA.bufferUser.m.u_8, u_8_A, 16*sizeof(Uint8));
- _kit_kmixerVoiceProcFromType(voiceA.bufferUser.m.u_8,voiceA.bufferType.m, 16,AUDIO_U8,SDL_FALSE);
- _kit_kmixerVoiceProcToType(voiceA.bufferType.m,voiceA.bufferUser.m.u_8, 16,AUDIO_U8,SDL_FALSE);
- for(Uint32 i=0; i<16; ++i){
- if(voiceA.bufferUser.m.u_8[i] != _MX(u_8_A[i],1)){
- SDL_SetError("u_8 type conversion failed (%u: %X != %X)",
- i, voiceA.bufferUser.m.u_8[i], _MX(u_8_A[i],1) ); return -999;
- }
- }
- //i16
- SDL_memcpy(voiceA.bufferUser.m.i16, i16_A, 16*sizeof(Sint16));
- _kit_kmixerVoiceProcFromType(voiceA.bufferUser.m.i16,voiceA.bufferType.m, 16,AUDIO_S16,SDL_FALSE);
- _kit_kmixerVoiceProcToType(voiceA.bufferType.m,voiceA.bufferUser.m.i16, 16,AUDIO_S16,SDL_FALSE);
- for(Uint32 i=0; i<16; ++i){
- if(voiceA.bufferUser.m.i16[i] != _MX(i16_A[i],-32767)){
- SDL_SetError("i16 type conversion failed (%u: %i != %i)",
- i, voiceA.bufferUser.m.i16[i], _MX(i16_A[i],-32767) ); return -999;
- }
- }
- //i32 (products of conversion are actually approximations with a max error of 64)
- SDL_memcpy(voiceA.bufferUser.m.i32, i32_A, 16*sizeof(Sint32));
- _kit_kmixerVoiceProcFromType(voiceA.bufferUser.m.i32,voiceA.bufferType.m, 16,AUDIO_S32,SDL_FALSE);
- _kit_kmixerVoiceProcToType(voiceA.bufferType.m,voiceA.bufferUser.m.i32, 16,AUDIO_S32,SDL_FALSE);
- for(Uint32 i=0; i<16; ++i){
- if((voiceA.bufferUser.m.i32[i] < (_MX(i32_A[i],-2147483647)-64)) &&
- (voiceA.bufferUser.m.i32[i] > (_MX(i32_A[i],-2147483647)+64)))
- {
- SDL_SetError("i32 type conversion failed (%u: %i != %i)",
- i, voiceA.bufferUser.m.i32[i], _MX(i32_A[i],-2147483647) ); return -999;
- }
- }
- //f32
- SDL_memcpy(voiceA.bufferUser.m.f32, f32_A, 16*sizeof(float));
- _kit_kmixerVoiceProcFromType(voiceA.bufferUser.m.f32,voiceA.bufferType.m, 16,AUDIO_F32,SDL_FALSE);
- _kit_kmixerVoiceProcToType(voiceA.bufferType.m,voiceA.bufferUser.m.f32, 16,AUDIO_F32,SDL_FALSE);
- for(Uint32 i=0; i<16; ++i){
- if(voiceA.bufferUser.m.f32[i] != _CLMP(f32_A[i], -1.0f,1.0f)){
- SDL_SetError("f32 type conversion failed (%u: %f != %f)",
- i, voiceA.bufferUser.m.f32[i], _CLMP(f32_A[i], -1.0f,1.0f) ); return -999;
- }
- }
- //test channel conversion
- // mono-stereo
- _kit_kmixerVoiceProcChannels(f32_A, voiceA.bufferChannel.s, 8,_M_to_S);
- for(Uint32 i=0; i<16; i+=2){
- //printf("%2u: %9f, %9f\n",i, voiceA.bufferChannel.m[i], voiceA.bufferChannel.m[i+1]);
- if(voiceA.bufferChannel.m[i] != voiceA.bufferChannel.m[i+1]){
- SDL_SetError("mono->stereo channel conversion failed (%u: %f != %f)",
- i, voiceA.bufferChannel.m[i], voiceA.bufferChannel.m[i+1] ); return -999;
- }
- }
- //stereo-mono
- _kit_kmixerVoiceProcChannels(f32_A, voiceA.bufferChannel.m, 8,_S_to_M);
- for(Uint32 i=0; i<16; i+=2){
- //printf("%2u: %9f,%9f -> %9f\n",i, f32_A[i],f32_A[i+1], voiceA.bufferChannel.m[i>>1]);
- if(voiceA.bufferChannel.m[i>>1] != (f32_A[i]+f32_A[i+1])*.5f){
- SDL_SetError("stereo->mono channel conversion failed (%u: %f != %f)",
- i, voiceA.bufferChannel.m[i>>1], (f32_A[i]+f32_A[i+1])*.5f ); return -999;
- }
- }
- //stereo-stereo
- _kit_kmixerVoiceProcChannels(f32_A, voiceA.bufferChannel.s, 8,_S_to_S);
- for(Uint32 i=0; i<16; ++i){
- //printf("%2u: %9f\n",i, voiceA.bufferChannel.m[i]);
- if(voiceA.bufferChannel.m[i] != f32_A[i]){
- SDL_SetError("stereo->stereo channel conversion failed (%u: %f != %f)",
- i, voiceA.bufferChannel.m[i], f32_A[i] ); return -999;
- }
- }
- // mono-mono
- _kit_kmixerVoiceProcChannels(f32_A, voiceA.bufferChannel.m, 16,_M_to_M);
- for(Uint32 i=0; i<16; ++i){
- //printf("%2u: %9f\n",i, voiceA.bufferChannel.m[i]);
- if(voiceA.bufferChannel.m[i] != f32_A[i]){
- SDL_SetError("mono->mono channel conversion failed (%u: %f != %f)",
- i, voiceA.bufferChannel.m[i], f32_A[i] ); return -999;
- }
- }
- //test f32 buffer copying
- _kit_kmixerVoiceProcCopy(f32_A, voiceA.bufferOutput.m, 16,0);
- for(Uint32 i=0; i<16; ++i){
- if(voiceA.bufferOutput.m[i] != f32_A[i]){
- SDL_SetError("f32 buffer copying failed (%u: %f != %f)",
- i, voiceA.bufferOutput.m[i], f32_A[i] ); return -999;
- }
- }
- //todo: test VoiceProc itself here
- //test mixing (might want to add in other volume settings at some point)
- SDL_memcpy(voiceA.bufferOutput.m, f32_A, 16*sizeof(float));
- SDL_memcpy(voiceB.bufferOutput.m, f32_B, 16*sizeof(float));
- _kit_kmixerVoice ivoices[2]={voiceA,voiceB};
- //mono, 1.0,1.0
- _kit_kmixerVoiceMix(&voiceC, ivoices,2);
- for(Uint32 i=0; i<16; ++i){
- float mixed=voiceC.bufferInput.m[i];
- float real=_CLMP(voiceA.bufferOutput.m[i]+voiceB.bufferOutput.m[i], -1.0f,1.0f);
- if(mixed != real){ SDL_SetError("mono, 100%%L,100%%R mixing failed (%u: %.1f != %.1f)",
- i, mixed, real ); return -999;
- }
- }
- //stereo, 1.0,1.0
- voiceA.stereoOutput=SDL_TRUE;
- voiceB.stereoOutput=SDL_TRUE;
- voiceC.stereoInput =SDL_TRUE;
- voiceA.sampleFrames=8;
- voiceB.sampleFrames=8;
- voiceC.sampleFrames=8;
- _kit_kmixerVoiceMix(&voiceC, ivoices,2);
- for(Uint32 i=0; i<16; ++i){
- float mixed=voiceC.bufferInput.m[i];
- float real=_CLMP(voiceA.bufferOutput.m[i]+voiceB.bufferOutput.m[i], -1.0f,1.0f);
- if(mixed != real){ SDL_SetError("stereo, 100%%L,100%%R mixing failed (%u: %.1f != %.1f)",
- i, mixed, real ); return -999;
- }
- }
- return 0;
- }
- #else
- int kit_kmixerVoiceTest(){
- SDL_SetError("\"_KIT_KMIXER_DEBUG\" was not defined during compilation of kmixer");
- return 999;
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement