parent
9b4115a7e5
commit
c4525059ce
@ -0,0 +1,10 @@
|
||||
# Try to find the VORBISFILE library
|
||||
# VORBISFILE_FOUND - system has VORBISFILE
|
||||
# VORBISFILE_INCLUDE_DIR - the VORBISFILE include directory
|
||||
# VORBISFILE_LIBRARY - the VORBISFILE library
|
||||
|
||||
FIND_PATH(VORBISFILE_INCLUDE_DIR NAMES vorbis/vorbisfile.h)
|
||||
FIND_LIBRARY(VORBISFILE_LIBRARY NAMES vorbisfile)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(VORBISFILE DEFAULT_MSG VORBISFILE_LIBRARY VORBISFILE_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(VORBISFILE_LIBRARY VORBISFILE_INCLUDE_DIR)
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_SOUND_DECLARATIONS_H
|
||||
#define FRAMEWORK_SOUND_DECLARATIONS_H
|
||||
|
||||
#include <framework/global.h>
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
class SoundManager;
|
||||
class SoundSource;
|
||||
class SoundBuffer;
|
||||
class SoundFile;
|
||||
class StreamSoundSource;
|
||||
class OggSoundFile;
|
||||
|
||||
typedef std::shared_ptr<SoundSource> SoundSourcePtr;
|
||||
typedef std::shared_ptr<SoundFile> SoundFilePtr;
|
||||
typedef std::shared_ptr<SoundBuffer> SoundBufferPtr;
|
||||
typedef std::shared_ptr<StreamSoundSource> StreamSoundSourcePtr;
|
||||
typedef std::shared_ptr<OggSoundFile> OggSoundFilePtr;
|
||||
|
||||
#endif
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "oggsoundfile.h"
|
||||
|
||||
OggSoundFile::OggSoundFile(const FileStreamPtr& fileStream) : SoundFile(fileStream)
|
||||
{
|
||||
memset(&m_vorbisFile, 0, sizeof(m_vorbisFile));
|
||||
}
|
||||
|
||||
OggSoundFile::~OggSoundFile()
|
||||
{
|
||||
ov_clear(&m_vorbisFile);
|
||||
}
|
||||
|
||||
bool OggSoundFile::prepareOgg()
|
||||
{
|
||||
ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell };
|
||||
ov_open_callbacks(m_file.get(), &m_vorbisFile, 0, 0, callbacks);
|
||||
|
||||
vorbis_info* vi = ov_info(&m_vorbisFile, -1);
|
||||
if(!vi) {
|
||||
logError("ogg file not supported: ", m_file->name());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_channels = vi->channels;
|
||||
m_rate = vi->rate;
|
||||
m_bps = 16;
|
||||
m_size = ov_pcm_total(&m_vorbisFile, -1) * 2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int OggSoundFile::read(void *buffer, int bufferSize)
|
||||
{
|
||||
char* bytesBuffer = reinterpret_cast<char*>(buffer);
|
||||
int section = 0;
|
||||
size_t totalBytesRead = 0;
|
||||
|
||||
while(bufferSize > 0) {
|
||||
size_t bytesToRead = bufferSize;
|
||||
long bytesRead = ov_read(&m_vorbisFile, bytesBuffer, bytesToRead, 0, 2, 1, §ion);
|
||||
if(bytesRead == 0)
|
||||
break;
|
||||
|
||||
bufferSize -= bytesRead;
|
||||
bytesBuffer += bytesRead;
|
||||
totalBytesRead += bytesRead;
|
||||
}
|
||||
|
||||
return totalBytesRead;
|
||||
}
|
||||
|
||||
void OggSoundFile::reset()
|
||||
{
|
||||
ov_pcm_seek(&m_vorbisFile, 0);
|
||||
}
|
||||
|
||||
size_t OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
|
||||
{
|
||||
FileStream *file = static_cast<FileStream*>(source);
|
||||
return file->read(ptr, size, nmemb);
|
||||
}
|
||||
|
||||
int OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
|
||||
{
|
||||
FileStream *file = static_cast<FileStream*>(source);
|
||||
switch(whence) {
|
||||
case SEEK_SET:
|
||||
if(file->seek(offset))
|
||||
return 0;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if(file->seek(file->tell() + offset))
|
||||
return 0;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if(file->seek(file->size() + offset))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int OggSoundFile::cb_close(void* source)
|
||||
{
|
||||
FileStream *file = static_cast<FileStream*>(source);
|
||||
file->close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
long OggSoundFile::cb_tell(void* source)
|
||||
{
|
||||
FileStream *file = static_cast<FileStream*>(source);
|
||||
return file->tell();
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef OGGSOUNDFILE_H
|
||||
#define OGGSOUNDFILE_H
|
||||
|
||||
#include "soundfile.h"
|
||||
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
class OggSoundFile : public SoundFile
|
||||
{
|
||||
public:
|
||||
OggSoundFile(const FileStreamPtr& fileStream);
|
||||
virtual ~OggSoundFile();
|
||||
|
||||
bool prepareOgg();
|
||||
|
||||
int read(void *buffer, int bufferSize);
|
||||
void reset();
|
||||
|
||||
private:
|
||||
static size_t cb_read(void* ptr, size_t size, size_t nmemb, void* source);
|
||||
static int cb_seek(void* source, ogg_int64_t offset, int whence);
|
||||
static int cb_close(void* source);
|
||||
static long cb_tell(void* source);
|
||||
|
||||
OggVorbis_File m_vorbisFile;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "soundbuffer.h"
|
||||
#include "soundfile.h"
|
||||
|
||||
#include <framework/util/databuffer.h>
|
||||
|
||||
SoundBuffer::SoundBuffer()
|
||||
{
|
||||
m_bufferId = 0;
|
||||
alGenBuffers(1, &m_bufferId);
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
}
|
||||
|
||||
SoundBuffer::~SoundBuffer()
|
||||
{
|
||||
alDeleteBuffers(1, &m_bufferId);
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
}
|
||||
|
||||
bool SoundBuffer::loadSoundFile(const SoundFilePtr& soundFile)
|
||||
{
|
||||
ALenum format = soundFile->getSampleFormat();
|
||||
if(format == AL_UNDETERMINED) {
|
||||
logError("unable to determine sample format for '", soundFile->getName(), "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
DataBuffer<char> samples(soundFile->getSize());
|
||||
int read = soundFile->read(&samples[0], soundFile->getSize());
|
||||
if(read <= 0) {
|
||||
logError("unable to fill audio buffer data for '", soundFile->getName(), "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
alBufferData(m_bufferId, format, &samples[0], soundFile->getSize(), soundFile->getRate());
|
||||
ALenum err = alGetError();
|
||||
if(err != AL_NO_ERROR) {
|
||||
logError("unable to fill audio buffer data for '", soundFile->getName(), "': ", alGetString(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SOUNDBUFFER_H
|
||||
#define SOUNDBUFFER_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class SoundBuffer
|
||||
{
|
||||
public:
|
||||
SoundBuffer();
|
||||
~SoundBuffer();
|
||||
|
||||
bool loadSoundFile(const SoundFilePtr& soundFile);
|
||||
|
||||
int getBufferId() { return m_bufferId; }
|
||||
|
||||
private:
|
||||
ALuint m_bufferId;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "soundfile.h"
|
||||
#include "oggsoundfile.h"
|
||||
#include <framework/core/resourcemanager.h>
|
||||
|
||||
SoundFile::SoundFile(const FileStreamPtr& fileStream)
|
||||
{
|
||||
m_file = fileStream;
|
||||
}
|
||||
|
||||
SoundFilePtr SoundFile::loadSoundFile(const std::string& filename)
|
||||
{
|
||||
FileStreamPtr file = g_resources.openFile(filename);
|
||||
if(!file) {
|
||||
logTraceError("unable to open ", filename);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char magic[4];
|
||||
file->read(magic, 4);
|
||||
file->seek(0);
|
||||
|
||||
SoundFilePtr soundFile;
|
||||
if(strncmp(magic, "OggS", 4) == 0) {
|
||||
OggSoundFilePtr oggSoundFile = OggSoundFilePtr(new OggSoundFile(file));
|
||||
if(oggSoundFile->prepareOgg())
|
||||
soundFile = oggSoundFile;
|
||||
} else
|
||||
logError("unknown sound file format ", filename);
|
||||
|
||||
return soundFile;
|
||||
}
|
||||
|
||||
ALenum SoundFile::getSampleFormat()
|
||||
{
|
||||
if(m_channels == 2) {
|
||||
if(m_bps == 16)
|
||||
return AL_FORMAT_STEREO16;
|
||||
else if(m_bps == 8)
|
||||
return AL_FORMAT_STEREO8;
|
||||
} else if(m_channels == 1) {
|
||||
if(m_bps == 16)
|
||||
return AL_FORMAT_MONO16;
|
||||
else if(m_bps == 8)
|
||||
return AL_FORMAT_MONO8;
|
||||
}
|
||||
return AL_UNDETERMINED;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SOUNDFILE_H
|
||||
#define SOUNDFILE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/core/filestream.h>
|
||||
|
||||
class SoundFile
|
||||
{
|
||||
public:
|
||||
SoundFile(const FileStreamPtr& fileStream);
|
||||
virtual ~SoundFile() { }
|
||||
static SoundFilePtr loadSoundFile(const std::string& filename);
|
||||
|
||||
virtual int read(void *buffer, int bufferSize) = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
ALenum getSampleFormat();
|
||||
|
||||
int getChannels() { return m_channels; }
|
||||
int getRate() { return m_rate; }
|
||||
int getBps() { return m_bps; }
|
||||
int getSize() { return m_size; }
|
||||
std::string getName() { return m_file ? m_file->name() : std::string(); }
|
||||
|
||||
protected:
|
||||
FileStreamPtr m_file;
|
||||
int m_channels;
|
||||
int m_rate;
|
||||
int m_bps;
|
||||
int m_size;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "soundmanager.h"
|
||||
#include "soundsource.h"
|
||||
#include "soundbuffer.h"
|
||||
#include "soundfile.h"
|
||||
#include "streamsoundsource.h"
|
||||
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
SoundManager g_sounds;
|
||||
|
||||
void SoundManager::init()
|
||||
{
|
||||
m_run = false;
|
||||
|
||||
m_device = alcOpenDevice(NULL);
|
||||
if(!m_device) {
|
||||
logError("unable to open audio device");
|
||||
return;
|
||||
}
|
||||
|
||||
m_context = alcCreateContext(m_device, NULL);
|
||||
if(!m_context) {
|
||||
logError("unable to create audio context: ", alcGetString(m_device, alcGetError(m_device)));
|
||||
return;
|
||||
}
|
||||
|
||||
alcMakeContextCurrent(m_context);
|
||||
m_thread = std::thread(std::bind(&SoundManager::audioThread, &g_sounds));
|
||||
while(!m_run)
|
||||
g_clock.sleep(1);
|
||||
|
||||
m_musicEnabled = true;
|
||||
m_soundEnabled = true;
|
||||
|
||||
/*
|
||||
g_eventDispatcher.scheduleEvent([this] {
|
||||
play("/test.ogg");
|
||||
}, 10);
|
||||
*/
|
||||
}
|
||||
|
||||
void SoundManager::terminate()
|
||||
{
|
||||
m_run = false;
|
||||
m_thread.join();
|
||||
|
||||
m_sources.clear();
|
||||
m_buffers.clear();
|
||||
m_musicSource = nullptr;
|
||||
m_currentMusic = "";
|
||||
|
||||
m_musicEnabled = false;
|
||||
m_soundEnabled = false;
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
|
||||
if(m_context) {
|
||||
alcDestroyContext(m_context);
|
||||
m_context = nullptr;
|
||||
}
|
||||
|
||||
if(m_device) {
|
||||
alcCloseDevice(m_device);
|
||||
m_device = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::audioThread()
|
||||
{
|
||||
m_run = true;
|
||||
while(m_run) {
|
||||
//TODO: use condition variable
|
||||
g_clock.sleep(30);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::update()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
static ticks_t lastUpdate = 0;
|
||||
ticks_t now = g_clock.asyncTicks();
|
||||
|
||||
if(now - lastUpdate < 300)
|
||||
return;
|
||||
lastUpdate = now;
|
||||
|
||||
for(auto it = m_sources.begin(); it != m_sources.end();) {
|
||||
SoundSourcePtr source = *it;
|
||||
|
||||
source->update();
|
||||
|
||||
if(!source->isPlaying())
|
||||
it = m_sources.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if(m_musicSource) {
|
||||
m_musicSource->update();
|
||||
if(!m_musicSource->isPlaying())
|
||||
m_musicSource = nullptr;
|
||||
}
|
||||
|
||||
if(m_context) {
|
||||
alcProcessContext(m_context);
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::preload(const std::string& filename)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
auto it = m_buffers.find(filename);
|
||||
if(it != m_buffers.end())
|
||||
return;
|
||||
|
||||
SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
|
||||
|
||||
// only keep small files
|
||||
if(soundFile->getSize() > MAX_CACHE_SIZE)
|
||||
return;
|
||||
|
||||
SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
|
||||
if(buffer->loadSoundFile(soundFile))
|
||||
m_buffers[filename] = buffer;
|
||||
}
|
||||
|
||||
void SoundManager::enableSound(bool enable)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(!isAudioEnabled())
|
||||
return;
|
||||
}
|
||||
|
||||
void SoundManager::play(const std::string& filename)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(!m_soundEnabled)
|
||||
return;
|
||||
|
||||
SoundSourcePtr soundSource = createSoundSource(filename);
|
||||
if(!soundSource) {
|
||||
logError("unable to play '", filename, "'");
|
||||
return;
|
||||
}
|
||||
|
||||
soundSource->setRelative(true);
|
||||
soundSource->play();
|
||||
|
||||
m_sources.push_back(soundSource);
|
||||
}
|
||||
|
||||
void SoundManager::enableMusic(bool enable)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(!isAudioEnabled())
|
||||
return;
|
||||
|
||||
m_musicEnabled = enable;
|
||||
|
||||
if(enable)
|
||||
playMusic(m_currentMusic);
|
||||
else
|
||||
m_musicSource = nullptr;
|
||||
}
|
||||
|
||||
void SoundManager::playMusic(const std::string& filename, bool fade)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if(m_currentMusic == filename && m_musicSource)
|
||||
return;
|
||||
m_currentMusic = filename;
|
||||
|
||||
if(!m_musicEnabled)
|
||||
return;
|
||||
|
||||
if(filename.empty()) {
|
||||
m_musicSource = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::stopMusic(float fadetime)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
}
|
||||
|
||||
SoundSourcePtr SoundManager::createSoundSource(const std::string& filename)
|
||||
{
|
||||
SoundSourcePtr soundSource;
|
||||
|
||||
auto it = m_buffers.find(filename);
|
||||
if(it != m_buffers.end()) {
|
||||
soundSource = SoundSourcePtr(new SoundSource);
|
||||
soundSource->setBuffer(it->second);
|
||||
} else {
|
||||
SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
|
||||
if(!soundFile)
|
||||
return nullptr;
|
||||
|
||||
if(soundFile->getSize() <= MAX_CACHE_SIZE) {
|
||||
soundSource = SoundSourcePtr(new SoundSource);
|
||||
SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
|
||||
buffer->loadSoundFile(soundFile);
|
||||
soundSource->setBuffer(buffer);
|
||||
m_buffers[filename] = buffer;
|
||||
logWarning("uncached sound '", filename, "' requested to be played");
|
||||
} else {
|
||||
StreamSoundSourcePtr streamSoundSource(new StreamSoundSource);
|
||||
streamSoundSource->setSoundFile(soundFile);
|
||||
soundSource = streamSoundSource;
|
||||
}
|
||||
}
|
||||
|
||||
return soundSource;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SOUNDMANAGER_H
|
||||
#define SOUNDMANAGER_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class SoundManager
|
||||
{
|
||||
enum {
|
||||
MAX_CACHE_SIZE = 10000000
|
||||
};
|
||||
|
||||
public:
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
void audioThread();
|
||||
|
||||
void update();
|
||||
|
||||
void preload(const std::string& filename);
|
||||
|
||||
void enableSound(bool enable);
|
||||
void play(const std::string& filename);
|
||||
|
||||
void enableMusic(bool enable);
|
||||
void playMusic(const std::string& filename, bool fade = false);
|
||||
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:
|
||||
SoundSourcePtr createSoundSource(const std::string& filename);
|
||||
ALuint loadFileIntoBuffer(const SoundFilePtr& soundFile);
|
||||
|
||||
std::map<std::string, SoundBufferPtr> m_buffers;
|
||||
std::vector<SoundSourcePtr> m_sources;
|
||||
StreamSoundSourcePtr m_musicSource;
|
||||
ALCdevice *m_device;
|
||||
ALCcontext *m_context;
|
||||
std::thread m_thread;
|
||||
std::atomic<bool> m_run;
|
||||
std::recursive_mutex m_mutex;
|
||||
Boolean<false> m_musicEnabled;
|
||||
Boolean<false> m_soundEnabled;
|
||||
std::string m_currentMusic;
|
||||
};
|
||||
|
||||
extern SoundManager g_sounds;
|
||||
|
||||
#endif
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "soundsource.h"
|
||||
#include "soundbuffer.h"
|
||||
|
||||
SoundSource::SoundSource()
|
||||
{
|
||||
m_sourceId = 0;
|
||||
alGenSources(1, &m_sourceId);
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
setReferenceDistance(128);
|
||||
}
|
||||
|
||||
SoundSource::~SoundSource()
|
||||
{
|
||||
stop();
|
||||
alDeleteSources(1, &m_sourceId);
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
}
|
||||
|
||||
void SoundSource::play()
|
||||
{
|
||||
alSourcePlay(m_sourceId);
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
}
|
||||
|
||||
void SoundSource::stop()
|
||||
{
|
||||
alSourceStop(m_sourceId);
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
if(m_buffer) {
|
||||
alSourcei(m_sourceId, AL_BUFFER, AL_NONE);
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
m_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool SoundSource::isPlaying()
|
||||
{
|
||||
ALint state = AL_PLAYING;
|
||||
alGetSourcei(m_sourceId, AL_SOURCE_STATE, &state);
|
||||
return state != AL_STOPPED;
|
||||
}
|
||||
|
||||
void SoundSource::setBuffer(const SoundBufferPtr& buffer)
|
||||
{
|
||||
alSourcei(m_sourceId, AL_BUFFER, buffer->getBufferId());
|
||||
assert(alGetError() == AL_NO_ERROR);
|
||||
m_buffer = buffer;
|
||||
}
|
||||
|
||||
void SoundSource::setLooping(bool looping)
|
||||
{
|
||||
alSourcei(m_sourceId, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
|
||||
}
|
||||
|
||||
void SoundSource::setRelative(bool relative)
|
||||
{
|
||||
alSourcei(m_sourceId, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE);
|
||||
}
|
||||
|
||||
void SoundSource::setReferenceDistance(float distance)
|
||||
{
|
||||
alSourcef(m_sourceId, AL_REFERENCE_DISTANCE, distance);
|
||||
}
|
||||
|
||||
void SoundSource::setGain(float gain)
|
||||
{
|
||||
alSourcef(m_sourceId, AL_GAIN, gain);
|
||||
}
|
||||
|
||||
void SoundSource::setPitch(float pitch)
|
||||
{
|
||||
alSourcef(m_sourceId, AL_PITCH, pitch);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SOUNDSOURCE_H
|
||||
#define SOUNDSOURCE_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class SoundSource
|
||||
{
|
||||
public:
|
||||
SoundSource();
|
||||
virtual ~SoundSource();
|
||||
|
||||
void play();
|
||||
void stop();
|
||||
|
||||
bool isPlaying();
|
||||
|
||||
void setBuffer(const SoundBufferPtr& buffer);
|
||||
virtual void setLooping(bool looping);
|
||||
void setRelative(bool relative);
|
||||
void setReferenceDistance(float distance);
|
||||
void setGain(float gain);
|
||||
void setPitch(float pitch);
|
||||
|
||||
// TODO: velocity, position
|
||||
|
||||
protected:
|
||||
virtual void update() { }
|
||||
friend class SoundManager;
|
||||
|
||||
ALuint m_sourceId;
|
||||
SoundBufferPtr m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "streamsoundsource.h"
|
||||
#include "soundbuffer.h"
|
||||
#include "soundfile.h"
|
||||
|
||||
#include <framework/util/databuffer.h>
|
||||
#include <framework/core/clock.h>
|
||||
|
||||
StreamSoundSource::StreamSoundSource()
|
||||
{
|
||||
for(auto& buffer : m_buffers)
|
||||
buffer = SoundBufferPtr(new SoundBuffer);
|
||||
m_fadeState = NoFading;
|
||||
}
|
||||
|
||||
StreamSoundSource::~StreamSoundSource()
|
||||
{
|
||||
stop();
|
||||
|
||||
ALint queued;
|
||||
alGetSourcei(m_sourceId, AL_BUFFERS_QUEUED, &queued);
|
||||
for(int i = 0; i < queued; ++i) {
|
||||
ALuint buffer;
|
||||
alSourceUnqueueBuffers(m_sourceId, 1, &buffer);
|
||||
}
|
||||
m_buffers.fill(nullptr);
|
||||
}
|
||||
|
||||
void StreamSoundSource::setSoundFile(const SoundFilePtr& soundFile)
|
||||
{
|
||||
m_soundFile = soundFile;
|
||||
|
||||
ALint queued;
|
||||
alGetSourcei(m_sourceId, AL_BUFFERS_QUEUED, &queued);
|
||||
for(int i = 0; i < STREAM_FRAGMENTS - queued; ++i) {
|
||||
if(!fillBufferAndQueue(m_buffers[i]->getBufferId()))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void StreamSoundSource::update()
|
||||
{
|
||||
ALint processed = 0;
|
||||
alGetSourcei(m_sourceId, AL_BUFFERS_PROCESSED, &processed);
|
||||
for(ALint i = 0; i < processed; ++i) {
|
||||
ALuint buffer;
|
||||
alSourceUnqueueBuffers(m_sourceId, 1, &buffer);
|
||||
//SoundManager::check_al_error("Couldn't unqueue audio buffer: ");
|
||||
|
||||
if(!fillBufferAndQueue(buffer))
|
||||
break;
|
||||
}
|
||||
|
||||
if(!isPlaying()) {
|
||||
if(processed == 0 || !m_looping)
|
||||
return;
|
||||
|
||||
// we might have to restart the source if we had a buffer underrun
|
||||
//log_info << "Restarting audio source because of buffer underrun" << std::endl;
|
||||
//play();
|
||||
}
|
||||
|
||||
float realTime = g_clock.asyncTime();
|
||||
if(m_fadeState == FadingOn) {
|
||||
float time = realTime - m_fadeStartTime;
|
||||
if(time >= m_fadeTime) {
|
||||
setGain(1.0);
|
||||
m_fadeState = NoFading;
|
||||
} else {
|
||||
setGain(time / m_fadeTime);
|
||||
}
|
||||
} else if(m_fadeState == FadingOff) {
|
||||
float time = realTime - m_fadeStartTime;
|
||||
if(time >= m_fadeTime) {
|
||||
stop();
|
||||
m_fadeState = NoFading;
|
||||
} else {
|
||||
setGain((m_fadeTime - time) / m_fadeTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool StreamSoundSource::fillBufferAndQueue(ALuint buffer)
|
||||
{
|
||||
// fill buffer
|
||||
DataBuffer<char> bufferData(STREAM_FRAGMENT_SIZE);
|
||||
|
||||
int bytesRead = 0;
|
||||
do {
|
||||
bytesRead += m_soundFile->read(&bufferData[bytesRead], STREAM_FRAGMENT_SIZE - bytesRead);
|
||||
|
||||
// end of sound file
|
||||
if(bytesRead < STREAM_FRAGMENT_SIZE) {
|
||||
if(m_looping)
|
||||
m_soundFile->reset();
|
||||
else
|
||||
break;
|
||||
}
|
||||
} while(bytesRead < STREAM_FRAGMENT_SIZE);
|
||||
|
||||
if(bytesRead > 0) {
|
||||
ALenum format = m_soundFile->getSampleFormat();
|
||||
alBufferData(buffer, format, &bufferData[0], bytesRead, m_soundFile->getRate());
|
||||
ALenum err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
logError("unable to refill audio buffer for '", m_soundFile->getName(), "': ", alGetString(err));
|
||||
|
||||
alSourceQueueBuffers(m_sourceId, 1, &buffer);
|
||||
err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
logError("unable to queue audio buffer for '", m_soundFile->getName(), "': ", alGetString(err));
|
||||
}
|
||||
|
||||
// return false if there aren't more buffers to fill
|
||||
return bytesRead >= STREAM_FRAGMENT_SIZE;
|
||||
}
|
||||
|
||||
void StreamSoundSource::setFading(FadeState state, float fadeTime)
|
||||
{
|
||||
m_fadeState = state;
|
||||
m_fadeTime = fadeTime;
|
||||
m_fadeStartTime = g_clock.asyncTime();
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef STREAMSOUNDSOURCE_H
|
||||
#define STREAMSOUNDSOURCE_H
|
||||
|
||||
#include "soundsource.h"
|
||||
|
||||
class StreamSoundSource : public SoundSource
|
||||
{
|
||||
enum {
|
||||
STREAM_BUFFER_SIZE = 1024 * 500,
|
||||
STREAM_FRAGMENTS = 5,
|
||||
STREAM_FRAGMENT_SIZE = STREAM_BUFFER_SIZE / STREAM_FRAGMENTS
|
||||
};
|
||||
|
||||
public:
|
||||
enum FadeState { NoFading, FadingOn, FadingOff };
|
||||
|
||||
StreamSoundSource();
|
||||
virtual ~StreamSoundSource();
|
||||
|
||||
void setSoundFile(const SoundFilePtr& soundFile);
|
||||
|
||||
void setFading(FadeState state, float fadetime);
|
||||
FadeState getFadeState() { return m_fadeState; }
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
bool fillBufferAndQueue(ALuint buffer);
|
||||
|
||||
SoundFilePtr m_soundFile;
|
||||
std::array<SoundBufferPtr,STREAM_FRAGMENTS> m_buffers;
|
||||
FadeState m_fadeState;
|
||||
float m_fadeStartTime;
|
||||
float m_fadeTime;
|
||||
Boolean<false> m_looping;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in new issue