1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-04 10:34:01 +00:00

Merge branch 'posaudio' of file:///Users/User/code/coding/Aquaria_fg_clean

This commit is contained in:
fgenesis 2013-07-26 01:19:26 +01:00
commit 0be960bedb
5 changed files with 51 additions and 14 deletions

View file

@ -2299,6 +2299,7 @@ void DSQ::playPositionalSfx(const std::string &name, const Vector &position, flo
sfx.freq = f; sfx.freq = f;
sfx.name = name; sfx.name = name;
sfx.relative = false; sfx.relative = false;
sfx.positional = true;
sfx.x = position.x; sfx.x = position.x;
sfx.y = position.y; sfx.y = position.y;

View file

@ -2774,6 +2774,7 @@ luaFunc(entity_playSfx)
float fadeOut = lua_tonumber(L, 6); float fadeOut = lua_tonumber(L, 6);
sfx.maxdist = lua_tonumber(L, 7); sfx.maxdist = lua_tonumber(L, 7);
sfx.relative = false; sfx.relative = false;
sfx.positional = true;
h = core->sound->playSfx(sfx); h = core->sound->playSfx(sfx);
if (fadeOut != 0) if (fadeOut != 0)
@ -5944,8 +5945,12 @@ luaFunc(playSfx)
if (sfx.vol <= 0) if (sfx.vol <= 0)
sfx.vol = 1; sfx.vol = 1;
sfx.loops = lua_tointeger(L, 4); sfx.loops = lua_tointeger(L, 4);
if(lua_isnumber(L, 6) && lua_isnumber(L, 7))
{
sfx.x = lua_tonumber(L, 5); sfx.x = lua_tonumber(L, 5);
sfx.y = lua_tonumber(L, 6); sfx.y = lua_tonumber(L, 6);
sfx.positional = true;
}
sfx.maxdist = lua_tonumber(L, 7); sfx.maxdist = lua_tonumber(L, 7);
if(lua_isnoneornil(L, 8)) if(lua_isnoneornil(L, 8))
sfx.relative = (sfx.x == 0 && sfx.y == 0); sfx.relative = (sfx.x == 0 && sfx.y == 0);

View file

@ -69,8 +69,12 @@ public:
~OggDecoder(); ~OggDecoder();
// Start playing on the given channel, with optional looping. // Prepare playing on the given channel.
bool start(ALuint source, bool loop); bool preStart(ALuint source);
// Decodes the first few buffers, starts the actual playback and detaches the decoder
// from the main thread, with optional looping.
void start(bool loop);
// Decode audio into any free buffers. Must be called periodically // Decode audio into any free buffers. Must be called periodically
// on systems without threads; may be called without harm on systems // on systems without threads; may be called without harm on systems
@ -322,10 +326,9 @@ OggDecoder::~OggDecoder()
} }
} }
bool OggDecoder::start(ALuint source, bool loop) bool OggDecoder::preStart(ALuint source)
{ {
this->source = source; this->source = source;
this->loop = loop;
if (fp) { if (fp) {
if (ov_open_callbacks(fp, &vf, NULL, 0, local_OV_CALLBACKS_NOCLOSE) != 0) if (ov_open_callbacks(fp, &vf, NULL, 0, local_OV_CALLBACKS_NOCLOSE) != 0)
@ -387,6 +390,13 @@ bool OggDecoder::start(ALuint source, bool loop)
return false; return false;
} }
return true;
}
void OggDecoder::start(bool loop)
{
this->loop = loop;
playing = true; playing = true;
eof = false; eof = false;
samples_done = 0; samples_done = 0;
@ -394,8 +404,6 @@ bool OggDecoder::start(ALuint source, bool loop)
queue(buffers[i]); queue(buffers[i]);
detachDecoder(this); detachDecoder(this);
return true;
} }
void OggDecoder::update() void OggDecoder::update()
@ -512,7 +520,22 @@ void OggDecoder::queue(ALuint buffer)
if (pcm_size > 0) if (pcm_size > 0)
{ {
alBufferData(buffer, format, pcm_buffer, pcm_size, freq); ALuint fmt = format;
if(channels == 2 && forcemono)
{
signed short *buf = (short*)&pcm_buffer[0];
int numSamples = pcm_size / 2; // 16 bit samples
int j = 0;
for (int i = 0; i < numSamples ; i += 2)
{
// This is in theory not quite correct, but it doesn't add any artifacts or clipping.
// FIXME: Seems that simple and stupid is the method of choice, then... -- FG
buf[j++] = (buf[i] + buf[i+1]) / 2;
}
pcm_size = numSamples;
fmt = AL_FORMAT_MONO16;
}
alBufferData(buffer, fmt, pcm_buffer, pcm_size, freq);
alSourceQueueBuffers(source, 1, &buffer); alSourceQueueBuffers(source, 1, &buffer);
} }
} }
@ -839,7 +862,7 @@ bool OpenALChannel::start(OpenALSound *sound)
decoder = new OggDecoder(sound->getFile()); decoder = new OggDecoder(sound->getFile());
else else
decoder = new OggDecoder(sound->getData(), sound->getSize()); decoder = new OggDecoder(sound->getData(), sound->getSize());
if (!decoder->start(sid, sound->isLooping())) if (!decoder->preStart(sid))
{ {
delete decoder; delete decoder;
decoder = NULL; decoder = NULL;
@ -954,6 +977,11 @@ FMOD_RESULT OpenALChannel::setPaused(const bool _paused, const bool setstate)
} }
else if ((!_paused) && (initial || ((state == AL_INITIAL) || (state == AL_PAUSED)))) else if ((!_paused) && (initial || ((state == AL_INITIAL) || (state == AL_PAUSED))))
{ {
if (initial && decoder)
{
decoder->setForceMono(mindist || maxdist); // HACK: this is set for positional sounds.
decoder->start(sound->isLooping());
}
alSourcePlay(sid); alSourcePlay(sid);
initial = false; initial = false;
SANITY_CHECK_OPENAL_CALL(); SANITY_CHECK_OPENAL_CALL();
@ -1429,6 +1457,8 @@ FMOD_RESULT OpenALSystem::createSound(const char *name_or_data, const FMOD_MODE
alGenBuffers(1, &bid); alGenBuffers(1, &bid);
if (bid != 0) if (bid != 0)
{ {
// FIXME: This needs to stored seperately and fed to the AL on demand,
// converting stereo to mono when it's known whether to do so or not.
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); ((OpenALSound*)*sound)->setNumChannels(format == AL_FORMAT_STEREO16 ? 2 : 1);

View file

@ -1158,9 +1158,9 @@ void *SoundManager::playSfx(const PlaySfx &play)
// 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)
maxdist = 1300; maxdist = 1800;
if(maxdist > 0) if(maxdist > 0 && play.positional)
channel->set3DMinMaxDistance(maxdist * 0.3, maxdist); // HACK: this works reasonably well channel->set3DMinMaxDistance(maxdist * 0.3, maxdist); // HACK: this works reasonably well
else else
channel->set3DMinMaxDistance(0, 0); // no attenuation channel->set3DMinMaxDistance(0, 0); // no attenuation

View file

@ -106,7 +106,7 @@ struct PlaySfx
{ {
PlaySfx() : priority(0.5), handle(0), vol(1), fade(SFT_NONE), PlaySfx() : priority(0.5), handle(0), vol(1), fade(SFT_NONE),
time(0), freq(1), loops(0), channel(BBGE_AUDIO_NOCHANNEL), time(0), freq(1), loops(0), channel(BBGE_AUDIO_NOCHANNEL),
maxdist(0), x(0), y(0), relative(true) {} maxdist(0), x(0), y(0), relative(true), positional(false) {}
std::string name; std::string name;
intptr_t handle; intptr_t handle;
@ -119,7 +119,8 @@ struct PlaySfx
float maxdist; // distance gain attenuation. if 0: use default value, -1: don't attenuate at all float maxdist; // distance gain attenuation. if 0: use default value, -1: don't attenuate at all
SoundFadeType fade; SoundFadeType fade;
float x, y; float x, y;
bool relative; bool relative; // relative to listener?
bool positional; // if true, this indicates that we want positional sound (stereo will be downmixed to mono to make OpenAL happy)
}; };
class SoundHolder; // defined below class SoundHolder; // defined below