From b7f8e97b0384ae37bff110a2ef42cc42cfa09228 Mon Sep 17 00:00:00 2001 From: Joshua Reisenauer <kd7tck@msn.com> Date: Tue, 10 May 2016 01:54:20 -0700 Subject: [PATCH] final fix for audiocontext system now it works --- src/audio.c | 74 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/src/audio.c b/src/audio.c index 8f6431f6a..fbf53df66 100644 --- a/src/audio.c +++ b/src/audio.c @@ -102,6 +102,7 @@ typedef struct AudioContext_t { unsigned char channels; // 1=mono,2=stereo unsigned char mixChannel; // 0-3 or mixA-mixD, each mix channel can receive up to one dedicated audio stream bool floatingPoint; // if false then the short datatype is used instead + bool playing; ALenum alFormat; // openAL format specifier ALuint alSource; // openAL source ALuint alBuffer[MAX_STREAM_BUFFERS]; // openAL sample buffer @@ -211,7 +212,7 @@ AudioContext InitAudioContext(unsigned short sampleRate, unsigned char mixChanne else StopMusicStream(); if(!mixChannelsActive_g[mixChannel]){ - AudioContext_t *ac = malloc(sizeof(AudioContext_t)); + AudioContext_t *ac = (AudioContext_t*)malloc(sizeof(AudioContext_t)); ac->sampleRate = sampleRate; ac->channels = channels; ac->mixChannel = mixChannel; @@ -250,8 +251,8 @@ AudioContext InitAudioContext(unsigned short sampleRate, unsigned char mixChanne FillAlBufferWithSilence(ac, ac->alBuffer[x]); alSourceQueueBuffers(ac->alSource, MAX_STREAM_BUFFERS, ac->alBuffer); - alSourcei(ac->alSource, AL_LOOPING, AL_FALSE); // this could cause errors alSourcePlay(ac->alSource); + ac->playing = true; return ac; } @@ -264,6 +265,7 @@ void CloseAudioContext(AudioContext ctx) AudioContext_t *context = (AudioContext_t*)ctx; if(context){ alSourceStop(context->alSource); + context->playing = false; //flush out all queued buffers ALuint buffer = 0; @@ -287,22 +289,29 @@ void CloseAudioContext(AudioContext ctx) // Pushes more audio data into context mix channel, if none are ever pushed then zeros are fed in. // Call "UpdateAudioContext(ctx, NULL, 0)" if you want to pause the audio. // @Returns number of samples that where processed. -// All data streams should be of a length that is evenly divisible by MUSIC_BUFFER_SIZE, -// otherwise the remaining data will not be pushed. unsigned short UpdateAudioContext(AudioContext ctx, void *data, unsigned short numberElements) { AudioContext_t *context = (AudioContext_t*)ctx; - if(context && context->channels == 2 && numberElements % 2 != 0) return 0; // when there is two channels there must be an even number of samples + if(!context || (context->channels == 2 && numberElements % 2 != 0)) return 0; // when there is two channels there must be an even number of samples - if (!data || !numberElements) alSourcePause(context->alSource); // pauses audio until data is given - else{ // restart audio otherwise + if (!data || !numberElements) + { // pauses audio until data is given + alSourcePause(context->alSource); + context->playing = false; + return 0; + } + else + { // restart audio otherwise ALint state; alGetSourcei(context->alSource, AL_SOURCE_STATE, &state); - if (state != AL_PLAYING) alSourcePlay(context->alSource); + if (state != AL_PLAYING){ + alSourcePlay(context->alSource); + context->playing = true; + } } - if (context && mixChannelsActive_g[context->mixChannel] == context) + if (context && context->playing && mixChannelsActive_g[context->mixChannel] == context) { ALint processed = 0; ALuint buffer = 0; @@ -311,36 +320,55 @@ unsigned short UpdateAudioContext(AudioContext ctx, void *data, unsigned short n alGetSourcei(context->alSource, AL_BUFFERS_PROCESSED, &processed); // Get the number of already processed buffers (if any) - if(!processed) return 0;//nothing to process, queue is still full + if(!processed) return 0; // nothing to process, queue is still full + - if(numberRemaining)// buffer data stream in increments of MUSIC_BUFFER_SIZE + while (processed > 0) { - while (processed > 0) + if(context->floatingPoint) // process float buffers { - if(context->floatingPoint && numberRemaining >= MUSIC_BUFFER_SIZE_FLOAT) // process float buffers + float *ptr = (float*)data; + alSourceUnqueueBuffers(context->alSource, 1, &buffer); + if(numberRemaining >= MUSIC_BUFFER_SIZE_FLOAT) { - float *ptr = (float*)data; - alSourceUnqueueBuffers(context->alSource, 1, &buffer); alBufferData(buffer, context->alFormat, &ptr[numberProcessed], MUSIC_BUFFER_SIZE_FLOAT*sizeof(float), context->sampleRate); - alSourceQueueBuffers(context->alSource, 1, &buffer); numberProcessed+=MUSIC_BUFFER_SIZE_FLOAT; numberRemaining-=MUSIC_BUFFER_SIZE_FLOAT; } - else if(!context->floatingPoint && numberRemaining >= MUSIC_BUFFER_SIZE_SHORT) // process short buffers + else { - short *ptr = (short*)data; - alSourceUnqueueBuffers(context->alSource, 1, &buffer); - alBufferData(buffer, context->alFormat, &ptr[numberProcessed], MUSIC_BUFFER_SIZE_SHORT*sizeof(short), context->sampleRate); - alSourceQueueBuffers(context->alSource, 1, &buffer); + alBufferData(buffer, context->alFormat, &ptr[numberProcessed], numberRemaining*sizeof(float), context->sampleRate); + numberProcessed+=numberRemaining; + numberRemaining=0; + } + alSourceQueueBuffers(context->alSource, 1, &buffer); + processed--; + } + else if(!context->floatingPoint) // process short buffers + { + short *ptr = (short*)data; + alSourceUnqueueBuffers(context->alSource, 1, &buffer); + if(numberRemaining >= MUSIC_BUFFER_SIZE_SHORT) + { + alBufferData(buffer, context->alFormat, &ptr[numberProcessed], MUSIC_BUFFER_SIZE_FLOAT*sizeof(short), context->sampleRate); numberProcessed+=MUSIC_BUFFER_SIZE_SHORT; numberRemaining-=MUSIC_BUFFER_SIZE_SHORT; } - + else + { + alBufferData(buffer, context->alFormat, &ptr[numberProcessed], numberRemaining*sizeof(short), context->sampleRate); + numberProcessed+=numberRemaining; + numberRemaining=0; + } + alSourceQueueBuffers(context->alSource, 1, &buffer); processed--; } + else + break; } + return numberProcessed; } - return numberProcessed; + return 0; } // fill buffer with zeros, returns number processed