1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef _SOUND_H_
#define _SOUND_H_
#include <atomic>
#include <string>
#include <vector>
#include <al.h>
#include <alc.h>
#include "System/Sound/ISound.h"
#include "System/float3.h"
#include "System/UnorderedMap.hpp"
#include "System/UnorderedSet.hpp"
#include "System/Threading/SpringThreading.h"
#include "SoundItem.h"
class CSoundSource;
class SoundBuffer;
class SoundItem;
/// Default sound system implementation (OpenAL)
class CSound : public ISound
{
public:
CSound();
~CSound();
void Init() override;
void Kill() override;
bool HasSoundItem(const std::string& name) const override;
bool PreloadSoundItem(const std::string& name) override;
size_t GetDefSoundId(const std::string& name) override;
size_t GetSoundId(const std::string& name) override;
SoundItem* GetSoundItem(size_t id) override;
CSoundSource* GetNextBestSource(bool lock = true) override;
void NewFrame() override;
void UpdateListener(const float3& campos, const float3& camdir, const float3& camup) override {
myPos = campos;
camDir = camdir;
camUp = camup;
// schedule UpdateListenerReal
updateListener = true;
}
/// @see ConfigHandler::ConfigNotifyCallback
void ConfigNotify(const std::string& key, const std::string& value) override;
void PitchAdjust(const float newPitch) override;
bool Mute() override;
bool IsMuted() const override { return mute; }
void Iconified(bool state) override;
void PrintDebugInfo() override;
bool SoundThreadQuit() const override { return soundThreadQuit; }
bool CanLoadSoundDefs() const override { return canLoadDefs; }
bool LoadSoundDefsImpl(LuaParser* defsParser) override;
const float3& GetListenerPos() const override { return myPos; }
ALCdevice* GetCurrentDevice() { return curDevice; }
int GetFrameSize() const { return frameSize; }
private:
typedef spring::unordered_map<std::string, std::string> SoundItemNameMap;
typedef spring::unordered_map<std::string, SoundItemNameMap> SoundItemDefsMap;
private:
void Cleanup();
void OpenOpenALDevice(const std::string& deviceName);
void OpenLoopbackDevice(const std::string& deviceName);
void InitThread(int cfgMaxSounds);
void UpdateThread(int cfgMaxSounds);
void Update();
void UpdateListenerReal();
int GetMaxMonoSources(ALCdevice* device, int cfgMaxSounds);
void GenSources(int alMaxSounds);
size_t MakeItemFromDef(const SoundItemNameMap& itemDef);
size_t LoadSoundBuffer(const std::string& filename);
private:
ALCdevice* curDevice = nullptr;
ALCcontext* curContext = nullptr;
int sdlDeviceID = 0;
spring::thread soundThread;
spring::unordered_map<std::string, size_t> soundMap; // <name, id>
spring::unordered_set<std::string> preloadSet;
spring::unordered_set<std::string> failureSet;
std::vector<SoundItem> soundItems;
std::vector<CSoundSource> soundSources; // fixed-size
std::vector<std::uint8_t> loadBuffer;
SoundItemNameMap defaultItemNameMap;
SoundItemDefsMap soundItemDefsMap; // parsed from sounds.lua
float masterVolume = 0.0f;
/// unscaled
float3 myPos;
float3 camDir;
float3 camUp;
float3 prevVelocity;
int pitchAdjustMode = 0;
int frameSize = -1;
bool mute = false;
/// we do not play if minimized / iconified
bool appIsIconified = false;
std::atomic<bool> updateListener = {false};
std::atomic<bool> soundThreadQuit = {false};
std::atomic<bool> canLoadDefs = {false};
};
#endif // _SOUND_H_
|