mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-25 23:43:58 +00:00
Horrible hack to attenuate stereo sources properly.
OpenAL refuses to pan stereo sources, so apparently it needs to be done this way.
This commit is contained in:
parent
e6680da428
commit
f5da61fe78
4 changed files with 84 additions and 11 deletions
|
@ -2767,6 +2767,8 @@ luaFunc(entity_playSfx)
|
||||||
sfx.name = getString(L, 2);
|
sfx.name = getString(L, 2);
|
||||||
sfx.freq = lua_tonumber(L, 3);
|
sfx.freq = lua_tonumber(L, 3);
|
||||||
sfx.vol = lua_tonumber(L, 4);
|
sfx.vol = lua_tonumber(L, 4);
|
||||||
|
if(sfx.vol <= 0)
|
||||||
|
sfx.vol = 1;
|
||||||
sfx.loops = lua_tonumber(L, 5);
|
sfx.loops = lua_tonumber(L, 5);
|
||||||
|
|
||||||
float fadeOut = lua_tonumber(L, 6);
|
float fadeOut = lua_tonumber(L, 6);
|
||||||
|
|
|
@ -49,6 +49,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
//#define _DEBUG 1
|
//#define _DEBUG 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Decoder implementation for streamed Ogg Vorbis audio.
|
// Decoder implementation for streamed Ogg Vorbis audio.
|
||||||
|
@ -85,6 +88,8 @@ public:
|
||||||
static void startDecoderThread();
|
static void startDecoderThread();
|
||||||
static void stopDecoderThread();
|
static void stopDecoderThread();
|
||||||
|
|
||||||
|
ALenum getFormat() const { return format; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void _stop();
|
void _stop();
|
||||||
|
@ -597,8 +602,11 @@ public:
|
||||||
bool isLooping() const { return looping; }
|
bool isLooping() const { return looping; }
|
||||||
bool isRaw() const { return raw; }
|
bool isRaw() const { return raw; }
|
||||||
FMOD_RESULT release();
|
FMOD_RESULT release();
|
||||||
|
FMOD_RESULT getFormat(FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits);
|
||||||
void reference() { refcount++; }
|
void reference() { refcount++; }
|
||||||
ALuint getBufferName() const { return bid; }
|
ALuint getBufferName() const { return bid; }
|
||||||
|
int getNumChannels() const { return numChannels; }
|
||||||
|
void setNumChannels(int c) { numChannels = c; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VFILE * const fp;
|
VFILE * const fp;
|
||||||
|
@ -608,6 +616,7 @@ private:
|
||||||
int refcount;
|
int refcount;
|
||||||
const bool raw; // true if buffer holds raw PCM data
|
const bool raw; // true if buffer holds raw PCM data
|
||||||
ALuint bid; // only used if raw == true
|
ALuint bid; // only used if raw == true
|
||||||
|
int numChannels;
|
||||||
};
|
};
|
||||||
|
|
||||||
OpenALSound::OpenALSound(VFILE *_fp, const bool _looping)
|
OpenALSound::OpenALSound(VFILE *_fp, const bool _looping)
|
||||||
|
@ -618,6 +627,7 @@ OpenALSound::OpenALSound(VFILE *_fp, const bool _looping)
|
||||||
, refcount(1)
|
, refcount(1)
|
||||||
, raw(false)
|
, raw(false)
|
||||||
, bid(0)
|
, bid(0)
|
||||||
|
, numChannels(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,6 +639,7 @@ OpenALSound::OpenALSound(void *_data, long _size, const bool _looping)
|
||||||
, refcount(1)
|
, refcount(1)
|
||||||
, raw(false)
|
, raw(false)
|
||||||
, bid(0)
|
, bid(0)
|
||||||
|
, numChannels(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,6 +651,7 @@ OpenALSound::OpenALSound(ALuint _bid, const bool _looping)
|
||||||
, refcount(1)
|
, refcount(1)
|
||||||
, raw(true)
|
, raw(true)
|
||||||
, bid(_bid)
|
, bid(_bid)
|
||||||
|
, numChannels(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,6 +677,14 @@ FMOD_RESULT OpenALSound::release()
|
||||||
return FMOD_OK;
|
return FMOD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALBRIDGE(Sound,getFormat,(FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits),(type, format, channels, bits))
|
||||||
|
FMOD_RESULT OpenALSound::getFormat(FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits)
|
||||||
|
{
|
||||||
|
if(channels)
|
||||||
|
*channels = getNumChannels();
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class OpenALChannelGroup;
|
class OpenALChannelGroup;
|
||||||
|
|
||||||
|
@ -691,6 +711,7 @@ public:
|
||||||
FMOD_RESULT getMode(FMOD_MODE *mode);
|
FMOD_RESULT getMode(FMOD_MODE *mode);
|
||||||
|
|
||||||
void setGroupVolume(const float _volume);
|
void setGroupVolume(const float _volume);
|
||||||
|
void setDistanceVolume(float _volume);
|
||||||
void setSourceName(const ALuint _sid) { sid = _sid; }
|
void setSourceName(const ALuint _sid) { sid = _sid; }
|
||||||
ALuint getSourceName() const { return sid; }
|
ALuint getSourceName() const { return sid; }
|
||||||
bool start(OpenALSound *sound);
|
bool start(OpenALSound *sound);
|
||||||
|
@ -700,9 +721,12 @@ public:
|
||||||
void setSound(OpenALSound *sound);
|
void setSound(OpenALSound *sound);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void applyVolume();
|
||||||
|
|
||||||
ALuint sid; // source id.
|
ALuint sid; // source id.
|
||||||
float groupvolume;
|
float groupvolume;
|
||||||
float volume;
|
float volume;
|
||||||
|
float distvolume;
|
||||||
bool paused;
|
bool paused;
|
||||||
int priority;
|
int priority;
|
||||||
float frequency;
|
float frequency;
|
||||||
|
@ -746,6 +770,7 @@ OpenALChannel::OpenALChannel()
|
||||||
: sid(0)
|
: sid(0)
|
||||||
, groupvolume(1.0f)
|
, groupvolume(1.0f)
|
||||||
, volume(1.0f)
|
, volume(1.0f)
|
||||||
|
, distvolume(1.0f)
|
||||||
, paused(false)
|
, paused(false)
|
||||||
, priority(0)
|
, priority(0)
|
||||||
, frequency(1.0f)
|
, frequency(1.0f)
|
||||||
|
@ -763,6 +788,7 @@ void OpenALChannel::reacquire()
|
||||||
assert(!inuse);
|
assert(!inuse);
|
||||||
inuse = true;
|
inuse = true;
|
||||||
volume = 1.0f;
|
volume = 1.0f;
|
||||||
|
distvolume = 1.0f;
|
||||||
paused = true;
|
paused = true;
|
||||||
priority = 0;
|
priority = 0;
|
||||||
frequency = 1.0f;
|
frequency = 1.0f;
|
||||||
|
@ -773,8 +799,7 @@ void OpenALChannel::reacquire()
|
||||||
void OpenALChannel::setGroupVolume(const float _volume)
|
void OpenALChannel::setGroupVolume(const float _volume)
|
||||||
{
|
{
|
||||||
groupvolume = _volume;
|
groupvolume = _volume;
|
||||||
alSourcef(sid, AL_GAIN, volume * groupvolume);
|
applyVolume();
|
||||||
SANITY_CHECK_OPENAL_CALL();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenALChannel::start(OpenALSound *sound)
|
bool OpenALChannel::start(OpenALSound *sound)
|
||||||
|
@ -798,6 +823,7 @@ bool OpenALChannel::start(OpenALSound *sound)
|
||||||
decoder = NULL;
|
decoder = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
sound->setNumChannels((decoder->getFormat() == AL_FORMAT_STEREO16) ? 2 : 1);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -820,8 +846,7 @@ ALBRIDGE(Channel,setVolume,(float volume),(volume))
|
||||||
FMOD_RESULT OpenALChannel::setVolume(const float _volume)
|
FMOD_RESULT OpenALChannel::setVolume(const float _volume)
|
||||||
{
|
{
|
||||||
volume = _volume;
|
volume = _volume;
|
||||||
alSourcef(sid, AL_GAIN, _volume * groupvolume);
|
applyVolume();
|
||||||
SANITY_CHECK_OPENAL_CALL();
|
|
||||||
return FMOD_OK;
|
return FMOD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,7 +1009,37 @@ ALBRIDGE(Channel,set3DAttributes,(const FMOD_VECTOR *pos, const FMOD_VECTOR *vel
|
||||||
FMOD_RESULT OpenALChannel::set3DAttributes(const FMOD_VECTOR *pos, const FMOD_VECTOR *vel)
|
FMOD_RESULT OpenALChannel::set3DAttributes(const FMOD_VECTOR *pos, const FMOD_VECTOR *vel)
|
||||||
{
|
{
|
||||||
if (pos)
|
if (pos)
|
||||||
|
{
|
||||||
alSource3f(sid, AL_POSITION, pos->x, pos->y, pos->z);
|
alSource3f(sid, AL_POSITION, pos->x, pos->y, pos->z);
|
||||||
|
int chans = sound->getNumChannels();
|
||||||
|
if(sound->getNumChannels() == 1)
|
||||||
|
setDistanceVolume(1); // nothing to do
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// HACK: reduce volume if far away (OpanAL does not do this for stereo sounds)
|
||||||
|
// HACK: assume linear distance model
|
||||||
|
ALfloat listenerPos[3];
|
||||||
|
ALint relative = 0;
|
||||||
|
alGetSourcei(sid, AL_SOURCE_RELATIVE, &relative);
|
||||||
|
if(relative)
|
||||||
|
listenerPos[0] = listenerPos[1] = listenerPos[2] = 0;
|
||||||
|
else
|
||||||
|
alGetListenerfv(AL_POSITION, &listenerPos[0]);
|
||||||
|
float dx = listenerPos[0] - pos->x;
|
||||||
|
float dy = listenerPos[1] - pos->y;
|
||||||
|
float dz = listenerPos[2] - pos->z;
|
||||||
|
float distance = sqrtf(dx*dx + dy*dy + dz*dz);
|
||||||
|
float rolloff = 1, refdist = 0, maxdist = 0;
|
||||||
|
alGetSourcef(sid, AL_ROLLOFF_FACTOR, &rolloff);
|
||||||
|
alGetSourcef(sid, AL_REFERENCE_DISTANCE, &refdist);
|
||||||
|
alGetSourcef(sid, AL_MAX_DISTANCE, &maxdist);
|
||||||
|
distance = std::max(distance, refdist);
|
||||||
|
distance = std::min(distance, maxdist);
|
||||||
|
float gain = (maxdist == refdist) ? 1 : (1 - rolloff * (distance - refdist) / (maxdist - refdist));
|
||||||
|
setDistanceVolume(gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if(vel)
|
if(vel)
|
||||||
alSource3f(sid, AL_VELOCITY, vel->x, vel->y, vel->z);
|
alSource3f(sid, AL_VELOCITY, vel->x, vel->y, vel->z);
|
||||||
|
|
||||||
|
@ -1024,6 +1079,18 @@ FMOD_RESULT OpenALChannel::getMode(FMOD_MODE *mode)
|
||||||
return FMOD_OK;
|
return FMOD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenALChannel::setDistanceVolume(float _volume)
|
||||||
|
{
|
||||||
|
distvolume = _volume;
|
||||||
|
applyVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenALChannel::applyVolume()
|
||||||
|
{
|
||||||
|
alSourcef(sid, AL_GAIN, volume * groupvolume * distvolume);
|
||||||
|
SANITY_CHECK_OPENAL_CALL();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// FMOD::ChannelGroup implementation...
|
// FMOD::ChannelGroup implementation...
|
||||||
|
@ -1330,6 +1397,7 @@ FMOD_RESULT OpenALSystem::createSound(const char *name_or_data, const FMOD_MODE
|
||||||
{
|
{
|
||||||
alBufferData(bid, format, data, size, freq);
|
alBufferData(bid, format, data, size, freq);
|
||||||
*sound = (Sound *) new OpenALSound(bid, (((mode & FMOD_LOOP_OFF) == 0) && (mode & FMOD_LOOP_NORMAL)));
|
*sound = (Sound *) new OpenALSound(bid, (((mode & FMOD_LOOP_OFF) == 0) && (mode & FMOD_LOOP_NORMAL)));
|
||||||
|
((OpenALSound*)*sound)->setNumChannels(format == AL_FORMAT_STEREO16 ? 2 : 1);
|
||||||
retval = FMOD_OK;
|
retval = FMOD_OK;
|
||||||
}
|
}
|
||||||
free(data);
|
free(data);
|
||||||
|
|
|
@ -101,6 +101,8 @@ typedef int FMOD_MODE;
|
||||||
#define FMOD_3D_LINEARROLLOFF (1<<10)
|
#define FMOD_3D_LINEARROLLOFF (1<<10)
|
||||||
#define FMOD_DEFAULT (FMOD_2D | FMOD_HARDWARE)
|
#define FMOD_DEFAULT (FMOD_2D | FMOD_HARDWARE)
|
||||||
|
|
||||||
|
typedef int FMOD_SOUND_FORMAT;
|
||||||
|
typedef int FMOD_SOUND_TYPE;
|
||||||
|
|
||||||
typedef int FMOD_CREATESOUNDEXINFO;
|
typedef int FMOD_CREATESOUNDEXINFO;
|
||||||
|
|
||||||
|
@ -137,6 +139,7 @@ namespace FMOD
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FMOD_RESULT release();
|
FMOD_RESULT release();
|
||||||
|
FMOD_RESULT getFormat(FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits); // only *channels implemented
|
||||||
};
|
};
|
||||||
|
|
||||||
class DSP
|
class DSP
|
||||||
|
|
|
@ -1060,8 +1060,8 @@ bool SoundManager::playVoice(const std::string &name, SoundVoiceType svt, float
|
||||||
voiceChannel->setCallback(NULL);
|
voiceChannel->setCallback(NULL);
|
||||||
voiceChannel->setUserData(NULL);
|
voiceChannel->setUserData(NULL);
|
||||||
voiceChannel->set3DMinMaxDistance(0.0f, 0.0f);
|
voiceChannel->set3DMinMaxDistance(0.0f, 0.0f);
|
||||||
setSoundPos(voiceChannel, 0, 0);
|
|
||||||
setSoundRelative(voiceChannel, true);
|
setSoundRelative(voiceChannel, true);
|
||||||
|
setSoundPos(voiceChannel, 0, 0);
|
||||||
|
|
||||||
result = voiceChannel->setPaused(false);
|
result = voiceChannel->setPaused(false);
|
||||||
checkError();
|
checkError();
|
||||||
|
@ -1158,10 +1158,6 @@ void *SoundManager::playSfx(const PlaySfx &play)
|
||||||
channel->setCallback(NULL);
|
channel->setCallback(NULL);
|
||||||
channel->setUserData(NULL);
|
channel->setUserData(NULL);
|
||||||
|
|
||||||
// position in space
|
|
||||||
setSoundPos(channel, play.x, play.y);
|
|
||||||
setSoundRelative(channel, play.relative);
|
|
||||||
|
|
||||||
// distance gain attenuation: stereo separation + silence at further away than maxdist
|
// distance gain attenuation: stereo separation + silence at further away than maxdist
|
||||||
float maxdist = play.maxdist;
|
float maxdist = play.maxdist;
|
||||||
if (!maxdist)
|
if (!maxdist)
|
||||||
|
@ -1172,6 +1168,10 @@ void *SoundManager::playSfx(const PlaySfx &play)
|
||||||
else
|
else
|
||||||
channel->set3DMinMaxDistance(0, 0); // no attenuation
|
channel->set3DMinMaxDistance(0, 0); // no attenuation
|
||||||
|
|
||||||
|
// position in space
|
||||||
|
setSoundRelative(channel, play.relative);
|
||||||
|
setSoundPos(channel, play.x, play.y); // must be set after everything else (See hack in OpenALChannel::set3DAttributes())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
result = channel->setPaused(false);
|
result = channel->setPaused(false);
|
||||||
|
@ -1344,9 +1344,9 @@ bool SoundManager::playMusic(const std::string &name, SoundLoopType slt, SoundFa
|
||||||
musicChannel->setPan(0);
|
musicChannel->setPan(0);
|
||||||
musicChannel->setCallback(NULL);
|
musicChannel->setCallback(NULL);
|
||||||
musicChannel->setUserData(NULL);
|
musicChannel->setUserData(NULL);
|
||||||
musicChannel->set3DMinMaxDistance(0.0f, 0.0f); // disable attenuation // FIXME: is that right?
|
musicChannel->set3DMinMaxDistance(0.0f, 0.0f); // disable attenuation
|
||||||
setSoundPos(musicChannel, 0, 0);
|
|
||||||
setSoundRelative(musicChannel, true);
|
setSoundRelative(musicChannel, true);
|
||||||
|
setSoundPos(musicChannel, 0, 0);
|
||||||
|
|
||||||
result = musicChannel->setPaused(false); // This is where the sound really starts.
|
result = musicChannel->setPaused(false); // This is where the sound really starts.
|
||||||
checkError();
|
checkError();
|
||||||
|
|
Loading…
Add table
Reference in a new issue