/* 0.0 - 2.0 in seconds */ void alReverbDelay_LOKI(ALuint sid, ALfloat param) { AL_source *src; if((param < 0.0) || (param > 2.0)) { /* * For this kludge, the scale is 2 * normalized. */ _alDebug(ALD_MAXIMUS, __FILE__, __LINE__, "alReverbDelay: invalid value %f", param); _alDCSetError(AL_INVALID_VALUE); return; } _alcDCLockContext(); src = _alDCGetSource(sid); if(src == NULL) { _alDebug(ALD_MAXIMUS, __FILE__, __LINE__, "alReverbScale: invalid source id %d", sid); _alDCSetError(AL_INVALID_NAME); return; } src->reverb_delay = param * canon_speed * _alGetChannelsFromFormat(canon_format); src->flags |= ALS_REVERB; _alcDCUnlockContext(); return; }
/* * _alSourceUnqueueBuffers( ALuint sid, ALsizei n, ALuint *bids ) * * Non locking version of alSourceUnqueueBuffers. * * assumes locked context */ void _alSourceUnqueueBuffers(ALuint sid, ALsizei n, ALuint *bids ) { AL_source *src; ALuint *tempqueue; AL_sourcestate *tempstate; struct dualarray *dualbuffers; /* the source's bid queue */ struct dualarray *dualbids; /* the passer's bids */ int newsize; int i; int j; if(n == 0) { /* legal nop */ return; } if(n < 0) { /* bad n */ _alDCSetError( AL_INVALID_VALUE ); _alDebug(ALD_SOURCE, __FILE__, __LINE__, "alSourceUnqueueBuffers: invalid numBuffers %d", n ); return; } src = _alDCGetSource( sid ); if(src == NULL) { _alDCSetError(AL_INVALID_NAME); return; } if(n >= src->bid_queue.read_index) { /* User has requested too many buffers unqueued */ _alDCSetError( AL_INVALID_VALUE ); _alDebug(ALD_SOURCE, __FILE__, __LINE__, "alSourceUnqueueBuffers: invalid numBuffers %d", n ); return; } dualbuffers = malloc( src->bid_queue.size * sizeof *dualbuffers ); if( dualbuffers == NULL ) { _alDCSetError( AL_OUT_OF_MEMORY ); return; } dualbids = malloc( n * sizeof *dualbuffers ); if( dualbids == NULL ) { free( dualbuffers ); _alDCSetError( AL_OUT_OF_MEMORY ); return; } /* mark */ for( i = 0; i < src->bid_queue.size; i++ ) { dualbuffers[i].id = src->bid_queue.queue[i]; dualbuffers[i].index = i; } for( i = 0; i < n; i++ ) { dualbids[i].id = bids[i]; dualbids[i].index = i; } /* * sort both the source's bids and the passer's deletion * request. */ qsort( dualbuffers, src->bid_queue.size, sizeof *dualbuffers, dualarray_id_cmp ); qsort( dualbids, n, sizeof *dualbids, dualarray_id_cmp ); /* sweep */ newsize = src->bid_queue.size; for( i = 0, j = 0; i < n; i++ ) { if( dualbids[j].id == dualbuffers[i].id ) { dualbuffers[i].id = 0; dualbuffers[i].index = -1; _alBidRemoveQueueRef( dualbids[j].id, src->sid ); j++; newsize--; } } tempqueue = malloc(newsize * sizeof *tempqueue); if(tempqueue == NULL) { /* * ouch */ _alDCSetError( AL_INVALID_VALUE ); free( dualbids ); free( dualbuffers ); return; } tempstate = malloc(newsize * sizeof *tempstate); if(tempstate == NULL) { /* too late * * FIXME: re-add queuerefs removed above */ _alDCSetError(AL_INVALID_VALUE); free( tempqueue ); free( dualbids ); free( dualbuffers ); return; } /* unsort */ qsort( dualbuffers, src->bid_queue.size, sizeof *dualbuffers, dualarray_index_cmp ); /* rewrite */ /* first, skip the 0'd out stuff */ for( i = 0; dualbuffers[i].id == 0; i++ ) { /* * ouch. not sure about read_index or write_index * moving. */ if(src->bid_queue.read_index >= i) { src->bid_queue.read_index--; } if(src->bid_queue.write_index >= i) { src->bid_queue.write_index--; } } for(j = 0; j < newsize; j++, i++) { tempqueue[j] = src->bid_queue.queue[i]; tempstate[j] = src->bid_queue.queuestate[i]; } /* free and assign */ free( dualbuffers ); free( dualbids ); free( src->bid_queue.queue ); free( src->bid_queue.queuestate ); src->bid_queue.queue = tempqueue; src->bid_queue.queuestate = tempstate; src->bid_queue.size = newsize; return; }
/* * alSourceQueueBuffers( ALuint sid, ALsizei numBuffers, ALuint *bids ) * * Queue bids[0..numBuffers-1] to the source named sid, setting * AL_INVALID_VALUE if numBuffers < 0, or AL_INVALID_NAME if either sid or and * bid in bids[0..numBuffers-1] is not a valid buffer. */ void alSourceQueueBuffers( ALuint sid, ALsizei numBuffers, ALuint *bids ) { AL_source *src; ALsizei i; if( numBuffers == 0) { /* with n == 0, we NOP */ return; } if( numBuffers < 0) { _alDebug(ALD_SOURCE, __FILE__, __LINE__, "alSourceQueueBuffers: illegal n value %d\n", numBuffers ); _alcDCLockContext(); _alDCSetError( AL_INVALID_VALUE ); _alcDCUnlockContext(); return; } SOURCELOCK(); src = _alDCGetSource( sid ); if( src == NULL ) { _alDCSetError( AL_INVALID_NAME ); _alDebug(ALD_SOURCE, __FILE__, __LINE__, "alSourceQueueBuffers: invalid sid %d\n", sid ); SOURCEUNLOCK(); return; } _alLockBuffer(); /* make sure that bids are valid */ for( i = 0; i < numBuffers; i++ ) { if( _alIsBuffer( bids[i] ) == AL_FALSE ) { /* * we have an invalid bid. bid 0 is okay but the * rest are not. */ if( bids[i] != 0 ) { _alUnlockBuffer(); _alDCSetError( AL_INVALID_NAME ); SOURCEUNLOCK(); return; } } } /* now, append the bids */ for( i = 0; i < numBuffers; i++ ) { if( bids[i] != 0 ) { /* * only append non-0 bids, because we don't * need them anyway. */ _alSourceQueueAppend( src, bids[i] ); } } /* we're done */ _alUnlockBuffer(); SOURCEUNLOCK(); return; }
/* * alQueuei( ALuint sid, ALenum param, ALint i1 ) * * Obsolete function. Remove this. */ void alQueuei( ALuint sid, ALenum param, ALint i1 ) { AL_source *src; ALboolean inrange = AL_FALSE; SOURCELOCK(); src = _alDCGetSource(sid); if(src == NULL) { _alDCSetError(AL_INVALID_NAME); SOURCEUNLOCK(); return; } /* * all calls to alQueuei specify either ALboolean parameters, * which means that i1 is either AL_TRUE, AL_FALSE, or * a buffer id. So check for validity of i1 first, and * set error if that's the case. */ switch(param) { case AL_LOOPING: case AL_SOURCE_RELATIVE: inrange = _alCheckRangeb(i1); break; case AL_BUFFER: inrange = alIsBuffer(i1); break; default: /* invalid param, error below. */ break; } if(inrange == AL_FALSE) { _alDebug(ALD_SOURCE, __FILE__, __LINE__, "alQueuei(%d, 0x%x, ...) called with invalid value %d", sid, param, i1); _alDCSetError(AL_INVALID_VALUE); SOURCEUNLOCK(); return; } switch(param) { /* FIXME: add loop count */ case AL_BUFFER: /* Append bid to end */ _alSourceQueueAppend(src, i1); break; default: _alDebug(ALD_SOURCE, __FILE__, __LINE__, "alQueuei: invalid or stubbed source param 0x%x", param); _alDCSetError(AL_ILLEGAL_ENUM); break; } SOURCEUNLOCK(); return; }