Update sound engine with some sound fixes

* Refactor client module
This commit is contained in:
Eduardo Bart 2013-01-16 16:46:42 -02:00
parent 52ede065fc
commit 62cd3d04e1
11 changed files with 223 additions and 174 deletions

View File

@ -1,30 +1,33 @@
Client = {} local musicFilename = "startup"
local musicChannel = g_sounds.getChannel(1)
local musicFilename = "startup.ogg" function setMusic(filename)
function Client.setMusic(filename)
musicFilename = filename musicFilename = filename
g_sounds.stopMusic(0)
if not g_game.isOnline() then if not g_game.isOnline() then
g_sounds.playMusic(musicFilename, 3) musicChannel:stop()
musicChannel:enqueue(musicFilename, 3)
end end
end end
function Client.reloadScripts() function reloadScripts()
g_textures.clearTexturesCache()
g_modules.reloadModules() g_modules.reloadModules()
dofile '/otclientrc' dofile('/' .. g_app.getCompactName() .. 'rc')
local message = tr('All modules and scripts were reloaded.') local message = tr('All modules and scripts were reloaded.')
modules.game_textmessage.displayGameMessage(message) modules.game_textmessage.displayGameMessage(message)
print(message) print(message)
end end
function Client.startup() function startup()
-- Play startup music (The Silver Tree, by Mattias Westlund) -- Play startup music (The Silver Tree, by Mattias Westlund)
g_sounds.playMusic(musicFilename, 3) musicChannel:enqueue(musicFilename, 3)
connect(g_game, { onGameStart = function() g_sounds.stopMusic(3) end }) connect(g_game, { onGameStart = function() musicChannel:stop(3) end })
connect(g_game, { onGameEnd = function() g_sounds.playMusic(musicFilename, 3) end }) connect(g_game, { onGameEnd = function()
g_sounds.stopAll()
musicChannel:enqueue(musicFilename, 3)
end })
-- Check for startup errors -- Check for startup errors
local errtitle = nil local errtitle = nil
@ -44,7 +47,7 @@ function Client.startup()
end end
end end
function Client.init() function init()
g_window.setMinimumSize({ width = 600, height = 480 }) g_window.setMinimumSize({ width = 600, height = 480 })
g_sounds.preload(musicFilename) g_sounds.preload(musicFilename)
@ -62,6 +65,8 @@ function Client.init()
local defaultPos = { x = (displaySize.width - size.width)/2, local defaultPos = { x = (displaySize.width - size.width)/2,
y = (displaySize.height - size.height)/2 } y = (displaySize.height - size.height)/2 }
local pos = g_settings.getPoint('window-pos', defaultPos) local pos = g_settings.getPoint('window-pos', defaultPos)
pos.x = math.max(pos.x, 0)
pos.y = math.max(pos.y, 0)
g_window.move(pos) g_window.move(pos)
-- window maximized? -- window maximized?
@ -69,23 +74,25 @@ function Client.init()
if maximized then g_window.maximize() end if maximized then g_window.maximize() end
end end
g_window.setTitle('OTClient') g_window.setTitle(g_app.getName())
g_window.setIcon(resolvepath('clienticon.png')) g_window.setIcon(resolvepath('clienticon'))
g_keyboard.bindKeyDown('Ctrl+Shift+R', Client.reloadScripts)
connect(g_app, { onRun = Client.startup }) -- poll resize events
g_window.poll()
g_keyboard.bindKeyDown('Ctrl+Shift+R', reloadScripts)
connect(g_app, { onRun = startup })
end end
function Client.terminate() function terminate()
-- save window configs -- save window configs
g_settings.set('window-size', g_window.getUnmaximizedSize()) g_settings.set('window-size', g_window.getUnmaximizedSize())
g_settings.set('window-pos', g_window.getUnmaximizedPos()) g_settings.set('window-pos', g_window.getUnmaximizedPos())
g_settings.set('window-maximized', g_window.isMaximized()) g_settings.set('window-maximized', g_window.isMaximized())
local protocolVersion = g_game.getProtocolVersion() local clientVersion = g_game.getProtocolVersion()
if protocolVersion ~= 0 then if clientVersion ~= 0 then
g_settings.set('protocol-version', protocolVersion) g_settings.set('client-version', clientVersion)
end end
Client = nil
end end

View File

@ -4,6 +4,10 @@ Module
author: edubart author: edubart
website: www.otclient.info website: www.otclient.info
reloadable: false reloadable: false
sandboxed: true
scripts: [ client ]
@onLoad: init()
@onUnload: terminate()
load-later: load-later:
- client_skins - client_skins
@ -18,9 +22,3 @@ Module
- client_exit - client_exit
//- client_stats //- client_stats
@onLoad: |
dofile 'client'
Client.init()
@onUnload: |
Client.terminate()

View File

@ -184,7 +184,7 @@ function Options.setOption(key, value)
modules.game_interface.updateStretchShrink() modules.game_interface.updateStretchShrink()
end) end)
elseif key == 'enableMusic' then elseif key == 'enableMusic' then
g_sounds.enableMusic(value) g_sounds.enableAudio(value)
elseif key == 'showLeftPanel' then elseif key == 'showLeftPanel' then
addEvent(function() addEvent(function()
modules.game_interface.getLeftPanel():setOn(value) modules.game_interface.getLeftPanel():setOn(value)

View File

@ -426,6 +426,8 @@ if(FRAMEWORK_SOUND)
${CMAKE_CURRENT_LIST_DIR}/sound/oggsoundfile.h ${CMAKE_CURRENT_LIST_DIR}/sound/oggsoundfile.h
${CMAKE_CURRENT_LIST_DIR}/sound/soundbuffer.cpp ${CMAKE_CURRENT_LIST_DIR}/sound/soundbuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/sound/soundbuffer.h ${CMAKE_CURRENT_LIST_DIR}/sound/soundbuffer.h
${CMAKE_CURRENT_LIST_DIR}/sound/soundchannel.cpp
${CMAKE_CURRENT_LIST_DIR}/sound/soundchannel.h
${CMAKE_CURRENT_LIST_DIR}/sound/soundfile.cpp ${CMAKE_CURRENT_LIST_DIR}/sound/soundfile.cpp
${CMAKE_CURRENT_LIST_DIR}/sound/soundfile.h ${CMAKE_CURRENT_LIST_DIR}/sound/soundfile.h
${CMAKE_CURRENT_LIST_DIR}/sound/soundmanager.cpp ${CMAKE_CURRENT_LIST_DIR}/sound/soundmanager.cpp

View File

@ -34,6 +34,14 @@
#include <framework/stdext/net.h> #include <framework/stdext/net.h>
#include <framework/platform/platform.h> #include <framework/platform/platform.h>
#ifdef FW_SOUND
#include <framework/sound/soundmanager.h>
#include <framework/sound/soundsource.h>
#include <framework/sound/soundchannel.h>
#include <framework/sound/combinedsoundsource.h>
#include <framework/sound/streamsoundsource.h>
#endif
#ifdef FW_GRAPHICS #ifdef FW_GRAPHICS
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include <framework/platform/platformwindow.h> #include <framework/platform/platformwindow.h>
@ -759,15 +767,29 @@ void Application::registerLuaFunctions()
// SoundManager // SoundManager
g_lua.registerSingletonClass("g_sounds"); g_lua.registerSingletonClass("g_sounds");
g_lua.bindSingletonFunction("g_sounds", "preload", &SoundManager::preload, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "preload", &SoundManager::preload, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "enableSound", &SoundManager::enableSound, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "play", &SoundManager::play, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "play", &SoundManager::play, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "enableMusic", &SoundManager::enableMusic, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "getChannel", &SoundManager::getChannel, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "playMusic", &SoundManager::playMusic, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "stopAll", &SoundManager::stopAll, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "stopMusic", &SoundManager::stopMusic, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "enableAudio", &SoundManager::enableAudio, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "isMusicEnabled", &SoundManager::isMusicEnabled, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "disableAudio", &SoundManager::disableAudio, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "isSoundEnabled", &SoundManager::isSoundEnabled, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "setAudioEnabled", &SoundManager::setAudioEnabled, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "isAudioEnabled", &SoundManager::isAudioEnabled, &g_sounds); g_lua.bindSingletonFunction("g_sounds", "isAudioEnabled", &SoundManager::isAudioEnabled, &g_sounds);
g_lua.bindSingletonFunction("g_sounds", "getCurrentMusic", &SoundManager::getCurrentMusic, &g_sounds);
g_lua.registerClass<SoundSource>();
g_lua.registerClass<CombinedSoundSource, SoundSource>();
g_lua.registerClass<StreamSoundSource, SoundSource>();
g_lua.registerClass<SoundChannel>();
g_lua.bindClassMemberFunction<SoundChannel>("play", &SoundChannel::play);
g_lua.bindClassMemberFunction<SoundChannel>("stop", &SoundChannel::stop);
g_lua.bindClassMemberFunction<SoundChannel>("enqueue", &SoundChannel::enqueue);
g_lua.bindClassMemberFunction<SoundChannel>("enable", &SoundChannel::enable);
g_lua.bindClassMemberFunction<SoundChannel>("disable", &SoundChannel::disable);
g_lua.bindClassMemberFunction<SoundChannel>("setGain", &SoundChannel::setGain);
g_lua.bindClassMemberFunction<SoundChannel>("getGain", &SoundChannel::getGain);
g_lua.bindClassMemberFunction<SoundChannel>("setEnabled", &SoundChannel::setEnabled);
g_lua.bindClassMemberFunction<SoundChannel>("isEnabled", &SoundChannel::isEnabled);
g_lua.bindClassMemberFunction<SoundChannel>("getId", &SoundChannel::getId);
#endif #endif
#ifdef FW_SQL #ifdef FW_SQL

View File

@ -34,6 +34,7 @@ class SoundManager;
class SoundSource; class SoundSource;
class SoundBuffer; class SoundBuffer;
class SoundFile; class SoundFile;
class SoundChannel;
class StreamSoundSource; class StreamSoundSource;
class CombinedSoundSource; class CombinedSoundSource;
class OggSoundFile; class OggSoundFile;
@ -41,6 +42,7 @@ class OggSoundFile;
typedef stdext::shared_object_ptr<SoundSource> SoundSourcePtr; typedef stdext::shared_object_ptr<SoundSource> SoundSourcePtr;
typedef stdext::shared_object_ptr<SoundFile> SoundFilePtr; typedef stdext::shared_object_ptr<SoundFile> SoundFilePtr;
typedef stdext::shared_object_ptr<SoundBuffer> SoundBufferPtr; typedef stdext::shared_object_ptr<SoundBuffer> SoundBufferPtr;
typedef stdext::shared_object_ptr<SoundChannel> SoundChannelPtr;
typedef stdext::shared_object_ptr<StreamSoundSource> StreamSoundSourcePtr; typedef stdext::shared_object_ptr<StreamSoundSource> StreamSoundSourcePtr;
typedef stdext::shared_object_ptr<CombinedSoundSource> CombinedSoundSourcePtr; typedef stdext::shared_object_ptr<CombinedSoundSource> CombinedSoundSourcePtr;
typedef stdext::shared_object_ptr<OggSoundFile> OggSoundFilePtr; typedef stdext::shared_object_ptr<OggSoundFile> OggSoundFilePtr;

View File

@ -46,21 +46,21 @@ void SoundManager::init()
g_logger.error(stdext::format("unable to create audio context: %s", alcGetString(m_device, alcGetError(m_device)))); g_logger.error(stdext::format("unable to create audio context: %s", alcGetString(m_device, alcGetError(m_device))));
return; return;
} }
alcMakeContextCurrent(m_context);
m_musicEnabled = true; if(alcMakeContextCurrent(m_context) != ALC_TRUE) {
m_soundEnabled = true; g_logger.error(stdext::format("unable to make context current: %s", alcGetString(m_device, alcGetError(m_device))));
return;
}
} }
void SoundManager::terminate() void SoundManager::terminate()
{ {
ensureContext();
m_sources.clear(); m_sources.clear();
m_buffers.clear(); m_buffers.clear();
m_musicSource = nullptr; m_channels.clear();
m_currentMusic = ""; m_audioEnabled = false;
m_musicEnabled = false;
m_soundEnabled = false;
alcMakeContextCurrent(nullptr); alcMakeContextCurrent(nullptr);
@ -85,6 +85,7 @@ void SoundManager::poll()
lastUpdate = now; lastUpdate = now;
ensureContext();
for(auto it = m_sources.begin(); it != m_sources.end();) { for(auto it = m_sources.begin(); it != m_sources.end();) {
SoundSourcePtr source = *it; SoundSourcePtr source = *it;
@ -96,10 +97,8 @@ void SoundManager::poll()
++it; ++it;
} }
if(m_musicSource) { for(auto it : m_channels) {
m_musicSource->update(); it.second->update();
if(!m_musicSource->isPlaying())
m_musicSource = nullptr;
} }
if(m_context) { if(m_context) {
@ -107,18 +106,33 @@ void SoundManager::poll()
} }
} }
void SoundManager::setAudioEnabled(bool enable)
{
if(m_audioEnabled == enable)
return;
m_audioEnabled = enable;
if(!enable) {
ensureContext();
for(const SoundSourcePtr& source : m_sources) {
source->stop();
}
}
}
void SoundManager::preload(std::string filename) void SoundManager::preload(std::string filename)
{ {
filename = g_resources.resolvePath(filename); filename = resolveSoundFile(filename);
auto it = m_buffers.find(filename); auto it = m_buffers.find(filename);
if(it != m_buffers.end()) if(it != m_buffers.end())
return; return;
ensureContext();
SoundFilePtr soundFile = SoundFile::loadSoundFile(filename); SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
// only keep small files // only keep small files
if(soundFile->getSize() > MAX_CACHE_SIZE) if(!soundFile || soundFile->getSize() > MAX_CACHE_SIZE)
return; return;
SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer); SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
@ -126,85 +140,55 @@ void SoundManager::preload(std::string filename)
m_buffers[filename] = buffer; m_buffers[filename] = buffer;
} }
void SoundManager::enableSound(bool enable) SoundSourcePtr SoundManager::play(std::string filename, float fadetime, float gain)
{ {
if(!isAudioEnabled()) if(!m_audioEnabled)
return; return nullptr;
}
void SoundManager::play(std::string filename) ensureContext();
{
if(!m_soundEnabled || filename.empty())
return;
filename = g_resources.resolvePath(filename); if(gain == 0)
gain = 1.0f;
filename = resolveSoundFile(filename);
SoundSourcePtr soundSource = createSoundSource(filename); SoundSourcePtr soundSource = createSoundSource(filename);
if(!soundSource) { if(!soundSource) {
g_logger.error(stdext::format("unable to play '%s'", filename)); g_logger.error(stdext::format("unable to play '%s'", filename));
return; return nullptr;
} }
soundSource->setName(filename);
soundSource->setRelative(true); soundSource->setRelative(true);
soundSource->setGain(gain);
if(fadetime > 0) {
soundSource->setFading(StreamSoundSource::FadingOn, fadetime);
}
soundSource->play(); soundSource->play();
m_sources.push_back(soundSource); m_sources.push_back(soundSource);
return soundSource;
} }
void SoundManager::enableMusic(bool enable) SoundChannelPtr SoundManager::getChannel(int channel)
{ {
if(!isAudioEnabled()) ensureContext();
return; if(!m_channels[channel])
m_channels[channel] = SoundChannelPtr(new SoundChannel(channel));
m_musicEnabled = enable; return m_channels[channel];
if(enable && !m_currentMusic.empty())
playMusic(m_currentMusic, 3.0f);
else
m_musicSource = nullptr;
} }
void SoundManager::playMusic(std::string filename, float fadetime) void SoundManager::stopAll()
{ {
if(filename.empty()) ensureContext();
return; for(const SoundSourcePtr& source : m_sources) {
source->stop();
filename = g_resources.resolvePath(filename);
if(m_currentMusic == filename && m_musicSource)
return;
if(!m_musicEnabled)
return;
if(filename.empty()) {
m_musicSource = nullptr;
return;
} }
m_musicSource = createSoundSource(filename); for(auto it : m_channels) {
if(!m_musicSource) { it.second->stop();
g_logger.error(stdext::format("unable to play '%s'", filename));
return;
}
m_musicSource->setRelative(true);
if(fadetime > 0) {
m_musicSource->setGain(0);
m_musicSource->setFading(StreamSoundSource::FadingOn, fadetime);
}
m_musicSource->play();
}
void SoundManager::stopMusic(float fadetime)
{
if(m_musicSource) {
if(fadetime > 0)
m_musicSource->setFading(StreamSoundSource::FadingOff, 3.0f);
else
m_musicSource->stop();
} }
} }
@ -212,51 +196,69 @@ SoundSourcePtr SoundManager::createSoundSource(const std::string& filename)
{ {
SoundSourcePtr source; SoundSourcePtr source;
auto it = m_buffers.find(filename); try {
if(it != m_buffers.end()) { auto it = m_buffers.find(filename);
source = SoundSourcePtr(new SoundSource); if(it != m_buffers.end()) {
source->setBuffer(it->second);
} else {
SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
if(!soundFile)
return nullptr;
if(soundFile->getSize() <= MAX_CACHE_SIZE) {
source = SoundSourcePtr(new SoundSource); source = SoundSourcePtr(new SoundSource);
SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer); source->setBuffer(it->second);
buffer->fillBuffer(soundFile);
source->setBuffer(buffer);
m_buffers[filename] = buffer;
g_logger.warning(stdext::format("uncached sound '%s' requested to be played", filename));
} else { } else {
StreamSoundSourcePtr streamSource(new StreamSoundSource); SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
streamSource->setSoundFile(soundFile); if(!soundFile)
source = streamSource; return nullptr;
#if defined __linux && !defined OPENGL_ES if(soundFile->getSize() <= MAX_CACHE_SIZE) {
// due to OpenAL implementation bug, stereo buffers are always downmixed to mono on linux systems source = SoundSourcePtr(new SoundSource);
// this is hack to work around the issue SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
// solution taken from http://opensource.creative.com/pipermail/openal/2007-April/010355.html buffer->fillBuffer(soundFile);
if(soundFile->getSampleFormat() == AL_FORMAT_STEREO16) { source->setBuffer(buffer);
CombinedSoundSourcePtr combinedSource(new CombinedSoundSource); m_buffers[filename] = buffer;
g_logger.warning(stdext::format("uncached sound '%s' requested to be played", filename));
} else {
StreamSoundSourcePtr streamSource(new StreamSoundSource);
streamSource->setSoundFile(soundFile);
source = streamSource;
streamSource->downMix(StreamSoundSource::DownMixLeft); #if defined __linux && !defined OPENGL_ES
streamSource->setRelative(true); // due to OpenAL implementation bug, stereo buffers are always downmixed to mono on linux systems
streamSource->setPosition(Point(-128, 0)); // this is hack to work around the issue
combinedSource->addSource(streamSource); // solution taken from http://opensource.creative.com/pipermail/openal/2007-April/010355.html
if(soundFile->getSampleFormat() == AL_FORMAT_STEREO16) {
CombinedSoundSourcePtr combinedSource(new CombinedSoundSource);
streamSource = StreamSoundSourcePtr(new StreamSoundSource); streamSource->downMix(StreamSoundSource::DownMixLeft);
streamSource->setSoundFile(SoundFile::loadSoundFile(filename)); streamSource->setRelative(true);
streamSource->downMix(StreamSoundSource::DownMixRight); streamSource->setPosition(Point(-128, 0));
streamSource->setRelative(true); combinedSource->addSource(streamSource);
streamSource->setPosition(Point(128,0));
combinedSource->addSource(streamSource);
source = combinedSource; streamSource = StreamSoundSourcePtr(new StreamSoundSource);
streamSource->setSoundFile(SoundFile::loadSoundFile(filename));
streamSource->downMix(StreamSoundSource::DownMixRight);
streamSource->setRelative(true);
streamSource->setPosition(Point(128,0));
combinedSource->addSource(streamSource);
source = combinedSource;
}
#endif
} }
#endif
} }
} catch(std::exception& e) {
g_logger.error(stdext::format("failed to load sound source: '%s'", e.what()));
return nullptr;
} }
return source; return source;
} }
std::string SoundManager::resolveSoundFile(std::string file)
{
file = g_resources.guessFileType(file, "ogg");
file = g_resources.resolvePath(file);
return file;
}
void SoundManager::ensureContext()
{
if(m_context)
alcMakeContextCurrent(m_context);
}

View File

@ -24,6 +24,7 @@
#define SOUNDMANAGER_H #define SOUNDMANAGER_H
#include "declarations.h" #include "declarations.h"
#include "soundchannel.h"
//@bindsingleton g_sounds //@bindsingleton g_sounds
class SoundManager class SoundManager
@ -32,38 +33,34 @@ class SoundManager
MAX_CACHE_SIZE = 100000, MAX_CACHE_SIZE = 100000,
POLL_DELAY = 100 POLL_DELAY = 100
}; };
public: public:
void init(); void init();
void terminate(); void terminate();
void poll(); void poll();
void setAudioEnabled(bool enable);
bool isAudioEnabled() { return m_device && m_context && m_audioEnabled ; }
void enableAudio() { setAudioEnabled(true); }
void disableAudio() { setAudioEnabled(true); }
void stopAll();
void preload(std::string filename); void preload(std::string filename);
void enableSound(bool enable); SoundSourcePtr play(std::string filename, float fadetime = 0, float gain = 0);
void play(std::string filename); SoundChannelPtr getChannel(int channel);
void enableMusic(bool enable); std::string resolveSoundFile(std::string file);
void playMusic(std::string filename, float fadetime); void ensureContext();
void stopMusic(float fadetime = 0);
bool isMusicEnabled() { return m_musicEnabled; }
bool isSoundEnabled() { return m_soundEnabled; }
bool isAudioEnabled() { return m_device && m_context; }
std::string getCurrentMusic() { return m_currentMusic; }
private: private:
StreamSoundSourcePtr createStreamSoundSource(const std::string& filename);
SoundSourcePtr createSoundSource(const std::string& filename); SoundSourcePtr createSoundSource(const std::string& filename);
uint loadFileIntoBuffer(const SoundFilePtr& soundFile);
ALCdevice *m_device;
ALCcontext *m_context;
std::unordered_map<std::string, SoundBufferPtr> m_buffers; std::unordered_map<std::string, SoundBufferPtr> m_buffers;
std::vector<SoundSourcePtr> m_sources; std::vector<SoundSourcePtr> m_sources;
SoundSourcePtr m_musicSource; stdext::boolean<true> m_audioEnabled;
ALCdevice *m_device; std::unordered_map<int, SoundChannelPtr> m_channels;
ALCcontext *m_context;
stdext::boolean<false> m_musicEnabled;
stdext::boolean<false> m_soundEnabled;
std::string m_currentMusic;
}; };
extern SoundManager g_sounds; extern SoundManager g_sounds;

View File

@ -28,9 +28,12 @@
SoundSource::SoundSource() SoundSource::SoundSource()
{ {
m_sourceId = 0; m_sourceId = 0;
m_channel = 0;
m_fadeState = NoFading; m_fadeState = NoFading;
m_fadeTime = 0; m_fadeTime = 0;
m_fadeStartTime = 0; m_fadeStartTime = 0;
m_fadeGain = 0;
m_gain = 1.0f;
alGenSources(1, &m_sourceId); alGenSources(1, &m_sourceId);
assert(alGetError() == AL_NO_ERROR); assert(alGetError() == AL_NO_ERROR);
@ -95,6 +98,7 @@ void SoundSource::setReferenceDistance(float distance)
void SoundSource::setGain(float gain) void SoundSource::setGain(float gain)
{ {
alSourcef(m_sourceId, AL_GAIN, gain); alSourcef(m_sourceId, AL_GAIN, gain);
m_gain = gain;
} }
void SoundSource::setPitch(float pitch) void SoundSource::setPitch(float pitch)
@ -114,7 +118,7 @@ void SoundSource::setVelocity(const Point& velocity)
void SoundSource::setFading(FadeState state, float fadeTime) void SoundSource::setFading(FadeState state, float fadeTime)
{ {
float now = g_clock.seconds(); float now = stdext::millis() / 1000.0f;
if(m_fadeState != NoFading) { if(m_fadeState != NoFading) {
float elapsed = now - m_fadeStartTime; float elapsed = now - m_fadeStartTime;
float add; float add;
@ -128,26 +132,30 @@ void SoundSource::setFading(FadeState state, float fadeTime)
m_fadeState = state; m_fadeState = state;
m_fadeTime = fadeTime; m_fadeTime = fadeTime;
m_fadeGain = m_gain;
if(m_fadeState == FadingOn)
setGain(0.0);
} }
void SoundSource::update() void SoundSource::update()
{ {
float now = g_clock.seconds(); float now = stdext::millis() / 1000.0f;
if(m_fadeState == FadingOn) { if(m_fadeState == FadingOn) {
float elapsed = now - m_fadeStartTime; float elapsed = now - m_fadeStartTime;
if(elapsed >= m_fadeTime) { if(elapsed >= m_fadeTime) {
setGain(1.0);
m_fadeState = NoFading; m_fadeState = NoFading;
} else { } else {
setGain(elapsed / m_fadeTime); setGain((elapsed / m_fadeTime) * m_fadeGain);
} }
} else if(m_fadeState == FadingOff) { } else if(m_fadeState == FadingOff) {
float time = now - m_fadeStartTime; float elapsed = now - m_fadeStartTime;
if(time >= m_fadeTime) { if(elapsed >= m_fadeTime) {
setGain(m_fadeGain);
stop(); stop();
m_fadeState = NoFading; m_fadeState = NoFading;
} else { } else {
setGain((m_fadeTime - time) / m_fadeTime); setGain(((m_fadeTime - elapsed) / m_fadeTime) * m_fadeGain);
} }
} }
} }

View File

@ -25,8 +25,9 @@
#include "declarations.h" #include "declarations.h"
#include "soundbuffer.h" #include "soundbuffer.h"
#include <framework/luaengine/luaobject.h>
class SoundSource : public stdext::shared_object class SoundSource : public LuaObject
{ {
protected: protected:
SoundSource(uint sourceId) : m_sourceId(sourceId) { } SoundSource(uint sourceId) : m_sourceId(sourceId) { }
@ -43,6 +44,7 @@ public:
virtual bool isBuffering(); virtual bool isBuffering();
virtual bool isPlaying() { return isBuffering(); } virtual bool isPlaying() { return isBuffering(); }
void setName(const std::string& name) { m_name == name; }
virtual void setLooping(bool looping); virtual void setLooping(bool looping);
virtual void setRelative(bool relative); virtual void setRelative(bool relative);
virtual void setReferenceDistance(float distance); virtual void setReferenceDistance(float distance);
@ -52,18 +54,27 @@ public:
virtual void setVelocity(const Point& velocity); virtual void setVelocity(const Point& velocity);
virtual void setFading(FadeState state, float fadetime); virtual void setFading(FadeState state, float fadetime);
std::string getName() { return m_name; }
uchar getChannel() { return m_channel; }
float getGain() { return m_gain; }
protected: protected:
void setBuffer(const SoundBufferPtr& buffer); void setBuffer(const SoundBufferPtr& buffer);
void setChannel(uchar channel) { m_channel = channel; }
virtual void update(); virtual void update();
friend class SoundManager; friend class SoundManager;
friend class CombinedSoundSource; friend class CombinedSoundSource;
uint m_sourceId; uint m_sourceId;
uchar m_channel;
std::string m_name;
SoundBufferPtr m_buffer; SoundBufferPtr m_buffer;
FadeState m_fadeState; FadeState m_fadeState;
float m_fadeStartTime; float m_fadeStartTime;
float m_fadeTime; float m_fadeTime;
float m_fadeGain;
float m_gain;
}; };
#endif #endif

View File

@ -28,8 +28,8 @@
class StreamSoundSource : public SoundSource class StreamSoundSource : public SoundSource
{ {
enum { enum {
STREAM_BUFFER_SIZE = 1024 * 200, STREAM_BUFFER_SIZE = 1024 * 400,
STREAM_FRAGMENTS = 5, STREAM_FRAGMENTS = 4,
STREAM_FRAGMENT_SIZE = STREAM_BUFFER_SIZE / STREAM_FRAGMENTS STREAM_FRAGMENT_SIZE = STREAM_BUFFER_SIZE / STREAM_FRAGMENTS
}; };