From 21629acc8d8c57592a5d52752aa8eaf089b054eb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 31 Dec 2012 01:03:03 -0500 Subject: [PATCH] Removed the hardcoded limit on generated buffers. Fixes audio eventually dropping out in Psychonauts. --- osx/alBuffer.c | 63 ++++++++++++++++++++++++++++++++---------------- osx/alContext.c | 5 ++-- osx/alInternal.h | 4 +-- osx/alSource.c | 2 +- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/osx/alBuffer.c b/osx/alBuffer.c index eefb5fe..223c300 100644 --- a/osx/alBuffer.c +++ b/osx/alBuffer.c @@ -63,13 +63,15 @@ static ALcontext *__alGrabContextAndGetBuffer(ALuint bufid, ALbuffer **bufout) bufid--; // account for Buffer Zero. - if (bufid > AL_MAXBUFFERS) + ctx = __alGrabCurrentContext(); + + if (bufid >= ctx->numBuffers) { __alSetError(AL_INVALID_NAME); + __alUngrabContext(ctx); return(NULL); } // if - ctx = __alGrabCurrentContext(); *bufout = &ctx->buffers[bufid]; if ( !((*bufout)->inUse) ) @@ -109,7 +111,7 @@ ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n, ALuint *buffers) return; // check if there're enough buffers available... - for (i = 0, buf = ctx->buffers; i < AL_MAXBUFFERS; i++, buf++) + for (i = 0, buf = ctx->buffers; i < ctx->numBuffers; i++, buf++) { if (!buf->inUse) { @@ -118,25 +120,44 @@ ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n, ALuint *buffers) break; } // if } // for - - if (iCount < n) - __alSetError(AL_OUT_OF_MEMORY); // !!! FIXME: Better error? - else + + if (iCount < n) // allocate more buffers? + { + const ALsizei needed = n - iCount; + ALsizei newAlloc = ctx->numBuffers * 2; + if (newAlloc == 0) + newAlloc = 1; + while (newAlloc < needed) + newAlloc *= 2; + + void *ptr = realloc(ctx->buffers, sizeof (ALbuffer) * (newAlloc)); + if (ptr == NULL) + { + __alSetError(AL_OUT_OF_MEMORY); + __alUngrabContext(ctx); + return; + } + else + { + ctx->buffers = (ALbuffer *) ptr; + __alBuffersInit(ctx->buffers + ctx->numBuffers, newAlloc - ctx->numBuffers); + ctx->numBuffers = newAlloc; + } // else + } // if + + iCount = 0; + for (i = 0, buf = ctx->buffers; i < ctx->numBuffers; i++, buf++) { - iCount = 0; - for (i = 0, buf = ctx->buffers; i < AL_MAXBUFFERS; i++, buf++) + if (!buf->inUse) { - if (!buf->inUse) - { - __alBuffersInit(buf, 1); - buf->inUse = AL_TRUE; - buffers[iCount] = i + 1; // see comments about the plus 1. - iCount++; - if (iCount >= n) - break; - } // if - } // for - } // else + __alBuffersInit(buf, 1); + buf->inUse = AL_TRUE; + buffers[iCount] = i + 1; // see comments about the plus 1. + iCount++; + if (iCount >= n) + break; + } // if + } // for __alUngrabContext(ctx); } // alGenBuffers @@ -194,7 +215,7 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, ALuint *buffers) for (i = 0; i < n; i++) { name = buffers[i] - 1; // minus one to account for Buffer Zero. - if ((name < AL_MAXBUFFERS) && (buf[name].inUse)) + if ((name < ctx->numBuffers) && (buf[name].inUse)) { __alBuffersShutdown(buf + name, 1); buf[name].inUse = AL_FALSE; diff --git a/osx/alContext.c b/osx/alContext.c index 260f2cd..b242be3 100644 --- a/osx/alContext.c +++ b/osx/alContext.c @@ -270,7 +270,6 @@ ALCAPI void * ALCAPIENTRY alcCreateContext(ALCdevice *device, ALint *attrlist) dev->createdContexts[i] = ctx; memset(ctx, '\0', sizeof (ALcontext)); - __alBuffersInit(ctx->buffers, AL_MAXBUFFERS); __alSourcesInit(ctx->sources, AL_MAXSOURCES); __alListenerInit(&ctx->listener); __alCreateLock(&ctx->contextLock); @@ -345,7 +344,9 @@ ALCAPI ALCenum ALCAPIENTRY alcDestroyContext(ALCcontext *context) __alListenerShutdown(&ctx->listener); __alSourcesShutdown(ctx->sources, AL_MAXSOURCES); - __alBuffersShutdown(ctx->buffers, AL_MAXBUFFERS); + __alBuffersShutdown(ctx->buffers, ctx->numBuffers); + free(ctx->buffers); + ctx->buffers = NULL; __alUngrabDevice(dev); // start audio callback, etc in motion again. diff --git a/osx/alInternal.h b/osx/alInternal.h index 0261b79..75009e3 100644 --- a/osx/alInternal.h +++ b/osx/alInternal.h @@ -69,7 +69,6 @@ struct ALsource_struct; typedef pthread_mutex_t ALlock; // These numbers might need adjustment up or down. -#define AL_MAXBUFFERS 1024 * 2 #define AL_MAXBUFFERQUEUE 128 #define AL_MAXSOURCES 1024 * 5 #define AL_MAXCONTEXTS 4 @@ -343,7 +342,8 @@ typedef struct ALcontext_struct // !!! FIXME: Eventually, these should make it at least to device // !!! FIXME: resolution, or perhaps globally if mutexes aren't a pain // !!! FIXME: to implement well. - ALbuffer buffers[AL_MAXBUFFERS]; + ALbuffer *buffers; + ALsizei numBuffers; } ALcontext; ALcontext *__alGrabCurrentContext(ALvoid); diff --git a/osx/alSource.c b/osx/alSource.c index f9916fb..185f5c8 100644 --- a/osx/alSource.c +++ b/osx/alSource.c @@ -443,7 +443,7 @@ ALAPI ALvoid ALAPIENTRY alSourcei (ALuint source, ALenum pname, ALint value) { // !!! FIXME: This is yucky. Use logic in alBuffer.c... ALboolean valid = AL_FALSE; - valid = ( (value > 0) && ((value - 1) < AL_MAXBUFFERS) && + valid = ( (value > 0) && ((value - 1) < ctx->numBuffers) && (ctx->buffers[value - 1].inUse) ); if (valid)