Different audio levels between SOURCE_RELATIVE True/False

[email protected]
Newsgroups gmane.comp.lib.openal
Message-ID <[email protected]>
Hi,
I'm looking into switching between SOURCE_RELATIVE True/False to allow
some form of split screen functionality.

In my testing I have noticed that there is a difference in audio output
level when switching between the two modes, and by the sound of it there
is some clipping/overload happening in the engine.

A small test application is attached which shows this problem. I have a
single sound source traveling around a circle, the listener is on the
circle and will hear the source traveling past.

With SOURCE_RELATIVE False the audio output is much loud/overloaded when
the source is closest to listener.


I tried to limit/equalise this with MAX_GAIN/CONE_ANGLES, but these did
not fix the problem.

Any suggestions as to what is wrong?
Simon.

_______________________________________________
Openal mailing list
[email protected]
http://opensource.creative.com/mailman/listinfo/openal
circle_test.c (text/x-csrc, 3.9 KB)
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alut.h>

#define POS_UPDATE 0.1	// 10Hz
#define SPLIT_UPDATE 20

#define RADIUS 100
#define ROTSPEED 20 	// seconds to complete rotation

#define MULTI_CONTEXT 0
#define MAX_SPLIT 2

double time_now(void)
{
	struct timeval my_time;

	gettimeofday(&my_time, NULL);
	return (double) my_time.tv_sec + ((double) my_time.tv_usec/1000000);
}

// Global defines
ALuint Buffer[MAX_SPLIT];
ALuint Source[MAX_SPLIT];

// Initial Positions
ALfloat SourcePos[] = { 0.0, RADIUS, 0.0 };
ALfloat SourceVel[] = { 0.0, 0.0, 0.0 };

// Listener positions (around a circle)
ALfloat ListenerMulti[][3] = { 	
				{ 0.0, -RADIUS, 0.0 },
				{ 0.0, -RADIUS, 0.0 },
				{ -RADIUS, 0.0, 0.0 },
				{ 0.0, RADIUS, 0.0 },
				{ RADIUS, 0.0, 0.0 }	  
			};  

ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };
ALfloat ListenerOri[] = { 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 };


int main(int argc, char *argv[])
{
	double start_time, current_time, next_pos_update, next_split_update;
	float angle, x, y;

	ALint play;
	ALenum format;
	ALsizei size;
	ALvoid* data;
	ALsizei freq;
	ALuint repeat;

	int loop, mode=0;

	// Create a device with multiple contexts on it
	ALCdevice * pSoundcard;
	ALCcontext * pContextStereo;
	ALCcontext * pContext[MAX_SPLIT];

	pSoundcard = alcOpenDevice(NULL);
	pContext[0] = alcCreateContext(pSoundcard, NULL);	// Stereo

	alcMakeContextCurrent(pContext[0]);

	// Load the wav data.
	alGenBuffers(1, &Buffer[0]);
	alutLoadWAVFile((ALbyte*)"tone1.wav", &format, &data, &size, &freq, &repeat);
	alBufferData(Buffer[0], format, data, size, freq);
	alutUnloadWAV(format, data, size, freq);

	// Set listener positions
	printf("Setting up stereo context:\n");
	printf("Setting location %f, %f, %f\n\n", ListenerMulti[0][0], ListenerMulti[0][1], ListenerMulti[0][2]);
	alListenerfv(AL_POSITION,    ListenerMulti[0]);
	alListenerfv(AL_VELOCITY,    ListenerVel);
	alListenerfv(AL_ORIENTATION, ListenerOri);

	alGenSources(1, &Source[0]);

	alSourcei (Source[0], AL_BUFFER,   Buffer[0]);
	alSourcef (Source[0], AL_PITCH,    1.0      );
	alSourcef (Source[0], AL_GAIN,     1.0      );
	alSourcei (Source[0], AL_LOOPING,  AL_TRUE);

	alSourcefv(Source[0], AL_POSITION, SourcePos);
	alSourcefv(Source[0], AL_VELOCITY, SourceVel);
	alSourcei (Source[0], AL_SOURCE_RELATIVE, AL_TRUE);

#if 0
	// attempt to limit gain
	alSourcef (Source[0], AL_MAX_GAIN, 0.7      );
	alSourcef (Source[0], AL_CONE_INNER_ANGLE, 360.0 );
	alSourcef (Source[0], AL_CONE_OUTER_ANGLE, 360.0 );
#endif

	alcMakeContextCurrent(pContext[0]);
	alSourcePlay(Source[0]);

	// Set up initial time reference
	start_time = time_now();
	next_pos_update = POS_UPDATE;
	next_split_update = 0;

	while (1) {
		// Get current time
		current_time = time_now() - start_time;

		// Do we need to switch to next listener?
		if (current_time > next_split_update) {
			switch (mode) {
				case 0:
					printf("\nAL_SOURCE_RELATIVE = AL_TRUE -> Stereo sound into L/R\n\n");

					// Stereo
					alcMakeContextCurrent(pContext[0]);
					alSourcei (Source[0], AL_SOURCE_RELATIVE, AL_TRUE);
					mode++;
					break;
				case 1:
					printf("\nAL_SOURCE_RELATIVE = AL_FALSE -> Mono into both ears\n\n");
					alSourcei (Source[0], AL_SOURCE_RELATIVE, AL_FALSE);
				default:
					mode = 0;
			}


			// prescision is not required here
			next_split_update += SPLIT_UPDATE;
		}

		// Reposition Source
		if (current_time > next_pos_update) {
			angle = ((current_time / ROTSPEED) - (int)(current_time / ROTSPEED)) * 2 * 3.141592653589793;

			SourcePos[0] = RADIUS * sin(angle);
			SourcePos[1] = RADIUS * cos(angle);

			alcMakeContextCurrent(pContext[0]);
			alSourcefv(Source[0], AL_POSITION, SourcePos);
			alSourcefv(Source[0], AL_VELOCITY, SourceVel);

			printf("%f: %f, %f, %f, %f\n",current_time, angle, SourcePos[0],SourcePos[1],SourcePos[2]);
			while (next_pos_update < current_time)
				next_pos_update = next_pos_update + POS_UPDATE;
		}
	}
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.