diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f9a54f1adc..a62e4b2825 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,4 @@
-The project embraces distributed development and if you'd like to help, we'll pay you -- find out more at [Worklist.net](https://worklist.net). If you find a small bug and have a fix, pull requests are welcome. If you'd like to get paid for your work, make sure you report the bug via a job on Worklist.net.
-
-We're hiring! We're looking for skilled developers; send your resume to hiring@highfidelity.io
+The project embraces distributed development and if you'd like to help, it would be greatly appreciated. Just open a pull request with the revisions.
Contributing
===
@@ -8,7 +6,7 @@ Contributing
2. Clone your fork of the repository locally
```
- git clone git://github.com/USERNAME/hifi.git
+ git clone git://github.com/USERNAME/project-athena.git
```
3. Create a new branch
@@ -22,15 +20,16 @@ Contributing
6. Update your branch
```
- git remote add upstream https://github.com/highfidelity/hifi
- git pull upstream master
+ git remote add upstream https://github.com/kasenvr/project-athena
+ git pull upstream kasen/core
```
Resolve any conflicts that arise with this step.
+
7. Push to your fork
```
- git push origin master
+ git push origin kasen/core
```
8. Submit a pull request
@@ -39,10 +38,10 @@ Contributing
Reporting Bugs
===
1. Always update to the latest code on master, we make many merges every day and it is possible the bug has already been fixed!
-2. Search jobs [on Worklist](https://worklist.net) to make sure that somebody has not already reported the same bug.
-3. Add a [job on Worklist](https://worklist.net/job/add) including information about your system and how to reproduce the bug.
+2. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already reported the same bug.
+3. [Add](https://github.com/kasenvr/project-athena/issues/new) your report to the issues list!
-Requesting a feature
+Requesting a Feature
===
-1. Search the [the Worklist](https://worklist.net) to make sure that somebody has not already requested the same feature. If you find a matching request, feel free to add any additional comments to the existing issue.
-2. Add a [job on Worklist](https://worklist.net/job/add) that is labeled as a Feature (and select any other appropriate Labels) and includes a detailed description of your request.
+1. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already requested the same feature.
+2. [Add](https://github.com/kasenvr/project-athena/issues/new) your request to the issues list!
diff --git a/cmake/macros/TargetOpus.cmake b/cmake/macros/TargetOpus.cmake
new file mode 100644
index 0000000000..a8faf5139e
--- /dev/null
+++ b/cmake/macros/TargetOpus.cmake
@@ -0,0 +1,13 @@
+#
+# Created by Michael Bailey on 12/20/2019
+# Copyright 2019 Michael Bailey
+#
+# Distributed under the Apache License, Version 2.0.
+# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+#
+macro(TARGET_opus)
+ find_library(OPUS_LIBRARY_RELEASE NAMES opus PATHS ${VCPKG_INSTALL_ROOT}/lib)
+ find_library(OPUS_LIBRARY_DEBUG NAMES opus PATHS ${VCPKG_INSTALL_ROOT}/debug/lib)
+ select_library_configurations(OPUS)
+ target_link_libraries(${TARGET_NAME} ${OPUS_LIBRARY})
+endmacro()
diff --git a/cmake/ports/hifi-deps/CONTROL b/cmake/ports/hifi-deps/CONTROL
index 4cf952ccf0..b1a7f96a00 100644
--- a/cmake/ports/hifi-deps/CONTROL
+++ b/cmake/ports/hifi-deps/CONTROL
@@ -1,4 +1,4 @@
Source: hifi-deps
-Version: 0.3
+Version: 0.4
Description: Collected dependencies for High Fidelity applications
-Build-Depends: bullet3, draco, etc2comp, glm, nvtt, openexr (!android), openssl (windows), tbb (!android&!osx), zlib, webrtc (!android)
+Build-Depends: bullet3, draco, etc2comp, glm, nvtt, openexr (!android), openssl (windows), opus, tbb (!android&!osx), zlib, webrtc (!android)
diff --git a/cmake/ports/opus/CONTROL b/cmake/ports/opus/CONTROL
new file mode 100644
index 0000000000..4314774ab5
--- /dev/null
+++ b/cmake/ports/opus/CONTROL
@@ -0,0 +1,3 @@
+Source: opus
+Version: 1.3.1
+Description: Totally open, royalty-free, highly versatile audio codec
diff --git a/cmake/ports/opus/portfile.cmake b/cmake/ports/opus/portfile.cmake
new file mode 100644
index 0000000000..bf23718df8
--- /dev/null
+++ b/cmake/ports/opus/portfile.cmake
@@ -0,0 +1,28 @@
+include(vcpkg_common_functions)
+
+vcpkg_from_github(
+ OUT_SOURCE_PATH
+ SOURCE_PATH
+ REPO
+ xiph/opus
+ REF
+ e85ed7726db5d677c9c0677298ea0cb9c65bdd23
+ SHA512
+ a8c7e5bf383c06f1fdffd44d9b5f658f31eb4800cb59d12da95ddaeb5646f7a7b03025f4663362b888b1374d4cc69154f006ba07b5840ec61ddc1a1af01d6c54
+ HEAD_REF
+ master)
+
+vcpkg_configure_cmake(SOURCE_PATH ${SOURCE_PATH} PREFER_NINJA)
+vcpkg_install_cmake()
+vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/Opus)
+vcpkg_copy_pdbs()
+
+file(INSTALL
+ ${SOURCE_PATH}/COPYING
+ DESTINATION
+ ${CURRENT_PACKAGES_DIR}/share/opus
+ RENAME copyright)
+
+file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/lib/cmake
+ ${CURRENT_PACKAGES_DIR}/lib/cmake
+ ${CURRENT_PACKAGES_DIR}/debug/include)
diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json
index b854955953..cdf92918c6 100644
--- a/domain-server/resources/describe-settings.json
+++ b/domain-server/resources/describe-settings.json
@@ -1227,8 +1227,8 @@
"name": "codec_preference_order",
"label": "Audio Codec Preference Order",
"help": "List of codec names in order of preferred usage",
- "placeholder": "hifiAC, zlib, pcm",
- "default": "hifiAC,zlib,pcm",
+ "placeholder": "opus, hifiAC, zlib, pcm",
+ "default": "opus,hifiAC,zlib,pcm",
"advanced": true
}
]
diff --git a/interface/resources/qml/+webengine/BrowserWebView.qml b/interface/resources/qml/+webengine/BrowserWebView.qml
index 137531f517..7f2136ec4f 100644
--- a/interface/resources/qml/+webengine/BrowserWebView.qml
+++ b/interface/resources/qml/+webengine/BrowserWebView.qml
@@ -6,7 +6,7 @@ import controlsUit 1.0
WebView {
id: webview
- url: "https://highfidelity.com/"
+ url: "https://projectathena.io/"
profile: FileTypeProfile;
property var parentRoot: null
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 83f7495372..a73281e569 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -3156,7 +3156,7 @@ void Application::showLoginScreen() {
QJsonObject loginData = {};
loginData["action"] = "login dialog popped up";
UserActivityLogger::getInstance().logAction("encourageLoginDialog", loginData);
- _window->setWindowTitle("High Fidelity");
+ _window->setWindowTitle("Project Athena");
} else {
resumeAfterLoginDialogActionTaken();
}
diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp
index 2b8f2b4c14..9afaa5e85b 100644
--- a/libraries/entities/src/EntityItemProperties.cpp
+++ b/libraries/entities/src/EntityItemProperties.cpp
@@ -1366,7 +1366,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
* var METERS_TO_INCHES = 39.3701;
* var entity = Entities.addEntity({
* type: "Web",
- * sourceUrl: "https://highfidelity.com/",
+ * sourceUrl: "https://projectathena.io/",
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -4 })),
* rotation: MyAvatar.orientation,
* dimensions: {
diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h
index 04222b3ea1..dd5ec2a845 100644
--- a/libraries/ui/src/ui/TabletScriptingInterface.h
+++ b/libraries/ui/src/ui/TabletScriptingInterface.h
@@ -105,7 +105,7 @@ public:
* @returns {TabletProxy} The tablet instance.
* @example
Display the High Fidelity home page on the system tablet.
* var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
- * tablet.gotoWebScreen("https://highfidelity.com/");
+ * tablet.gotoWebScreen("https://projectathena.io/");
*/
Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId);
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index c9bc3e4c33..c88bb8a00d 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -43,6 +43,8 @@ set(DIR "pcmCodec")
add_subdirectory(${DIR})
set(DIR "hifiCodec")
add_subdirectory(${DIR})
+set(DIR "opusCodec")
+add_subdirectory(${DIR})
# example plugins
set(DIR "KasenAPIExample")
diff --git a/plugins/hifiCodec/CMakeLists.txt b/plugins/hifiCodec/CMakeLists.txt
index 0d4f093fc2..5515602d2f 100644
--- a/plugins/hifiCodec/CMakeLists.txt
+++ b/plugins/hifiCodec/CMakeLists.txt
@@ -8,7 +8,7 @@
set(TARGET_NAME hifiCodec)
setup_hifi_client_server_plugin()
-link_hifi_libraries(audio plugins)
+link_hifi_libraries(shared audio plugins)
target_hifiAudioCodec()
if (BUILD_SERVER)
install_beside_console()
diff --git a/plugins/hifiCodec/src/HiFiCodec.cpp b/plugins/hifiCodec/src/HiFiCodec.cpp
index 99bb411539..a93e6c47d0 100644
--- a/plugins/hifiCodec/src/HiFiCodec.cpp
+++ b/plugins/hifiCodec/src/HiFiCodec.cpp
@@ -13,6 +13,7 @@
#include
#include
+#include
const char* HiFiCodec::NAME { "hifiAC" };
@@ -44,6 +45,8 @@ public:
}
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override {
+ PerformanceTimer perfTimer("HiFiEncoder::encode");
+
encodedBuffer.resize(_encodedSize);
AudioEncoder::process((const int16_t*)decodedBuffer.constData(), (int16_t*)encodedBuffer.data(), AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL);
}
@@ -58,11 +61,15 @@ public:
}
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override {
+ PerformanceTimer perfTimer("HiFiEncoder::decode");
+
decodedBuffer.resize(_decodedSize);
AudioDecoder::process((const int16_t*)encodedBuffer.constData(), (int16_t*)decodedBuffer.data(), AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL, true);
}
virtual void lostFrame(QByteArray& decodedBuffer) override {
+ PerformanceTimer perfTimer("HiFiEncoder::lostFrame");
+
decodedBuffer.resize(_decodedSize);
// this performs packet loss interpolation
AudioDecoder::process(nullptr, (int16_t*)decodedBuffer.data(), AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL, false);
diff --git a/plugins/opusCodec/CMakeLists.txt b/plugins/opusCodec/CMakeLists.txt
new file mode 100644
index 0000000000..583aff85d6
--- /dev/null
+++ b/plugins/opusCodec/CMakeLists.txt
@@ -0,0 +1,16 @@
+#
+# Created by Michael Bailey on 12/20/2019
+# Copyright 2019 Michael Bailey
+#
+# Distributed under the Apache License, Version 2.0.
+# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
+#
+
+set(TARGET_NAME opusCodec)
+setup_hifi_client_server_plugin()
+link_hifi_libraries(shared audio plugins)
+target_opus()
+
+if (BUILD_SERVER)
+ install_beside_console()
+endif ()
diff --git a/plugins/opusCodec/src/OpusCodecManager.cpp b/plugins/opusCodec/src/OpusCodecManager.cpp
new file mode 100644
index 0000000000..1e3d73a229
--- /dev/null
+++ b/plugins/opusCodec/src/OpusCodecManager.cpp
@@ -0,0 +1,58 @@
+//
+// opusCodec.cpp
+// plugins/opusCodec/src
+//
+// Created by Michael Bailey on 12/20/2019
+// Copyright 2019 Michael Bailey
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include "OpusCodecManager.h"
+
+#include
+
+#include
+
+#include "OpusEncoder.h"
+#include "OpusDecoder.h"
+
+const char* AthenaOpusCodec::NAME { "opus" };
+
+void AthenaOpusCodec::init() {
+}
+
+void AthenaOpusCodec::deinit() {
+}
+
+bool AthenaOpusCodec::activate() {
+ CodecPlugin::activate();
+ return true;
+}
+
+void AthenaOpusCodec::deactivate() {
+ CodecPlugin::deactivate();
+}
+
+
+bool AthenaOpusCodec::isSupported() const {
+ return true;
+}
+
+
+Encoder* AthenaOpusCodec::createEncoder(int sampleRate, int numChannels) {
+ return new AthenaOpusEncoder(sampleRate, numChannels);
+}
+
+Decoder* AthenaOpusCodec::createDecoder(int sampleRate, int numChannels) {
+ return new AthenaOpusDecoder(sampleRate, numChannels);
+}
+
+void AthenaOpusCodec::releaseEncoder(Encoder* encoder) {
+ delete encoder;
+}
+
+void AthenaOpusCodec::releaseDecoder(Decoder* decoder) {
+ delete decoder;
+}
diff --git a/plugins/opusCodec/src/OpusCodecManager.h b/plugins/opusCodec/src/OpusCodecManager.h
new file mode 100644
index 0000000000..be6a6b2ff0
--- /dev/null
+++ b/plugins/opusCodec/src/OpusCodecManager.h
@@ -0,0 +1,42 @@
+//
+// OpusCodecManager.h
+// plugins/opusCodec/src
+//
+// Created by Michael Bailey on 12/20/2019
+// Copyright 2019 Michael Bailey
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef hifi__OpusCodecManager_h
+#define hifi__OpusCodecManager_h
+
+#include
+
+class AthenaOpusCodec : public CodecPlugin {
+ Q_OBJECT
+
+public:
+ // Plugin functions
+ bool isSupported() const override;
+ const QString getName() const override { return NAME; }
+
+ void init() override;
+ void deinit() override;
+
+ /// Called when a plugin is being activated for use. May be called multiple times.
+ bool activate() override;
+ /// Called when a plugin is no longer being used. May be called multiple times.
+ void deactivate() override;
+
+ virtual Encoder* createEncoder(int sampleRate, int numChannels) override;
+ virtual Decoder* createDecoder(int sampleRate, int numChannels) override;
+ virtual void releaseEncoder(Encoder* encoder) override;
+ virtual void releaseDecoder(Decoder* decoder) override;
+
+private:
+ static const char* NAME;
+};
+
+#endif // hifi__opusCodecManager_h
diff --git a/plugins/opusCodec/src/OpusCodecProvider.cpp b/plugins/opusCodec/src/OpusCodecProvider.cpp
new file mode 100644
index 0000000000..79f01de4bd
--- /dev/null
+++ b/plugins/opusCodec/src/OpusCodecProvider.cpp
@@ -0,0 +1,45 @@
+//
+// Created by Michael Bailey on 12/20/2019
+// Copyright 2019 Michael Bailey
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "OpusCodecManager.h"
+
+class AthenaOpusCodecProvider : public QObject, public CodecProvider {
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID CodecProvider_iid FILE "plugin.json")
+ Q_INTERFACES(CodecProvider)
+
+public:
+ AthenaOpusCodecProvider(QObject* parent = nullptr) : QObject(parent) {}
+ virtual ~AthenaOpusCodecProvider() {}
+
+ virtual CodecPluginList getCodecPlugins() override {
+ static std::once_flag once;
+ std::call_once(once, [&] {
+
+ CodecPluginPointer opusCodec(new AthenaOpusCodec());
+ if (opusCodec->isSupported()) {
+ _codecPlugins.push_back(opusCodec);
+ }
+ });
+ return _codecPlugins;
+ }
+
+private:
+ CodecPluginList _codecPlugins;
+};
+
+#include "OpusCodecProvider.moc"
diff --git a/plugins/opusCodec/src/OpusDecoder.cpp b/plugins/opusCodec/src/OpusDecoder.cpp
new file mode 100644
index 0000000000..e3e4e3645a
--- /dev/null
+++ b/plugins/opusCodec/src/OpusDecoder.cpp
@@ -0,0 +1,131 @@
+//
+// OpusCodecManager.h
+// plugins/opusCodec/src
+//
+// Copyright 2020 Dale Glass
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include
+#include
+#include
+
+#include "OpusDecoder.h"
+
+static QLoggingCategory decoder("AthenaOpusDecoder");
+
+static QString error_to_string(int error) {
+ switch (error) {
+ case OPUS_OK:
+ return "OK";
+ case OPUS_BAD_ARG:
+ return "One or more invalid/out of range arguments.";
+ case OPUS_BUFFER_TOO_SMALL:
+ return "The mode struct passed is invalid.";
+ case OPUS_INTERNAL_ERROR:
+ return "An internal error was detected.";
+ case OPUS_INVALID_PACKET:
+ return "The compressed data passed is corrupted.";
+ case OPUS_UNIMPLEMENTED:
+ return "Invalid/unsupported request number.";
+ case OPUS_INVALID_STATE:
+ return "An encoder or decoder structure is invalid or already freed.";
+ default:
+ return QString("Unknown error code: %i").arg(error);
+ }
+}
+
+
+AthenaOpusDecoder::AthenaOpusDecoder(int sampleRate, int numChannels) {
+ int error;
+
+ _opusSampleRate = sampleRate;
+ _opusNumChannels = numChannels;
+
+ _decoder = opus_decoder_create(sampleRate, numChannels, &error);
+
+ if (error != OPUS_OK) {
+ qCCritical(decoder) << "Failed to initialize Opus encoder: " << error_to_string(error);
+ _decoder = nullptr;
+ return;
+ }
+
+
+ qCDebug(decoder) << "Opus decoder initialized, sampleRate = " << sampleRate << "; numChannels = " << numChannels;
+}
+
+AthenaOpusDecoder::~AthenaOpusDecoder() {
+ if (_decoder) {
+ opus_decoder_destroy(_decoder);
+ }
+
+}
+
+void AthenaOpusDecoder::decode(const QByteArray &encodedBuffer, QByteArray &decodedBuffer) {
+ assert(_decoder);
+ PerformanceTimer perfTimer("AthenaOpusDecoder::decode");
+
+ // The audio system encodes and decodes always in fixed size chunks
+ int bufferSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast(sizeof(int16_t))
+ * _opusNumChannels;
+
+ decodedBuffer.resize(bufferSize);
+ int bufferFrames = decodedBuffer.size() / _opusNumChannels / static_cast(sizeof(opus_int16));
+ int decoded_frames = opus_decode(_decoder, reinterpret_cast(encodedBuffer.data()),
+ encodedBuffer.length(), reinterpret_cast(decodedBuffer.data()), bufferFrames, 0);
+
+ if (decoded_frames >= 0) {
+
+ if (decoded_frames < bufferFrames) {
+ qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << bufferFrames
+ << " were expected!";
+
+ int start = decoded_frames * static_cast(sizeof(int16_t)) * _opusNumChannels;
+ memset( &decodedBuffer.data()[start], 0, static_cast(decodedBuffer.length() - start));
+ } else if (decoded_frames > bufferFrames) {
+ // This should never happen
+ qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << bufferFrames
+ << " were expected! Buffer overflow!?";
+ }
+ } else {
+ qCCritical(decoder) << "Failed to decode audio: " << error_to_string(decoded_frames);
+ decodedBuffer.fill('\0');
+ }
+
+}
+
+void AthenaOpusDecoder::lostFrame(QByteArray &decodedBuffer) {
+ assert(_decoder);
+
+ PerformanceTimer perfTimer("AthenaOpusDecoder::lostFrame");
+
+ int bufferSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast(sizeof(int16_t))
+ * _opusNumChannels;
+ decodedBuffer.resize(bufferSize);
+ int bufferFrames = decodedBuffer.size() / _opusNumChannels / static_cast(sizeof(opus_int16));
+
+ int decoded_frames = opus_decode(_decoder, nullptr, 0, reinterpret_cast(decodedBuffer.data()),
+ bufferFrames, 1);
+
+ if (decoded_frames >= 0) {
+
+ if ( decoded_frames < bufferFrames ) {
+ qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << bufferFrames
+ << " were expected!";
+
+ int start = decoded_frames * static_cast(sizeof(int16_t)) * _opusNumChannels;
+ memset( &decodedBuffer.data()[start], 0, static_cast(decodedBuffer.length() - start));
+ } else if (decoded_frames > bufferFrames) {
+ // This should never happen
+ qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << bufferFrames
+ << " were expected! Buffer overflow!?";
+ }
+
+ } else {
+ qCCritical(decoder) << "Failed to decode lost frame: " << error_to_string(decoded_frames);
+ decodedBuffer.fill('\0');
+ }
+
+}
diff --git a/plugins/opusCodec/src/OpusDecoder.h b/plugins/opusCodec/src/OpusDecoder.h
new file mode 100644
index 0000000000..095893856b
--- /dev/null
+++ b/plugins/opusCodec/src/OpusDecoder.h
@@ -0,0 +1,39 @@
+//
+// OpusCodecManager.h
+// plugins/opusCodec/src
+//
+// Copyright 2020 Dale Glass
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef OPUSDECODER_H
+#define OPUSDECODER_H
+
+
+#include
+#include
+
+
+class AthenaOpusDecoder : public Decoder {
+public:
+ AthenaOpusDecoder(int sampleRate, int numChannels);
+ ~AthenaOpusDecoder() override;
+
+
+ virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override;
+ virtual void lostFrame(QByteArray &decodedBuffer) override;
+
+
+private:
+ int _encodedSize;
+
+ OpusDecoder* _decoder = nullptr;
+ int _opusSampleRate = 0;
+ int _opusNumChannels = 0;
+ int _decodedSize = 0;
+};
+
+
+#endif // OPUSDECODER_H
diff --git a/plugins/opusCodec/src/OpusEncoder.cpp b/plugins/opusCodec/src/OpusEncoder.cpp
new file mode 100644
index 0000000000..3408701633
--- /dev/null
+++ b/plugins/opusCodec/src/OpusEncoder.cpp
@@ -0,0 +1,273 @@
+//
+// OpusCodecManager.h
+// plugins/opusCodec/src
+//
+// Copyright 2020 Dale Glass
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include
+#include
+#include
+
+#include "OpusEncoder.h"
+
+static QLoggingCategory encoder("AthenaOpusEncoder");
+
+static QString errorToString(int error) {
+ switch (error) {
+ case OPUS_OK:
+ return "OK";
+ case OPUS_BAD_ARG:
+ return "One or more invalid/out of range arguments.";
+ case OPUS_BUFFER_TOO_SMALL:
+ return "The mode struct passed is invalid.";
+ case OPUS_INTERNAL_ERROR:
+ return "An internal error was detected.";
+ case OPUS_INVALID_PACKET:
+ return "The compressed data passed is corrupted.";
+ case OPUS_UNIMPLEMENTED:
+ return "Invalid/unsupported request number.";
+ case OPUS_INVALID_STATE:
+ return "An encoder or decoder structure is invalid or already freed.";
+ default:
+ return QString("Unknown error code: %i").arg(error);
+ }
+}
+
+
+
+AthenaOpusEncoder::AthenaOpusEncoder(int sampleRate, int numChannels) {
+ _opusSampleRate = sampleRate;
+ _opusChannels = numChannels;
+
+ int error;
+
+ _encoder = opus_encoder_create(sampleRate, numChannels, DEFAULT_APPLICATION, &error);
+
+ if (error != OPUS_OK) {
+ qCCritical(encoder) << "Failed to initialize Opus encoder: " << errorToString(error);
+ _encoder = nullptr;
+ return;
+ }
+
+ setBitrate(DEFAULT_BITRATE);
+ setComplexity(DEFAULT_COMPLEXITY);
+ setApplication(DEFAULT_APPLICATION);
+ setSignal(DEFAULT_SIGNAL);
+
+ qCDebug(encoder) << "Opus encoder initialized, sampleRate = " << sampleRate << "; numChannels = " << numChannels;
+}
+
+AthenaOpusEncoder::~AthenaOpusEncoder() {
+ opus_encoder_destroy(_encoder);
+}
+
+
+
+void AthenaOpusEncoder::encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) {
+
+ PerformanceTimer perfTimer("AthenaOpusEncoder::encode");
+ assert(_encoder);
+
+ encodedBuffer.resize(decodedBuffer.size());
+ int frameSize = decodedBuffer.length() / _opusChannels / static_cast(sizeof(opus_int16));
+
+ int bytes = opus_encode(_encoder, reinterpret_cast(decodedBuffer.constData()), frameSize,
+ reinterpret_cast(encodedBuffer.data()), encodedBuffer.size() );
+
+ if (bytes >= 0) {
+ encodedBuffer.resize(bytes);
+ } else {
+ encodedBuffer.resize(0);
+
+ qCWarning(encoder) << "Error when encoding " << decodedBuffer.length() << " bytes of audio: "
+ << errorToString(bytes);
+ }
+
+}
+
+int AthenaOpusEncoder::getComplexity() const {
+ assert(_encoder);
+ int returnValue;
+ opus_encoder_ctl(_encoder, OPUS_GET_COMPLEXITY(&returnValue));
+ return returnValue;
+}
+
+void AthenaOpusEncoder::setComplexity(int complexity) {
+ assert(_encoder);
+ int returnValue = opus_encoder_ctl(_encoder, OPUS_SET_COMPLEXITY(complexity));
+
+ if (returnValue != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting complexity to " << complexity << ": " << errorToString(returnValue);
+ }
+}
+
+int AthenaOpusEncoder::getBitrate() const {
+ assert(_encoder);
+ int returnValue;
+ opus_encoder_ctl(_encoder, OPUS_GET_BITRATE(&returnValue));
+ return returnValue;
+}
+
+void AthenaOpusEncoder::setBitrate(int bitrate) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_BITRATE(bitrate));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting bitrate to " << bitrate << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getVBR() const {
+ assert(_encoder);
+ int returnValue;
+ opus_encoder_ctl(_encoder, OPUS_GET_VBR(&returnValue));
+ return returnValue;
+}
+
+void AthenaOpusEncoder::setVBR(int vbr) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_VBR(vbr));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting VBR to " << vbr << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getVBRConstraint() const {
+ assert(_encoder);
+ int returnValue;
+ opus_encoder_ctl(_encoder, OPUS_GET_VBR_CONSTRAINT(&returnValue));
+ return returnValue;
+}
+
+void AthenaOpusEncoder::setVBRConstraint(int vbr_const) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_VBR_CONSTRAINT(vbr_const));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting VBR constraint to " << vbr_const << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getMaxBandwidth() const {
+ assert(_encoder);
+ int returnValue;
+ opus_encoder_ctl(_encoder, OPUS_GET_MAX_BANDWIDTH(&returnValue));
+ return returnValue;
+}
+
+void AthenaOpusEncoder::setMaxBandwidth(int maxBandwidth) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_MAX_BANDWIDTH(maxBandwidth));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting max bandwidth to " << maxBandwidth << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getBandwidth() const {
+ assert(_encoder);
+ int bandwidth;
+ opus_encoder_ctl(_encoder, OPUS_GET_BANDWIDTH(&bandwidth));
+ return bandwidth;
+}
+
+void AthenaOpusEncoder::setBandwidth(int bandwidth) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_BANDWIDTH(bandwidth));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting bandwidth to " << bandwidth << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getSignal() const {
+ assert(_encoder);
+ int signal;
+ opus_encoder_ctl(_encoder, OPUS_GET_SIGNAL(&signal));
+ return signal;
+}
+
+void AthenaOpusEncoder::setSignal(int signal) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_SIGNAL(signal));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting signal to " << signal << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getApplication() const {
+ assert(_encoder);
+ int applicationValue;
+ opus_encoder_ctl(_encoder, OPUS_GET_APPLICATION(&applicationValue));
+ return applicationValue;
+}
+
+void AthenaOpusEncoder::setApplication(int application) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_APPLICATION(application));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting application to " << application << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getLookahead() const {
+ assert(_encoder);
+ int lookAhead;
+ opus_encoder_ctl(_encoder, OPUS_GET_LOOKAHEAD(&lookAhead));
+ return lookAhead;
+}
+
+int AthenaOpusEncoder::getInbandFEC() const {
+ assert(_encoder);
+ int fec;
+ opus_encoder_ctl(_encoder, OPUS_GET_INBAND_FEC(&fec));
+ return fec;
+}
+
+void AthenaOpusEncoder::setInbandFEC(int inBandFEC) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_INBAND_FEC(inBandFEC));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting inband FEC to " << inBandFEC << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getExpectedPacketLossPercentage() const {
+ assert(_encoder);
+ int lossPercentage;
+ opus_encoder_ctl(_encoder, OPUS_GET_PACKET_LOSS_PERC(&lossPercentage));
+ return lossPercentage;
+}
+
+void AthenaOpusEncoder::setExpectedPacketLossPercentage(int percentage) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_PACKET_LOSS_PERC(percentage));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting loss percent to " << percentage << ": " << errorToString(errorCode);
+ }
+}
+
+int AthenaOpusEncoder::getDTX() const {
+ assert(_encoder);
+ int dtx;
+ opus_encoder_ctl(_encoder, OPUS_GET_DTX(&dtx));
+ return dtx;
+}
+
+void AthenaOpusEncoder::setDTX(int dtx) {
+ assert(_encoder);
+ int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_DTX(dtx));
+
+ if (errorCode != OPUS_OK) {
+ qCWarning(encoder) << "Error when setting DTX to " << dtx << ": " << errorToString(errorCode);
+ }
+}
diff --git a/plugins/opusCodec/src/OpusEncoder.h b/plugins/opusCodec/src/OpusEncoder.h
new file mode 100644
index 0000000000..10640bf409
--- /dev/null
+++ b/plugins/opusCodec/src/OpusEncoder.h
@@ -0,0 +1,78 @@
+//
+// OpusCodecManager.h
+// plugins/opusCodec/src
+//
+// Copyright 2020 Dale Glass
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#ifndef OPUSENCODER_H
+#define OPUSENCODER_H
+#include
+#include
+
+
+class AthenaOpusEncoder : public Encoder {
+public:
+
+ AthenaOpusEncoder(int sampleRate, int numChannels);
+ ~AthenaOpusEncoder() override;
+
+ virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override;
+
+
+ int getComplexity() const;
+ void setComplexity(int complexity);
+
+ int getBitrate() const;
+ void setBitrate(int bitrate);
+
+ int getVBR() const;
+ void setVBR(int vbr);
+
+ int getVBRConstraint() const;
+ void setVBRConstraint(int vbrConstraint);
+
+ int getMaxBandwidth() const;
+ void setMaxBandwidth(int maxBandwidth);
+
+ int getBandwidth() const;
+ void setBandwidth(int bandwidth);
+
+ int getSignal() const;
+ void setSignal(int signal);
+
+ int getApplication() const;
+ void setApplication(int application);
+
+ int getLookahead() const;
+
+ int getInbandFEC() const;
+ void setInbandFEC(int inBandFEC);
+
+ int getExpectedPacketLossPercentage() const;
+ void setExpectedPacketLossPercentage(int percentage);
+
+ int getDTX() const;
+ void setDTX(int dtx);
+
+
+private:
+
+ const int DEFAULT_BITRATE = 128000;
+ const int DEFAULT_COMPLEXITY = 10;
+ const int DEFAULT_APPLICATION = OPUS_APPLICATION_VOIP;
+ const int DEFAULT_SIGNAL = OPUS_AUTO;
+
+ int _opusSampleRate = 0;
+ int _opusChannels = 0;
+ int _opusExpectedLoss = 0;
+
+
+ OpusEncoder* _encoder = nullptr;
+};
+
+
+#endif // OPUSENCODER_H
diff --git a/plugins/opusCodec/src/plugin.json b/plugins/opusCodec/src/plugin.json
new file mode 100644
index 0000000000..17217d6017
--- /dev/null
+++ b/plugins/opusCodec/src/plugin.json
@@ -0,0 +1,4 @@
+{
+ "name": "Opus Codec",
+ "version": 1
+}
diff --git a/script-archive/tests/performance/renderableMatrix.js b/script-archive/tests/performance/renderableMatrix.js
index dd0fd6e54d..04946328cc 100644
--- a/script-archive/tests/performance/renderableMatrix.js
+++ b/script-archive/tests/performance/renderableMatrix.js
@@ -114,7 +114,7 @@ Script.setInterval(function () {
if (isModel) {
properties.modelURL = type;
} else if (type === 'Web') {
- properties.sourceUrl = 'https://highfidelity.com';
+ properties.sourceUrl = 'https://projectathena.io';
} else {
properties.color = { red: x / ROWS_X * 255, green: y / ROWS_Y * 255, blue: z / ROWS_Z * 255 };
if (type === 'ParticleEffect') {
diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js
index 795458f05d..7ea1632314 100644
--- a/scripts/defaultScripts.js
+++ b/scripts/defaultScripts.js
@@ -39,7 +39,7 @@ var DEFAULT_SCRIPTS_COMBINED = [
var DEFAULT_SCRIPTS_SEPARATE = [
"system/controllers/controllerScripts.js",
"communityModules/notificationCore/notificationCore.js",
- "communityModules/chat/FloofChat.js"
+ {"stable": "communityModules/chat/FloofChat.js", "beta": "https://content.fluffy.ws/scripts/chat/FloofChat.js"}
//"system/chat.js"
];
@@ -53,7 +53,9 @@ var MENU_CATEGORY = "Developer > Scripting";
var MENU_ITEM = "Debug defaultScripts.js";
var SETTINGS_KEY = '_debugDefaultScriptsIsChecked';
-var previousSetting = Settings.getValue(SETTINGS_KEY);
+var SETTINGS_KEY_BETA = '_betaDefaultScriptsIsChecked';
+var previousSetting = Settings.getValue(SETTINGS_KEY, false);
+var previousSettingBeta = Settings.getValue(SETTINGS_KEY_BETA, false);
if (previousSetting === '' || previousSetting === false || previousSetting === 'false') {
previousSetting = false;
@@ -77,17 +79,30 @@ function loadSeparateDefaults() {
for (var i in DEFAULT_SCRIPTS_SEPARATE) {
var shouldLoadCurrentDefaultScript = true;
+ var scriptItem = DEFAULT_SCRIPTS_SEPARATE[i];
+ if (typeof scriptItem === "object") {
+ if (previousSettingBeta) {
+ console.log("Loading Beta item " + scriptItem.beta);
+ scriptItem = scriptItem.beta;
+ } else {
+ scriptItem = scriptItem.stable;
+ }
+ }
for (var j = 0; j < currentlyRunningScripts.length; j++) {
var currentRunningScriptObject = currentlyRunningScripts[j];
- var currentDefaultScriptName = DEFAULT_SCRIPTS_SEPARATE[i].substr((DEFAULT_SCRIPTS_SEPARATE[i].lastIndexOf("/") + 1), DEFAULT_SCRIPTS_SEPARATE[i].length);
+ var currentDefaultScriptName = scriptItem.substr((scriptItem.lastIndexOf("/") + 1), scriptItem.length);
if (currentDefaultScriptName === currentRunningScriptObject.name) {
- shouldLoadCurrentDefaultScript = false;
+ if (currentRunningScriptObject.url !== scriptItem) {
+ ScriptDiscoveryService.stopScript(currentRunningScriptObject.url);
+ } else {
+ shouldLoadCurrentDefaultScript = false;
+ }
}
}
if (shouldLoadCurrentDefaultScript) {
- Script.load(DEFAULT_SCRIPTS_SEPARATE[i]);
+ Script.load(scriptItem);
}
}
}
@@ -161,7 +176,7 @@ function removeMenuItem() {
}
}
-Script.scriptEnding.connect(function() {
+Script.scriptEnding.connect(function () {
removeMenuItem();
});
diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js
index c57f4bae50..ef07aa4d6e 100644
--- a/scripts/system/create/edit.js
+++ b/scripts/system/create/edit.js
@@ -427,7 +427,7 @@ const DEFAULT_ENTITY_PROPERTIES = {
y: 0.9,
z: 0.01
},
- sourceUrl: "https://highfidelity.com/",
+ sourceUrl: "https://projectathena.io/",
dpi: 30,
},
ParticleEffect: {
diff --git a/tools/jsdoc/hifi-jsdoc-template/static/styles/main.css b/tools/jsdoc/hifi-jsdoc-template/static/styles/main.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tools/jsdoc/hifi-jsdoc-template/static/styles/responsive.css b/tools/jsdoc/hifi-jsdoc-template/static/styles/responsive.css
new file mode 100644
index 0000000000..cc730818b6
--- /dev/null
+++ b/tools/jsdoc/hifi-jsdoc-template/static/styles/responsive.css
@@ -0,0 +1,17 @@
+.nav-header {
+ display: none;
+}
+
+nav {
+ display: none !important;
+}
+
+section {
+ margin-right: 0px !important;
+}
+
+#main {
+ margin-left: 15px !important;
+ margin-right: 15px !important;
+ overflow: auto;
+}
\ No newline at end of file
diff --git a/tools/jsdoc/hifi-jsdoc-template/tmpl/layout.tmpl b/tools/jsdoc/hifi-jsdoc-template/tmpl/layout.tmpl
index 7093109ae1..6d12ccd816 100644
--- a/tools/jsdoc/hifi-jsdoc-template/tmpl/layout.tmpl
+++ b/tools/jsdoc/hifi-jsdoc-template/tmpl/layout.tmpl
@@ -4,10 +4,10 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-