Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/frontend/StarVoice.hpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-07-13 19:12:55 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-07-13 19:12:55 +1000
commit28f4204b09b04280340ffbbeaccf86b96f377296 (patch)
treee2a166cc3ddd57460814631b7a8258ed0ee975ea /source/frontend/StarVoice.hpp
parentc3bf7a3c87e61c56d48dd932f295c99d64d14a38 (diff)
more Voice work
Diffstat (limited to 'source/frontend/StarVoice.hpp')
-rw-r--r--source/frontend/StarVoice.hpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/source/frontend/StarVoice.hpp b/source/frontend/StarVoice.hpp
new file mode 100644
index 0000000..0d485db
--- /dev/null
+++ b/source/frontend/StarVoice.hpp
@@ -0,0 +1,109 @@
+#ifndef STAR_VOICE_HPP
+#define STAR_VOICE_HPP
+#include "StarJson.hpp"
+#include "StarBiMap.hpp"
+#include "StarException.hpp"
+#include "StarGameTypes.hpp"
+#include "StarMaybe.hpp"
+#include "StarApplicationController.hpp"
+
+struct OpusDecoder;
+typedef std::unique_ptr<OpusDecoder, void(*)(OpusDecoder*)> OpusDecoderPtr;
+struct OpusEncoder;
+typedef std::unique_ptr<OpusEncoder, void(*)(OpusEncoder*)> OpusEncoderPtr;
+
+namespace Star {
+
+STAR_EXCEPTION(VoiceException, StarException);
+
+enum class VoiceInputMode : uint8_t { VoiceActivity, PushToTalk };
+extern EnumMap<VoiceInputMode> const VoiceInputModeNames;
+
+enum class VoiceChannelMode: uint8_t { Mono = 1, Stereo = 2 };
+extern EnumMap<VoiceChannelMode> const VoiceChannelModeNames;
+
+STAR_CLASS(Voice);
+STAR_CLASS(ApplicationController);
+
+class Voice {
+public:
+ // Individual speakers are represented by their connection ID.
+ typedef ConnectionId SpeakerId;
+
+ struct Speaker {
+ SpeakerId speakerId = 0;
+ EntityId entityId = 0;
+
+ Vec2F position = Vec2F();
+ String name = "Unnamed";
+
+ OpusDecoderPtr decoderMono;
+ OpusDecoderPtr decoderStereo;
+
+ atomic<bool> active = false;
+ atomic<float> currentLoudness = 0.0f;
+ atomic<Array<float, 2>> channelVolumes = Array<float, 2>::filled(1.0f);
+
+ Speaker(SpeakerId speakerId);
+ };
+
+ typedef std::shared_ptr<Speaker> SpeakerPtr;
+
+ // Get pointer to the singleton Voice instance, if it exists. Otherwise,
+ // returns nullptr.
+ static Voice* singletonPtr();
+
+ // Gets reference to Voice singleton, throws VoiceException if root
+ // is not initialized.
+ static Voice& singleton();
+
+ Voice(ApplicationControllerPtr appController);
+ ~Voice();
+
+ Voice(Voice const&) = delete;
+ Voice& operator=(Voice const&) = delete;
+
+ void load(Json const& config);
+ Json save() const;
+
+ // Sets the local speaker ID and returns the local speaker. Must be called upon loading into a world.
+ SpeakerPtr setLocalSpeaker(SpeakerId speakerId);
+ SpeakerPtr speaker(SpeakerId speakerId);
+
+ // Called to mix voice audio with the game.
+ void mix(int16_t* buffer, size_t frames, unsigned channels);
+
+ typedef function<float(unsigned, Vec2F, float)> PositionalAttenuationFunction;
+ void update(PositionalAttenuationFunction positionalAttenuationFunction = {});
+
+ inline int encoderChannels() const {
+ return m_channelMode == VoiceChannelMode::Mono ? 1 : 2;
+ }
+private:
+ static Voice* s_singleton;
+
+ static OpusDecoder* createDecoder(int channels);
+ static OpusEncoder* createEncoder(int channels);
+ void resetEncoder();
+ void openDevice();
+ void closeDevice();
+
+ SpeakerId m_speakerId = 0;
+ SpeakerPtr m_clientSpeaker;
+ HashMap<SpeakerId, SpeakerPtr> m_speakers;
+
+ HashSet<SpeakerPtr> m_activeSpeakers;
+
+ OpusEncoderPtr m_encoder;
+
+ bool m_deviceOpen = false;
+ Maybe<String> m_deviceName;
+ VoiceInputMode m_inputMode;
+ VoiceChannelMode m_channelMode;
+
+ ApplicationControllerPtr m_applicationController;
+};
+
+}
+
+#endif \ No newline at end of file