Different audio levels between SOURCE_RELATIVE True/False
| 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;
}
}
}