/* 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;
}
Exemple #2
0
/*
 * _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;
}
Exemple #3
0
/*
 * 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;
}
Exemple #4
0
/*
 * 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;
}