Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mumble_positional_audio_utils.h')
-rw-r--r--plugins/mumble_positional_audio_utils.h218
1 files changed, 218 insertions, 0 deletions
diff --git a/plugins/mumble_positional_audio_utils.h b/plugins/mumble_positional_audio_utils.h
new file mode 100644
index 000000000..ca6b5b4f0
--- /dev/null
+++ b/plugins/mumble_positional_audio_utils.h
@@ -0,0 +1,218 @@
+// Copyright 2021 The Mumble Developers. All rights reserved.
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file at the root of the
+// Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+#ifndef MUMBLE_POSITIONAL_AUDIO_UTILS_H_
+#define MUMBLE_POSITIONAL_AUDIO_UTILS_H_
+
+#include <cmath>
+#include <codecvt>
+#include <fstream>
+#include <locale>
+#include <sstream>
+#include <vector>
+
+#ifdef OS_LINUX
+# include <fenv.h>
+#endif
+
+#ifdef _MSC_VER
+# include <corecrt_math_defines.h>
+# include <intrin.h>
+#endif
+
+/// This union is used by isBigEndian() to determine the endianness.
+union SingleSplit4Bytes {
+ uint32_t single;
+ uint8_t split[4];
+
+ constexpr SingleSplit4Bytes(const uint32_t value) : single(value) {}
+};
+
+/// Converts from UTF-8 to UTF-16.
+static inline std::wstring utf8ToUtf16(const std::string &str) {
+ try {
+ std::wstring_convert< std::codecvt_utf8_utf16< wchar_t > > conv;
+ return conv.from_bytes(str);
+ } catch (std::range_error &) {
+ return {};
+ }
+}
+
+/// Converts from UTF-16 to UTF-8.
+/// Meant to be used when "wchar_t" is 2 bytes, usually with Windows processes.
+static inline std::string utf16ToUtf8(const std::u16string &str) {
+ try {
+ std::wstring_convert< std::codecvt_utf8_utf16< char16_t >, char16_t > conv;
+ return conv.to_bytes(str);
+ } catch (std::range_error &) {
+ return {};
+ }
+}
+
+/// Converts from UTF-16 to UTF-8.
+/// Meant to be used when "wchar_t" is 4 bytes, usually with Linux processes.
+static inline std::string utf16ToUtf8(const std::u32string &str) {
+ try {
+ std::wstring_convert< std::codecvt_utf8_utf16< char32_t >, char32_t > conv;
+ return conv.to_bytes(str);
+ } catch (std::range_error &) {
+ return {};
+ }
+}
+
+// escape lossily converts the given
+// string to ASCII, replacing any
+// character not within the printable
+// ASCII region (32-126) with an ASCII
+// space character.
+//
+// escape also replaces any double quote
+// characters with an ASCII space. This
+// allows the string to be safely used
+// when constructing JSON documents via
+// string concatenation.
+//
+// Finally, escape ensures that the given
+// string is NUL-terminated by always
+// setting the last byte of the input
+// string to the value 0.
+static inline void escape(char *str, const size_t &size) {
+ // Ensure the input string is properly NUL-terminated.
+ str[size - 1] = 0;
+ char *c = str;
+
+ while (*c != '\0') {
+ // For JSON compatibility, the string
+ // can't contain double quotes.
+ // If a double quote is found, replace
+ // it with an ASCII space.
+ if (*c == '"') {
+ *c = ' ';
+ }
+
+ // Ensure the string is within printable
+ // ASCII. If not, replace the offending
+ // byte with an ASCII space.
+ if (*c < 32 || *c > 126) {
+ *c = ' ';
+ }
+
+ c += 1;
+ }
+}
+
+/// Reads the file's content and returns it in a std::string.
+static inline std::string readFile(const std::string &path) {
+ std::ifstream ifs(path, std::ifstream::binary);
+ std::string content;
+ char buf[256];
+
+ while (ifs.good()) {
+ ifs.read(&buf[0], sizeof(buf));
+ size_t read = ifs.gcount();
+ if (read > 0) {
+ content.append(&buf[0], read);
+ }
+ }
+
+ return content;
+}
+
+/// Reads characters from the stream until \p character is encountered.
+/// @return Read characters and whether the stream is still good.
+static inline std::pair< std::string, bool > readUntil(std::stringstream &stream,
+ const std::stringstream::int_type character) {
+ std::string buf;
+
+ for (auto input = stream.get(); input != character; input = stream.get()) {
+ if (!stream) {
+ return { buf, false };
+ }
+
+ buf.push_back(input);
+ };
+
+ return { buf, true };
+}
+
+/// Discards characters in the stream until the specified one is encountered.
+/// @param[inverted] Inverts the behavior.
+/// @return Whether the stream is still good.
+static inline bool skipUntil(std::stringstream &stream, const std::stringstream::int_type character,
+ const bool inverted) {
+ for (auto input = stream.get(); inverted ? (input == character) : (input != character); input = stream.get()) {
+ if (!stream) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/// Returns the index of the specified pattern in the specified buffer.
+/// "?" is used as wildcard character.
+/// If the pattern is not found, the function returns SIZE_MAX.
+static inline size_t searchInBuffer(const std::vector< uint8_t > &pattern, const std::vector< uint8_t > &buffer) {
+ for (size_t i = 0; i < buffer.size() - pattern.size(); ++i) {
+ const auto *buf = &buffer[i];
+ bool match = true;
+
+ for (size_t j = 0; j < pattern.size(); ++j) {
+ if (pattern[j] != '?' && buf[j] != pattern[j]) {
+ match = false;
+ break;
+ }
+ }
+
+ if (match) {
+ return buf - &buffer[0];
+ }
+ }
+
+ return SIZE_MAX;
+}
+
+/// Calculates sine and cosine of the specified value.
+/// On Linux the calculation is guaranteed to be simultaneous.
+static inline bool sinCos(const float value, float &outSin, float &outCos) {
+#ifdef OS_WINDOWS
+ outSin = sin(value);
+ outCos = cos(value);
+ return true;
+#else
+ errno = 0;
+ feclearexcept(FE_ALL_EXCEPT);
+
+ sincosf(value, &outSin, &outCos);
+
+ return fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) == 0;
+#endif
+}
+
+/// Converts degrees to radians.
+static inline float degreesToRadians(const float degrees) {
+ constexpr float piOver180 = M_PI / 180.0f;
+ return piOver180 * degrees;
+}
+
+/// Detects whether the architecture is big-endian.
+static constexpr bool isBigEndian() {
+ // An union allows access to a single byte without the need for a cast.
+ return SingleSplit4Bytes(0x01020304).split[0] == 1;
+}
+
+/// Converts from network byte order to host byte order.
+static inline uint16_t networkToHost(const uint16_t value) {
+ if (isBigEndian()) {
+ return value;
+ }
+#ifdef _MSC_VER
+ return _byteswap_ushort(value);
+#else
+ return __builtin_bswap16(value);
+#endif
+}
+
+#endif