22 #include "MASoundDatabase.hpp" 24 #include "core/MACoreTypes.hpp" 25 #include "MASoundFile.hpp" 29 #include <boost/algorithm/string/join.hpp> 30 #include <boost/algorithm/string/split.hpp> 36 std::string SoundProfileConfigName(
"SOUND_PROFILE");
39 MASoundDatabase::MASoundDatabase() : DatabaseFileHandler(nullptr), SoundProfile(
"csaba")
44 MASoundDatabase::~MASoundDatabase()
46 if (DatabaseFileHandler)
48 fclose(DatabaseFileHandler);
49 DatabaseFileHandler =
nullptr;
56 if (SoundProfile ==
"tts")
58 SoundProfile =
"csaba";
60 if (SoundProfile ==
"csaba")
62 SoundProfile =
"marissa";
64 if (SoundProfile ==
"marissa")
66 SoundProfile =
"gillian";
68 if (SoundProfile ==
"gillian")
72 MC_LOG(
"New sound profile: %s", SoundProfile.c_str());
84 if (profile_name ==
"tts" || profile_name ==
"csaba" || profile_name ==
"marissa" ||
85 profile_name ==
"gillian")
87 SoundProfile = profile_name;
89 SoundProfile =
"csaba";
91 MC_LOG(
"New sound profile: %s", SoundProfile.c_str());
97 std::string JokerName = sound_name+
"_all.raw";
98 std::string ExpectedName = sound_name+
'_'+SoundProfile+
".raw";
99 std::string FallbackName = sound_name+
"_tts.raw";
101 if (Files.find(JokerName) != Files.end())
105 if (Files.find(ExpectedName) != Files.end())
109 if (Files.find(FallbackName) != Files.end())
119 const auto Iter = Files.find(file_name);
121 if (Iter != Files.end())
124 MC::StringList StrParts;
125 std::string DisplayName;
127 boost::split(StrParts, Iter->first, boost::is_any_of(
"_"));
129 DisplayName = boost::algorithm::join(StrParts,
"");
130 SoundFile =
new MASoundFile(DisplayName, DatabaseFileHandler, Iter->second.first, Iter->second.second, caching);
131 return MA::SoundBaseSPtr(SoundFile);
133 return MA::SoundBaseSPtr();
138 const MA::BinaryDataSPtrList& sounds)
141 if (file_name.empty() || sound_file_names.size() != sounds.size() || sounds.size() == 0)
144 for (
unsigned int i = 0; i < sounds.size(); ++i)
146 if (sound_file_names[i].empty() || !sounds[i].get() || sounds[i]->GetSize() <= 0)
153 HeaderData->IncrementPosition(4);
154 for (
unsigned int i = 0; i < sounds.size(); ++i)
156 HeaderData->AddInt16(sound_file_names[i].size());
157 HeaderData->AddString(sound_file_names[i]);
158 HeaderData->AddInt32(sounds[i]->GetSize());
160 HeaderSize = HeaderData->GetPosition();
161 HeaderData->ResetPosition();
162 HeaderData->AddInt32(HeaderSize-4);
164 FILE* FileHandler = fopen(file_name.c_str(),
"wb+");
166 fwrite(HeaderData->GetData(), HeaderSize, 1, FileHandler);
167 for (
unsigned int i = 0; i < sounds.size(); ++i)
169 fwrite(sounds[i]->GetData(), sounds[i]->GetSize(), 1, FileHandler);
179 FILE* FileHandler = fopen(file_name.c_str(),
"rb");
183 MC_WARNING(
"Unable to open a sound database file (%s)... :-|", file_name.c_str());
192 fseek(FileHandler, 0, SEEK_END);
193 FileSize = (int)ftell(FileHandler);
200 FileHandler =
nullptr;
201 MC_WARNING(
"Empty sound database file (%s)... :-|", file_name.c_str());
205 fseek(FileHandler, 0, SEEK_SET);
206 int Ret = fread(FileData->GetData(), 4, 1, FileHandler);
208 HeaderSize = FileData->GetInt32();
209 if (HeaderSize > FileSize && Ret != 4)
214 FileHandler =
nullptr;
215 MC_WARNING(
"Corrupt header in the sound database file (%s)... :-|", file_name.c_str());
219 FileData->Allocate(HeaderSize);
220 Ret = fread(FileData->GetData(), HeaderSize, 1, FileHandler);
221 if (HeaderSize > FileSize && Ret != HeaderSize)
226 FileHandler =
nullptr;
227 MC_WARNING(
"Can't read the header in the sound database file (%s)... :-|", file_name.c_str());
230 while (!FileData->IsPositionAtEnd())
232 int StrSize = FileData->GetInt16();
234 std::string FileName;
236 if (StrSize > 0 && StrSize < 100)
238 FileName = FileData->GetString(StrSize,
"_.");
239 FileSize = FileData->GetInt32();
241 if (FileName.empty() || FileSize <= 0)
246 FileHandler =
nullptr;
247 MC_WARNING(
"Corrupt header in the sound database file (%s)... :-|", file_name.c_str());
250 Database->
Files.insert(std::make_pair(FileName, MA::SoundFileInfo(0, FileSize)));
253 for (
auto& file : Database->
Files)
255 file.second.first = (int)ftell(FileHandler);
256 if (fseek(FileHandler, file.second.second, SEEK_CUR) == 0 && (int)ftell(FileHandler) > FileSize)
261 FileHandler =
nullptr;
262 MC_WARNING(
"Unexpected EOF in the sound database file (%s)... :-|", file_name.c_str());
266 if ((
int)ftell(FileHandler) < FileSize)
271 FileHandler =
nullptr;
272 MC_WARNING(
"Too much data in the sound database file (%s)... :-|", file_name.c_str());
std::string GetProfileName() const
Get sound profile name.
void SetProfileName(const std::string &profile_name)
Set sound profile name.
static MASoundDatabase * LoadFromFile(const std::string &file_name)
Load sound database from file.
#define MC_WARNING(...)
Warning macro.
std::string GetSoundFileName(const std::string &sound_name)
Get an sound file name.
static bool SaveToFile(const std::string &file_name, const MC::StringList &sound_file_names, const MA::BinaryDataSPtrList &sounds)
Assembly an sound database file.
MA::SoundFileMap Files
Sound files.
MA::SoundBaseSPtr GetSoundFile(const std::string &sound_name, bool caching)
Get an sound file.
A wrapper class to cover boost::thread_specific_ptr/folly::ThreadLocal API on certain targets...
#define MC_LOG(...)
Debug macro.
FILE * DatabaseFileHandler
Sound database handler.
void SwitchProfile()
Switch sound profile.