summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--CMakeLists.txt4
-rw-r--r--HOWTO-MXE.txt4
-rw-r--r--HOWTO.txt6
-rw-r--r--cmake/FindLibSndFile.cmake23
-rw-r--r--cmake/mxe.cmake14
-rw-r--r--debian/changelog2
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/app/app.cpp11
-rw-r--r--src/common/test/image_test.cpp4
-rw-r--r--src/object/object.cpp4
-rw-r--r--src/sound/oalsound/alsound.cpp164
-rw-r--r--src/sound/oalsound/alsound.h9
-rw-r--r--src/sound/oalsound/buffer.cpp41
-rw-r--r--src/sound/oalsound/buffer.h5
-rw-r--r--src/sound/oalsound/channel.cpp42
-rw-r--r--src/sound/oalsound/channel.h10
-rw-r--r--src/sound/sound.h15
-rw-r--r--src/ui/maindialog.cpp5
-rw-r--r--src/ui/test/CMakeLists.txt2
20 files changed, 281 insertions, 101 deletions
diff --git a/.gitignore b/.gitignore
index bc2649c..0e9774c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,8 @@ Makefile
/Testing
/CTestTestfile.cmake
/src/CBot/tests/CBot_console/bin/
+.kdev4
+*.kdev4
+*.flv
+*.mp4
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2e309d2..aa05134 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,7 +52,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
message(STATUS "Detected GCC version 4.7+")
- set(CXX11_FLAGS "-std=c++11")
+ set(CXX11_FLAGS "-std=gnu++11")
elseif (GCC_VERSION VERSION_GREATER 4.6 OR GCC_VERSION VERSION_EQUAL 4.6)
message(STATUS "Detected GCC version 4.6+")
set(CXX11_FLAGS "-std=c++0x")
@@ -113,6 +113,8 @@ option(GLEW_STATIC "Link statically with GLEW" OFF)
find_package(GLEW REQUIRED)
+include("${colobot_SOURCE_DIR}/cmake/FindLibSndFile.cmake")
+
##
# Additional settings to use when cross-compiling with MXE (http://mxe.cc/)
diff --git a/HOWTO-MXE.txt b/HOWTO-MXE.txt
index 67107bd..4467cd3 100644
--- a/HOWTO-MXE.txt
+++ b/HOWTO-MXE.txt
@@ -49,6 +49,10 @@ libraries and tools.
xz
zlib
+ for audio support:
+ openal
+ libsndfile
+
4. Now `cd' to colobot directory. To cross-compile a CMake project, you have to specify
a CMake toolchain file. MXE has such file in MXE's directory:
usr/i686-pc-mingw32/share/cmake/mxe-conf.cmake
diff --git a/HOWTO.txt b/HOWTO.txt
index c547939..c7ba1a5 100644
--- a/HOWTO.txt
+++ b/HOWTO.txt
@@ -42,8 +42,10 @@ How to...
$ cmake .
$ make
- Note: If you experience problems with OpenGL's extensions, install GLEW library and enable
- it in compilation by setting USE_GLEW to 1 in CMakeLists.txt
+ Note #1: If you experience problems with OpenGL's extensions, install GLEW library and enable
+ it in compilation by setting USE_GLEW to 1 in CMakeLists.txt
+
+ Note #2: For audio support you need libsndfile and openal.
1.3 Other platforms, compilers, etc.
diff --git a/cmake/FindLibSndFile.cmake b/cmake/FindLibSndFile.cmake
new file mode 100644
index 0000000..8666c66
--- /dev/null
+++ b/cmake/FindLibSndFile.cmake
@@ -0,0 +1,23 @@
+# Base Io build system
+# Written by Jeremy Tregunna <jeremy.tregunna@me.com>
+#
+# Find libsndfile.
+
+FIND_PATH(LIBSNDFILE_INCLUDE_DIR sndfile.h)
+
+SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile)
+FIND_LIBRARY(LIBSNDFILE_LIBRARY NAMES ${LIBSNDFILE_NAMES} PATH)
+
+IF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY)
+ SET(LIBSNDFILE_FOUND TRUE)
+ENDIF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY)
+
+IF(LIBSNDFILE_FOUND)
+ IF(NOT LibSndFile_FIND_QUIETLY)
+ MESSAGE(STATUS "Found LibSndFile: ${LIBSNDFILE_LIBRARY}")
+ ENDIF (NOT LibSndFile_FIND_QUIETLY)
+ELSE(LIBSNDFILE_FOUND)
+ IF(LibSndFile_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find sndfile")
+ ENDIF(LibSndFile_FIND_REQUIRED)
+ENDIF (LIBSNDFILE_FOUND)
diff --git a/cmake/mxe.cmake b/cmake/mxe.cmake
index 322ba4a..5502c1b 100644
--- a/cmake/mxe.cmake
+++ b/cmake/mxe.cmake
@@ -12,6 +12,19 @@ if((${CMAKE_CROSSCOMPILING}) AND (DEFINED MSYS))
# Because find package scripts are lame
set(SDLTTF_INCLUDE_DIR ${CMAKE_FIND_ROOT_PATH}/include/SDL)
set(SDLIMAGE_INCLUDE_DIR ${CMAKE_FIND_ROOT_PATH}/include/SDL)
+
+ if (${OPENAL_SOUND})
+ set(OPENAL_MXE_LIBS
+ ${CMAKE_FIND_ROOT_PATH}/lib/libFLAC.a
+ ${CMAKE_FIND_ROOT_PATH}/lib/libvorbis.a
+ ${CMAKE_FIND_ROOT_PATH}/lib/libvorbisenc.a
+ ${CMAKE_FIND_ROOT_PATH}/lib/libvorbisfile.a
+ ${CMAKE_FIND_ROOT_PATH}/lib/libogg.a
+ ${CMAKE_FIND_ROOT_PATH}/lib/libwsock32.a
+ )
+ endif()
+
+ set(MXE_CFLAGS "-DAL_LIBTYPE_STATIC")
set(MXE_LIBS
# For some reason, these have to be absolute paths
${CMAKE_FIND_ROOT_PATH}/lib/libintl.a
@@ -23,6 +36,7 @@ if((${CMAKE_CROSSCOMPILING}) AND (DEFINED MSYS))
${CMAKE_FIND_ROOT_PATH}/lib/libwinmm.a
${CMAKE_FIND_ROOT_PATH}/lib/libdxguid.a
${CMAKE_FIND_ROOT_PATH}/lib/libbz2.a
+ ${OPENAL_MXE_LIBS}
)
else()
set(MXE 0)
diff --git a/debian/changelog b/debian/changelog
index a744226..78baaaa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-colobot (0.1.0~pre-alpha-git-dev~r35faf62-1~OdyX0) UNRELEASED; urgency=low
+colobot (0.1.0~pre-alpha-git-dev~rb50f9ae-1~OdyX0) UNRELEASED; urgency=low
* Initial release. (Closes: #695829)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a90b735..238b8ba 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,5 @@
# Compile flags as defined in global CMakeLists
-set(CMAKE_CXX_FLAGS ${COLOBOT_CXX_FLAGS})
+set(CMAKE_CXX_FLAGS "${COLOBOT_CXX_FLAGS} ${MXE_CFLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE ${COLOBOT_CXX_FLAGS_RELEASE})
set(CMAKE_CXX_FLAGS_DEBUG ${COLOBOT_CXX_FLAGS_DEBUG})
@@ -27,22 +27,18 @@ endif()
set(OPTIONAL_LIBS "")
if (${OPENAL_SOUND})
- if (${MXE})
+ if (${PLATFORM_WINDOWS})
set(OPTIONAL_LIBS
- ${CMAKE_FIND_ROOT_PATH}/lib/libOpenAL32.a
- ${CMAKE_FIND_ROOT_PATH}/lib/libalut.a
+ OpenAL32
)
else()
set(OPTIONAL_LIBS
openal
- alut
)
endif()
endif()
# Additional libraries per platform
-set(PLATFORM_LIBS "")
-
if (${MXE}) # MXE requires special treatment
set(PLATFORM_LIBS ${MXE_LIBS})
elseif (${PLATFORM_WINDOWS})
@@ -199,6 +195,7 @@ ${PNG_LIBRARIES}
${GLEW_LIBRARY}
${Boost_LIBRARIES}
${OPTIONAL_LIBS}
+${LIBSNDFILE_LIBRARY}
${PLATFORM_LIBS}
)
@@ -219,6 +216,7 @@ ${PNG_INCLUDE_DIRS}
${GLEW_INCLUDE_PATH}
${Boost_INCLUDE_DIRS}
${OPTIONAL_INCLUDE_DIRS}
+${LIBSNDFILE_INCLUDE_DIR}
)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/CBot)
diff --git a/src/app/app.cpp b/src/app/app.cpp
index 4a69655..9886b24 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -321,10 +321,17 @@ bool CApplication::Create()
#endif
m_sound->Create(true);
- if (GetProfile().GetLocalProfileString("Resources", "Sound", path))
+ if (GetProfile().GetLocalProfileString("Resources", "Sound", path)) {
m_sound->CacheAll(path);
- else
+ } else {
m_sound->CacheAll(GetDataSubdirPath(DIR_SOUND));
+ }
+
+ if (GetProfile().GetLocalProfileString("Resources", "Music", path)) {
+ m_sound->AddMusicFiles(path);
+ } else {
+ m_sound->AddMusicFiles(GetDataSubdirPath(DIR_MUSIC));
+ }
}
std::string standardInfoMessage =
diff --git a/src/common/test/image_test.cpp b/src/common/test/image_test.cpp
index a98c9cc..09ae4c6 100644
--- a/src/common/test/image_test.cpp
+++ b/src/common/test/image_test.cpp
@@ -19,7 +19,7 @@ int main(int argc, char *argv[])
if (! image.Load(argv[1]))
{
std::string err = image.GetError();
- printf("Error loading '%s': %s\n", err.c_str());
+ printf("Error loading '%s': %s\n", argv[1], err.c_str());
return 1;
}
Gfx::Color color;
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
if (! image.SavePNG(argv[2]))
{
std::string err = image.GetError();
- printf("Error saving PNG '%s': %s\n", err.c_str());
+ printf("Error saving PNG '%s': %s\n", argv[2], err.c_str());
return 2;
}
diff --git a/src/object/object.cpp b/src/object/object.cpp
index afa7815..9615866 100644
--- a/src/object/object.cpp
+++ b/src/object/object.cpp
@@ -6243,12 +6243,12 @@ void CObject::SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV,
void CObject::SetCharacter(Character* character)
{
- memcpy(&m_character, character, sizeof(m_character));
+ memcpy(&m_character, character, sizeof(Character));
}
void CObject::GetCharacter(Character* character)
{
- memcpy(character, &m_character, sizeof(character));
+ memcpy(character, &m_character, sizeof(Character));
}
Character* CObject::GetCharacter()
diff --git a/src/sound/oalsound/alsound.cpp b/src/sound/oalsound/alsound.cpp
index 80e8fe6..2e44eef 100644
--- a/src/sound/oalsound/alsound.cpp
+++ b/src/sound/oalsound/alsound.cpp
@@ -27,7 +27,9 @@ ALSound::ALSound()
mEnabled = false;
m3D = false;
mAudioVolume = 1.0f;
+ mMusicVolume = 1.0f;
mMute = false;
+ mCurrentMusic = nullptr;
auto pointer = CInstanceManager::GetInstancePointer();
if (pointer != nullptr)
CInstanceManager::GetInstancePointer()->AddInstance(CLASS_SOUND, this);
@@ -48,17 +50,21 @@ void ALSound::CleanUp()
if (mEnabled) {
GetLogger()->Info("Unloading files and closing device...\n");
StopAll();
-
- for (auto channel : mChannels) {
- delete channel.second;
- }
+
+ for (auto channel : mChannels) {
+ delete channel.second;
+ }
for (auto item : mSounds) {
delete item.second;
- }
+ }
mEnabled = false;
- alutExit();
+
+ mCurrentMusic->FreeBuffer();
+ delete mCurrentMusic;
+ alcDestroyContext(mContext);
+ alcCloseDevice(mDevice);
}
}
@@ -71,13 +77,21 @@ bool ALSound::Create(bool b3D)
return true;
GetLogger()->Info("Opening audio device...\n");
- if (!alutInit(NULL, NULL)) {
- ALenum error = alutGetError();
- GetLogger()->Error("Could not open audio device! Reason: %s\n", alutGetErrorString(error));
+ mDevice = alcOpenDevice(NULL);
+ if (!mDevice) {
+ GetLogger()->Error("Could not open audio device!\n");
return false;
}
- GetLogger()->Info("Done.\n");
+ mContext = alcCreateContext(mDevice, NULL);
+ if (!mContext) {
+ GetLogger()->Error("Could not create audio context!\n");
+ return false;
+ }
+ alcMakeContextCurrent(mContext);
+
+ mCurrentMusic = new Channel();
+ GetLogger()->Info("Done.\n");
mEnabled = true;
return true;
}
@@ -112,35 +126,35 @@ bool ALSound::GetEnable()
void ALSound::SetAudioVolume(int volume)
{
- alListenerf(AL_GAIN, MIN(static_cast<float>(volume) / MAXVOLUME, 1.0f));
mAudioVolume = MIN(static_cast<float>(volume) / MAXVOLUME, 1.0f);
+ alListenerf(AL_GAIN, mAudioVolume);
}
int ALSound::GetAudioVolume()
{
- float volume;
if ( !mEnabled )
return 0;
- alGetListenerf(AL_GAIN, &volume);
- return volume * MAXVOLUME;
+ return mAudioVolume * MAXVOLUME;
}
void ALSound::SetMusicVolume(int volume)
{
- // TODO stub! Add music support
+ mMusicVolume = MIN(static_cast<float>(volume) / MAXVOLUME, 1.0f);
+ if (mCurrentMusic) {
+ mCurrentMusic->SetVolume(mMusicVolume);
+ }
}
int ALSound::GetMusicVolume()
{
- // TODO stub! Add music support
if ( !mEnabled )
- return 0;
+ return 0.0f;
- return 0;
+ return mMusicVolume * MAXVOLUME;
}
@@ -242,8 +256,7 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
auto it = mChannels.end();
it--;
int i = (*it).first;
- while (++i)
- {
+ while (++i) {
if (mChannels.find(i) == mChannels.end()) {
Channel *chn = new Channel();
// check if channel is ready to play music, if not destroy it and seek free one
@@ -300,29 +313,28 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc
}
int channel;
- bool bAlreadyLoaded;
+ bool bAlreadyLoaded = false;
if (!SearchFreeBuffer(sound, channel, bAlreadyLoaded))
return -1;
-
- bAlreadyLoaded = false;
+
if (!bAlreadyLoaded) {
if (!mChannels[channel]->SetBuffer(mSounds[sound])) {
- mChannels[channel]->SetBuffer(nullptr);
- return -1;
- }
+ mChannels[channel]->SetBuffer(nullptr);
+ return -1;
+ }
}
-
Position(channel, pos);
// setting initial values
- mChannels[channel]->SetStartAmplitude(amplitude);
+ mChannels[channel]->SetStartAmplitude(amplitude * mAudioVolume);
mChannels[channel]->SetStartFrequency(frequency);
mChannels[channel]->SetChangeFrequency(1.0f);
mChannels[channel]->ResetOper();
- mChannels[channel]->SetFrequency(frequency * mChannels[channel]->GetFrequency());
- mChannels[channel]->SetVolume(amplitude);
+ mChannels[channel]->SetFrequency(frequency);
+ mChannels[channel]->SetVolume(amplitude * mAudioVolume);
mChannels[channel]->SetLoop(bLoop);
mChannels[channel]->Play();
+
return channel;
}
@@ -445,36 +457,36 @@ void ALSound::FrameMove(float delta)
for (auto it : mChannels) {
if (!it.second->IsPlaying()) {
continue;
- }
+ }
if (!it.second->HasEnvelope())
continue;
-
+
SoundOper &oper = it.second->GetEnvelope();
- oper.currentTime += delta;
+ oper.currentTime += delta;
progress = oper.currentTime / oper.totalTime;
progress = MIN(progress, 1.0f);
-
+
// setting volume
volume = progress * (oper.finalAmplitude - it.second->GetStartAmplitude());
- it.second->SetVolume(volume + it.second->GetStartAmplitude());
-
- // setting frequency
+ it.second->SetVolume((volume + it.second->GetStartAmplitude()) * mAudioVolume);
+
+ // setting frequency
frequency = progress * (oper.finalFrequency - it.second->GetStartFrequency()) * it.second->GetStartFrequency() * it.second->GetChangeFrequency() * it.second->GetInitFrequency();
it.second->AdjustFrequency(frequency);
if (oper.totalTime <= oper.currentTime) {
if (oper.nextOper == SOPER_LOOP) {
- oper.currentTime = 0.0f;
+ oper.currentTime = 0.0f;
it.second->Play();
} else {
- it.second->SetStartAmplitude(oper.finalAmplitude);
- it.second->SetStartFrequency(oper.finalFrequency);
+ it.second->SetStartAmplitude(oper.finalAmplitude);
+ it.second->SetStartFrequency(oper.finalFrequency);
if (oper.nextOper == SOPER_STOP) {
- it.second->Stop();
+ it.second->Stop();
}
-
- it.second->PopEnvelope();
+
+ it.second->PopEnvelope();
}
}
}
@@ -491,32 +503,86 @@ void ALSound::SetListener(Math::Vector eye, Math::Vector lookat)
bool ALSound::PlayMusic(int rank, bool bRepeat)
{
- // TODO stub! Add music support
+ if (!mEnabled) {
+ return false;
+ }
+
+ if (static_cast<int>(mCurrentMusic->GetSoundType()) != rank) {
+ // check if we have music in cache
+ for (auto music : mMusicCache) {
+ if (static_cast<int>(music->GetSoundType()) == rank) {
+ GetLogger()->Debug("Music loaded from cache\n");
+ mCurrentMusic->SetBuffer(music);
+
+ mCurrentMusic->SetVolume(mMusicVolume);
+ mCurrentMusic->SetLoop(bRepeat);
+ mCurrentMusic->Play();
+ return true;
+ }
+ }
+
+ // we cache only 3 music files
+ if (mMusicCache.size() == 3) {
+ mCurrentMusic->FreeBuffer();
+ mMusicCache.pop_back();
+ }
+
+ if (mMusic.find(rank) == mMusic.end()) {
+ GetLogger()->Info("Requested music %d was not found.\n", rank);
+ return false;
+ }
+
+ Buffer *buffer = new Buffer();
+ mMusicCache.push_front(buffer);
+ buffer->LoadFromFile(mMusic.at(rank), static_cast<Sound>(rank));
+ mCurrentMusic->SetBuffer(buffer);
+ mMusicCache[rank] = buffer;
+ }
+
+ mCurrentMusic->SetVolume(mMusicVolume);
+ mCurrentMusic->SetLoop(bRepeat);
+ mCurrentMusic->Play();
+
return true;
}
bool ALSound::RestartMusic()
{
- // TODO stub! Add music support
+ if (!mEnabled || !mCurrentMusic) {
+ return false;
+ }
+
+ mCurrentMusic->Stop();
+ mCurrentMusic->Play();
return true;
}
void ALSound::StopMusic()
{
- // TODO stub! Add music support
+ if (!mEnabled || !mCurrentMusic) {
+ return;
+ }
+
SuspendMusic();
}
bool ALSound::IsPlayingMusic()
{
- // TODO stub! Add music support
- return true;
+ if (!mEnabled || !mCurrentMusic) {
+ return false;
+ }
+
+ return mCurrentMusic->IsPlaying();
}
void ALSound::SuspendMusic()
{
- // TODO stub! Add music support
+ if (!mEnabled || !mCurrentMusic) {
+ return;
+ }
+
+ mCurrentMusic->Stop();
}
diff --git a/src/sound/oalsound/alsound.h b/src/sound/oalsound/alsound.h
index 7aeec90..530aa5e 100644
--- a/src/sound/oalsound/alsound.h
+++ b/src/sound/oalsound/alsound.h
@@ -22,7 +22,7 @@
#include <map>
#include <string>
-#include <AL/alut.h>
+#include <AL/al.h>
#include "common/iman.h"
#include "common/logger.h"
@@ -87,8 +87,11 @@ class ALSound : public CSoundInterface
bool m3D;
bool mMute;
float mAudioVolume;
- ALCdevice* audioDevice;
- ALCcontext* audioContext;
+ float mMusicVolume;
+ ALCdevice* mDevice;
+ ALCcontext* mContext;
std::map<Sound, Buffer*> mSounds;
std::map<int, Channel*> mChannels;
+ std::deque<Buffer*> mMusicCache;
+ Channel *mCurrentMusic;
};
diff --git a/src/sound/oalsound/buffer.cpp b/src/sound/oalsound/buffer.cpp
index 27da848..d76b24a 100644
--- a/src/sound/oalsound/buffer.cpp
+++ b/src/sound/oalsound/buffer.cpp
@@ -35,26 +35,43 @@ Buffer::~Buffer() {
bool Buffer::LoadFromFile(std::string filename, Sound sound) {
mSound = sound;
-
GetLogger()->Debug("Loading audio file: %s\n", filename.c_str());
- mBuffer = alutCreateBufferFromFile(filename.c_str());
- ALenum error = alutGetError();
- if (error) {
- GetLogger()->Warn("Failed to load file. Reason: %s\n", alutGetErrorString(error));
+ SF_INFO fileInfo;
+ SNDFILE *file = sf_open(filename.c_str(), SFM_READ, &fileInfo);
+
+ GetLogger()->Trace(" channels %d\n", fileInfo.channels);
+ GetLogger()->Trace(" format %d\n", fileInfo.format);
+ GetLogger()->Trace(" frames %d\n", fileInfo.frames);
+ GetLogger()->Trace(" samplerate %d\n", fileInfo.samplerate);
+ GetLogger()->Trace(" sections %d\n", fileInfo.sections);
+
+ if (!file) {
+ GetLogger()->Warn("Could not load file. Reason: %s\n", sf_strerror(file));
mLoaded = false;
return false;
}
- ALint size, bits, channels, freq;
-
- alGetBufferi(mBuffer, AL_SIZE, &size);
- alGetBufferi(mBuffer, AL_BITS, &bits);
- alGetBufferi(mBuffer, AL_CHANNELS, &channels);
- alGetBufferi(mBuffer, AL_FREQUENCY, &freq);
+ alGenBuffers(1, &mBuffer);
+ if (!mBuffer) {
+ GetLogger()->Warn("Could not create audio buffer\n");
+ mLoaded = false;
+ sf_close(file);
+ return false;
+ }
- mDuration = static_cast<ALfloat>(size) * 8 / channels / bits / static_cast<ALfloat>(freq);
+ // read chunks of 4096 samples
+ std::vector<uint16_t> data;
+ std::array<int16_t, 4096> buffer;
+ data.reserve(fileInfo.frames);
+ size_t read = 0;
+ while ((read = sf_read_short(file, buffer.data(), buffer.size())) != 0) {
+ data.insert(data.end(), buffer.begin(), buffer.begin() + read);
+ }
+ sf_close(file);
+ alBufferData(mBuffer, fileInfo.channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, &data.front(), data.size() * sizeof(uint16_t), fileInfo.samplerate);
+ mDuration = static_cast<float>(fileInfo.frames) / fileInfo.samplerate;
mLoaded = true;
return true;
}
diff --git a/src/sound/oalsound/buffer.h b/src/sound/oalsound/buffer.h
index 8c4a2d3..7286deb 100644
--- a/src/sound/oalsound/buffer.h
+++ b/src/sound/oalsound/buffer.h
@@ -19,8 +19,11 @@
#pragma once
#include <string>
+#include <vector>
+#include <array>
-#include <AL/alut.h>
+#include <AL/al.h>
+#include <sndfile.h>
#include "sound/sound.h"
#include "common/logger.h"
diff --git a/src/sound/oalsound/channel.cpp b/src/sound/oalsound/channel.cpp
index 4069313..2b9af9b 100644
--- a/src/sound/oalsound/channel.cpp
+++ b/src/sound/oalsound/channel.cpp
@@ -34,12 +34,15 @@ Channel::Channel() {
mBuffer = nullptr;
mLoop = false;
mInitFrequency = 0.0f;
+ mStartAmplitude = 0.0f;
+ mStartFrequency = 0.0f;
+ mChangeFrequency = 0.0f;
}
Channel::~Channel() {
if (mReady) {
- alSourceStop(mSource);
+ alSourceStop(mSource);
alSourcei(mSource, AL_BUFFER, 0);
alDeleteSources(1, &mSource);
if (alCheck())
@@ -51,7 +54,7 @@ Channel::~Channel() {
bool Channel::Play() {
if (!mReady || mBuffer == nullptr)
return false;
-
+
alSourcei(mSource, AL_LOOPING, static_cast<ALint>(mLoop));
alSourcePlay(mSource);
if (alCheck())
@@ -220,11 +223,12 @@ Sound Channel::GetSoundType() {
bool Channel::SetBuffer(Buffer *buffer) {
if (!mReady)
return false;
-
+
+ Stop();
mBuffer = buffer;
if (buffer == nullptr) {
- alSourcei(mSource, AL_BUFFER, 0);
- return true;
+ alSourcei(mSource, AL_BUFFER, 0);
+ return true;
}
alSourcei(mSource, AL_BUFFER, buffer->GetBuffer());
@@ -237,10 +241,26 @@ bool Channel::SetBuffer(Buffer *buffer) {
}
+bool Channel::FreeBuffer() {
+ if (!mReady)
+ return false;
+
+ if (!mBuffer) {
+ return false;
+ }
+
+ alSourceStop(mSource);
+ alSourcei(mSource, AL_BUFFER, 0);
+ delete mBuffer;
+ mBuffer = nullptr;
+ return true;
+}
+
+
bool Channel::IsPlaying() {
ALint status;
if (!mReady || mBuffer == nullptr)
- return false;
+ return false;
alGetSourcei(mSource, AL_SOURCE_STATE, &status);
if (alCheck()) {
@@ -257,13 +277,13 @@ bool Channel::IsReady() {
}
bool Channel::IsLoaded() {
- return mBuffer == nullptr;
+ return mBuffer != nullptr;
}
bool Channel::Stop() {
if (!mReady || mBuffer == nullptr)
- return false;
+ return false;
alSourceStop(mSource);
if (alCheck()) {
@@ -277,7 +297,7 @@ bool Channel::Stop() {
float Channel::GetCurrentTime()
{
if (!mReady || mBuffer == nullptr)
- return 0.0f;
+ return 0.0f;
ALfloat current;
alGetSourcef(mSource, AL_SEC_OFFSET, &current);
@@ -292,7 +312,7 @@ float Channel::GetCurrentTime()
void Channel::SetCurrentTime(float current)
{
if (!mReady || mBuffer == nullptr)
- return;
+ return;
alSourcef(mSource, AL_SEC_OFFSET, current);
if (alCheck())
@@ -303,7 +323,7 @@ void Channel::SetCurrentTime(float current)
float Channel::GetDuration()
{
if (!mReady || mBuffer == nullptr)
- return 0.0f;
+ return 0.0f;
return mBuffer->GetDuration();
}
diff --git a/src/sound/oalsound/channel.h b/src/sound/oalsound/channel.h
index 70307ef..8965306 100644
--- a/src/sound/oalsound/channel.h
+++ b/src/sound/oalsound/channel.h
@@ -52,7 +52,7 @@ class Channel
bool SetFrequency(float);
float GetFrequency();
- bool AdjustFrequency(float);
+ bool AdjustFrequency(float);
float GetCurrentTime();
void SetCurrentTime(float);
@@ -62,9 +62,11 @@ class Channel
float GetVolume();
bool IsPlaying();
bool IsReady();
- bool IsLoaded();
+ bool IsLoaded();
bool SetBuffer(Buffer *);
+ bool FreeBuffer();
+
bool HasEnvelope();
SoundOper& GetEnvelope();
void PopEnvelope();
@@ -84,7 +86,7 @@ class Channel
void AddOper(SoundOper);
void ResetOper();
Sound GetSoundType();
- void SetLoop(bool);
+ void SetLoop(bool);
private:
Buffer *mBuffer;
@@ -97,5 +99,5 @@ class Channel
float mInitFrequency;
std::deque<SoundOper> mOper;
bool mReady;
- bool mLoop;
+ bool mLoop;
};
diff --git a/src/sound/sound.h b/src/sound/sound.h
index c9ac349..d152f76 100644
--- a/src/sound/sound.h
+++ b/src/sound/sound.h
@@ -22,6 +22,7 @@
#pragma once
+#include <boost/filesystem.hpp>
#include "math/vector.h"
@@ -32,6 +33,7 @@
#include <iostream>
#include <iomanip>
#include <sstream>
+#include <map>
/*!
@@ -177,6 +179,16 @@ class CSoundInterface
}
};
+ /** Function called to add all music files to list */
+ inline void AddMusicFiles(std::string path) {
+ for ( int i = 1; i <= 12; i++ ) {
+ std::stringstream filename;
+ filename << path << "/music" << std::setfill('0') << std::setw(3) << i << ".ogg";
+ if (boost::filesystem::exists(filename.str()))
+ mMusic[i] = filename.str();
+ }
+ };
+
/** Function called to cache sound effect file.
* This function is called by plugin interface for each file.
* \param bSound - id of a file, will be used to identify sound files
@@ -328,5 +340,8 @@ class CSoundInterface
* \return return true if music is playing
*/
inline virtual bool IsPlayingMusic() {return true;};
+
+ protected:
+ std::map<int, std::string> mMusic;
};
diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp
index bbba825..cf451e5 100644
--- a/src/ui/maindialog.cpp
+++ b/src/ui/maindialog.cpp
@@ -4676,6 +4676,7 @@ void CMainDialog::UpdateSceneChap(int &chap)
{
j = 0;
fs::directory_iterator dirIt(m_savegameDir), dirEndIt;
+ m_userList.clear();
BOOST_FOREACH (const fs::path & p, std::make_pair(dirIt, dirEndIt))
{
@@ -5458,10 +5459,8 @@ void CMainDialog::ChangeSetupButtons()
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_VOLMUSIC));
if ( ps != 0 )
{
- /*
- TODO: midi volume
value = ps->GetVisibleValue();
- m_sound->SetMidiVolume((int)value);*/
+ m_sound->SetMusicVolume(static_cast<int>(value));
}
}
diff --git a/src/ui/test/CMakeLists.txt b/src/ui/test/CMakeLists.txt
index c38d2bb..452df43 100644
--- a/src/ui/test/CMakeLists.txt
+++ b/src/ui/test/CMakeLists.txt
@@ -31,6 +31,6 @@ add_executable(edit_test
stubs/restext_stub.cpp
stubs/robotmain_stub.cpp
edit_test.cpp)
-target_link_libraries(edit_test gtest gmock ${SDL_LIBRARY} ${SDLTTF_LIBRARY})
+target_link_libraries(edit_test gtest gmock ${SDL_LIBRARY} ${SDLTTF_LIBRARY} ${Boost_LIBRARIES})
add_test(edit_test ./edit_test)