aboutsummaryrefslogtreecommitdiff
path: root/externals/oboe/apps/fxlab/app/src/main/cpp
diff options
context:
space:
mode:
authorswurl <swurl@swurl.xyz>2025-05-31 02:33:02 -0400
committerswurl <swurl@swurl.xyz>2025-05-31 02:33:02 -0400
commit6c655321e6b04b8648802e296bb5ca11d290ae68 (patch)
tree5c906511e4a2910ce8b806bb9d763b524c28619e /externals/oboe/apps/fxlab/app/src/main/cpp
parentc0cceff365f754f8859f4c9a0362ebdba7ea388b (diff)
Move dead submodules in-tree
Signed-off-by: swurl <swurl@swurl.xyz>
Diffstat (limited to 'externals/oboe/apps/fxlab/app/src/main/cpp')
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/DuplexCallback.h80
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.cpp93
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.h64
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/FunctionList.h85
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/CombFilter.h53
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/DelayLineEffect.h79
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/DoublingEffect.h34
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/DriveControl.h41
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/EchoEffect.h33
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/Effects.h61
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/FlangerEffect.h29
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/SingleFunctionEffects.h56
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/SlapbackEffect.h30
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/TremoloEffect.h43
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/VibratroEffect.h27
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/WhiteChorusEffect.h32
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/AllPassDescription.h48
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DistortionDescription.h46
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DoublingDescription.h33
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EchoDescription.h48
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EffectDescription.h107
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FIRDescription.h46
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FlangerDescription.h50
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/GainDescription.h50
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/IIRDescription.h50
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/OverdriveDescription.h51
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/PassthroughDescription.h48
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/SlapbackDescription.h50
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/TremoloDescription.h46
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/VibratoDescription.h47
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/WhiteChorusDescription.h49
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/DelayLine.h44
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/PhaseAccumulator.h41
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/SineWave.h37
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/WhiteNoise.h36
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/logging_macros.h46
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/native-lib.cpp160
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/tests/.gitignore5
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/tests/CMakeLists.txt15
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineEffectTest.h52
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineTest.h61
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/tests/TypeTests.h54
-rw-r--r--externals/oboe/apps/fxlab/app/src/main/cpp/tests/testEffects.cpp29
43 files changed, 2189 insertions, 0 deletions
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexCallback.h b/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexCallback.h
new file mode 100644
index 0000000000..1be1bdddec
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexCallback.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_DUPLEXCALLBACK_H
+#define ANDROID_FXLAB_DUPLEXCALLBACK_H
+
+#include <oboe/Oboe.h>
+
+
+
+// This callback handles mono in, stereo out synchronized audio passthrough.
+// It takes a function which operates on two pointers (beginning and end)
+// of underlying data.
+
+template<class numeric_type>
+class DuplexCallback : public oboe::AudioStreamCallback {
+public:
+
+ DuplexCallback(oboe::AudioStream &inStream,
+ std::function<void(numeric_type *, numeric_type *)> fun,
+ size_t buffer_size, std::function<void(void)> restartFunction) :
+ kBufferSize(buffer_size), inRef(inStream), f(fun), restart(restartFunction) {}
+
+
+ oboe::DataCallbackResult
+ onAudioReady(oboe::AudioStream *outputStream, void *audioData, int32_t numFrames) override {
+ auto *outputData = static_cast<numeric_type *>(audioData);
+ auto outputChannelCount = outputStream->getChannelCount();
+
+ // Silence first to simplify glitch detection
+ std::fill(outputData, outputData + numFrames * outputChannelCount, 0);
+ oboe::ResultWithValue<int32_t> result = inRef.read(inputBuffer.get(), numFrames, 0);
+ int32_t framesRead = result.value();
+ if (!result) {
+ inRef.requestStop();
+ return oboe::DataCallbackResult::Stop;
+ }
+ if (mSpinUpCallbacks > 0 && framesRead > 0) {
+ mSpinUpCallbacks--;
+ return oboe::DataCallbackResult::Continue;
+ }
+ f(inputBuffer.get(), inputBuffer.get() + framesRead);
+ for (int i = 0; i < framesRead; i++) {
+ for (size_t j = 0; j < outputChannelCount; j++) {
+ *outputData++ = inputBuffer[i];
+ }
+ }
+ return oboe::DataCallbackResult::Continue;
+ }
+
+ void onErrorAfterClose(oboe::AudioStream *, oboe::Result result) override {
+ inRef.close();
+ if (result == oboe::Result::ErrorDisconnected) {
+ restart();
+ }
+ }
+
+
+private:
+ int mSpinUpCallbacks = 10; // We will let the streams sync for the first few valid frames
+ const size_t kBufferSize;
+ oboe::AudioStream &inRef;
+ std::function<void(numeric_type *, numeric_type *)> f;
+ std::function<void(void)> restart;
+ std::unique_ptr<numeric_type[]> inputBuffer = std::make_unique<numeric_type[]>(kBufferSize);
+};
+
+#endif //ANDROID_FXLAB_DUPLEXCALLBACK_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.cpp b/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.cpp
new file mode 100644
index 0000000000..123d52c33a
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DuplexEngine.h"
+#include "effects/Effects.h"
+
+DuplexEngine::DuplexEngine() {
+ beginStreams();
+}
+
+void DuplexEngine::beginStreams() {
+ // This ordering is extremely important
+ openInStream();
+ if (inStream->getFormat() == oboe::AudioFormat::Float) {
+ functionList.emplace<FunctionList<float *>>();
+ createCallback<float_t>();
+ } else if (inStream->getFormat() == oboe::AudioFormat::I16) {
+ createCallback<int16_t>();
+ } else {
+ stopStreams();
+ }
+ SAMPLE_RATE = inStream->getSampleRate();
+ openOutStream();
+
+ oboe::Result result = startStreams();
+ if (result != oboe::Result::OK) stopStreams();
+}
+
+template<class numeric>
+void DuplexEngine::createCallback() {
+ mCallback = std::make_unique<DuplexCallback<numeric>>(
+ *inStream, [&functionStack = this->functionList](numeric *beg, numeric *end) {
+ std::get<FunctionList<numeric *>>(functionStack)(beg, end);
+ },
+ inStream->getBufferCapacityInFrames(),
+ std::bind(&DuplexEngine::beginStreams, this));
+}
+
+
+oboe::AudioStreamBuilder DuplexEngine::defaultBuilder() {
+ return *oboe::AudioStreamBuilder()
+ .setPerformanceMode(oboe::PerformanceMode::LowLatency)
+ ->setSharingMode(oboe::SharingMode::Exclusive);
+}
+
+void DuplexEngine::openInStream() {
+ defaultBuilder().setDirection(oboe::Direction::Input)
+ ->setFormat(oboe::AudioFormat::Float) // For now
+ ->setChannelCount(1) // Mono in for effects processing
+ ->openManagedStream(inStream);
+}
+
+void DuplexEngine::openOutStream() {
+ defaultBuilder().setCallback(mCallback.get())
+ ->setSampleRate(inStream->getSampleRate())
+ ->setFormat(inStream->getFormat())
+ ->setChannelCount(2) // Stereo out
+ ->openManagedStream(outStream);
+}
+
+oboe::Result DuplexEngine::startStreams() {
+ oboe::Result result = outStream->requestStart();
+ int64_t timeoutNanos = 500 * 1000000; // arbitrary 1/2 second
+ auto currentState = outStream->getState();
+ auto nextState = oboe::StreamState::Unknown;
+ while (result == oboe::Result::OK && currentState != oboe::StreamState::Started) {
+ result = outStream->waitForStateChange(currentState, &nextState, timeoutNanos);
+ currentState = nextState;
+ }
+ if (result != oboe::Result::OK) return result;
+ return inStream->requestStart();
+}
+
+oboe::Result DuplexEngine::stopStreams() {
+ oboe::Result outputResult = inStream->requestStop();
+ oboe::Result inputResult = outStream->requestStop();
+ if (outputResult != oboe::Result::OK) return outputResult;
+ return inputResult;
+}
+
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.h b/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.h
new file mode 100644
index 0000000000..c870fe1ea6
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/DuplexEngine.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef EFFECTS_APP_DUPLEXSTREAM_H
+#define EFFECTS_APP_DUPLEXSTREAM_H
+
+#include <array>
+#include <algorithm>
+#include <variant>
+
+#include <oboe/Oboe.h>
+#include "FunctionList.h"
+#include "DuplexCallback.h"
+
+
+class DuplexEngine {
+public:
+ DuplexEngine();
+
+ void beginStreams();
+
+ virtual ~DuplexEngine() = default;
+
+ oboe::Result startStreams();
+
+ oboe::Result stopStreams();
+
+
+ std::variant<FunctionList<int16_t *>, FunctionList<float *>> functionList{
+ std::in_place_type<FunctionList<int16_t *>>};
+
+private:
+
+ void openInStream();
+
+ void openOutStream();
+
+ static oboe::AudioStreamBuilder defaultBuilder();
+
+ template<class numeric>
+ void createCallback();
+
+ oboe::ManagedStream inStream;
+ std::unique_ptr<oboe::AudioStreamCallback> mCallback;
+ oboe::ManagedStream outStream;
+
+
+};
+
+
+#endif //EFFECTS_APP_DUPLEXSTREAM_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/FunctionList.h b/externals/oboe/apps/fxlab/app/src/main/cpp/FunctionList.h
new file mode 100644
index 0000000000..8513f323c6
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/FunctionList.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef ANDROID_FXLAB_FUNCTIONLIST_H
+#define ANDROID_FXLAB_FUNCTIONLIST_H
+
+#include <vector>
+#include <functional>
+#include <array>
+
+template<class iter_type>
+class FunctionList {
+ std::vector<std::pair<std::function<void(iter_type, iter_type)>, bool>> functionList;
+ bool muted = false;
+public:
+ FunctionList() = default;
+
+ FunctionList(const FunctionList &) = delete;
+
+ FunctionList &operator=(const FunctionList &) = delete;
+
+
+ void operator()(iter_type begin, iter_type end) {
+ for (auto &f : functionList) {
+ if (f.second == true) std::get<0>(f)(begin, end);
+ }
+ if (muted) std::fill(begin, end, 0);
+ }
+
+ void addEffect(std::function<void(iter_type, iter_type)> f) {
+ functionList.emplace_back(std::move(f), true);
+ }
+
+ void removeEffectAt(unsigned int index) {
+ if (index < functionList.size()) {
+ functionList.erase(std::next(functionList.begin(), index));
+ }
+ }
+
+ void rotateEffectAt(unsigned int from, unsigned int to) {
+ auto &v = functionList;
+ if (from >= v.size() || to >= v.size()) return;
+ if (from <= to) {
+ std::rotate(v.begin() + from, v.begin() + from + 1, v.begin() + to + 1);
+ } else {
+ from = v.size() - 1 - from;
+ to = v.size() - 1 - to;
+ std::rotate(v.rbegin() + from, v.rbegin() + from + 1, v.rbegin() + to + 1);
+ }
+ }
+
+ void modifyEffectAt(size_t index, std::function<void(iter_type, iter_type)> fun) {
+ functionList[index] = {std::move(fun), functionList[index].second};
+ }
+
+ void enableEffectAt(size_t index, bool enable) {
+ functionList[index].second = enable;
+ }
+
+ void mute(bool toMute) {
+ muted = toMute;
+ }
+
+ auto getType() {
+ return iter_type();
+ }
+
+};
+
+#endif //ANDROID_FXLAB_FUNCTIONLIST_H
+
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/CombFilter.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/CombFilter.h
new file mode 100644
index 0000000000..c96b907749
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/CombFilter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_COMBFILTER_H
+#define ANDROID_FXLAB_COMBFILTER_H
+
+#include "utils/DelayLine.h"
+
+template <class iter_type>
+class CombFilter {
+
+public:
+ // delay > 0 in samples
+ CombFilter(float blend, float feedForward, float feedBack, int delay) :
+ kBlend(blend),
+ kFeedForward(feedForward),
+ kFeedBack(feedBack),
+ kDelay(static_cast<size_t>(delay)) {}
+
+
+ void operator () (typename std::iterator_traits<iter_type>::reference x) {
+ auto delayOutput = delayLine[kDelay];
+ auto delayInput = x + kFeedBack * delayOutput;
+ delayLine.push(delayInput);
+ x = delayInput * kBlend + delayOutput * kFeedForward;
+ }
+ void operator () (iter_type begin, iter_type end) {
+ for (; begin != end; ++begin) {
+ operator()(*begin);
+ }
+ }
+private:
+ // Weights
+ const float kBlend;
+ const float kFeedForward;
+ const float kFeedBack;
+ const size_t kDelay;
+
+ DelayLine<typename std::iterator_traits<iter_type>::value_type> delayLine {kDelay + 1};
+};
+#endif //ANDROID_FXLAB_COMBFILTER_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DelayLineEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DelayLineEffect.h
new file mode 100644
index 0000000000..436da421db
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DelayLineEffect.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_DELAYLINEEFFECT_H
+#define ANDROID_FXLAB_DELAYLINEEFFECT_H
+
+#include <functional>
+
+#include "utils/SineWave.h"
+#include "utils/DelayLine.h"
+
+// Abstract class for implementing delay line based effects
+// This functor retains state (it must be used sequentially)
+// Effects are float, mono, 48000 hz
+template <class iter_type>
+class DelayLineEffect {
+
+public:
+ // delay > 0, depth in samples, mod is control signal
+ DelayLineEffect(float blend, float feedForward, float feedBack, int delay, int depth, std::function<float()> &&mod) :
+ kBlend(blend),
+ kFeedForward(feedForward),
+ kFeedBack(feedBack),
+ kDelay(delay),
+ kDepth(depth),
+ mMod(mod) { }
+
+
+ void operator () (typename std::iterator_traits<iter_type>::reference x) {
+ auto delayInput = x + kFeedBack * delayLine[kTap];
+ auto variableDelay = mMod() * kDepth + kTap;
+ int index = static_cast<int>(variableDelay);
+ auto fracComp = 1 - (variableDelay - index);
+ //linear
+ // auto interpolated = fracComp * delayLine[index] + (1 - fracComp) * delayLine[index + 1];
+ // all - pass
+ float interpolated = fracComp * delayLine[index] + delayLine[index + 1]
+ - fracComp * prevInterpolated;
+
+ prevInterpolated = interpolated;
+ delayLine.push(delayInput);
+ x = interpolated * kFeedForward + kBlend * delayInput;
+ }
+ void operator () (iter_type begin, iter_type end) {
+ for (; begin != end; ++begin) {
+ operator()(*begin);
+ }
+ }
+private:
+ // Weights
+ const float kBlend;
+ const float kFeedForward;
+ const float kFeedBack;
+ const int kDelay;
+ const int kDepth;
+ const int kTap = kDelay + kDepth;
+
+ // Control function
+ const std::function<float()> mMod;
+
+ // Memory
+ float prevInterpolated = 0; // for all pass interp
+ const size_t kDelayLineSize = kTap + kDepth + 1; // index one is immediate prev sample
+ DelayLine<typename std::iterator_traits<iter_type>::value_type> delayLine {kDelayLineSize};
+};
+#endif //ANDROID_FXLAB_DELAYLINEEFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DoublingEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DoublingEffect.h
new file mode 100644
index 0000000000..44ee025a82
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DoublingEffect.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_DOUBLINGEFFECT_H
+#define ANDROID_FXLAB_DOUBLINGEFFECT_H
+
+#include "DelayLineEffect.h"
+#include "utils/WhiteNoise.h"
+
+
+template <class iter_type>
+class DoublingEffect: public DelayLineEffect<iter_type> {
+public:
+ DoublingEffect(float depth_ms, float delay_ms, float noise_pass):
+ DelayLineEffect<iter_type> {0.7071, 0.7071, 0,
+ static_cast<int>(delay_ms * SAMPLE_RATE / 1000),
+ static_cast<int>(depth_ms * SAMPLE_RATE / 1000),
+ std::function<float()>{WhiteNoise{static_cast<int>(4800 * noise_pass)}}}
+ {}
+};
+#
+#endif //ANDROID_FXLAB_DOUBLINGEFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DriveControl.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DriveControl.h
new file mode 100644
index 0000000000..61846a57b6
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/DriveControl.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_DRIVECONTROL_H
+#define ANDROID_FXLAB_DRIVECONTROL_H
+
+
+#include <functional>
+
+template <class iter_type>
+
+class DriveControl {
+public:
+
+ DriveControl(std::function<void(iter_type, iter_type)> function, double scale):
+ mFunction(function), kScale(scale) {}
+
+ void operator() (iter_type beg, iter_type end) {
+ std::for_each(beg, end, [this](auto &x){x *= kScale;});
+ mFunction(beg, end);
+ std::for_each(beg, end, [this](auto &x){x *= recip;});
+ }
+
+private:
+ std::function<void(iter_type, iter_type)> mFunction;
+ const double kScale;
+ const double recip = 1 / kScale;
+};
+#endif //ANDROID_FXLAB_DRIVECONTROL_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/EchoEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/EchoEffect.h
new file mode 100644
index 0000000000..b0da075391
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/EchoEffect.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_ECHOEFFECT_H
+#define ANDROID_FXLAB_ECHOEFFECT_H
+
+#include "DelayLineEffect.h"
+#include "utils/WhiteNoise.h"
+
+
+template <class iter_type>
+class EchoEffect: public DelayLineEffect<iter_type> {
+public:
+ EchoEffect(float feedback, float delay_ms):
+ DelayLineEffect<iter_type> {1, 0, feedback,
+ static_cast<int>(delay_ms * SAMPLE_RATE / 1000),
+ 0,
+ std::function<float()>{[](){return 0.0;}}}
+ {}
+};
+#endif //ANDROID_FXLAB_ECHOEFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/Effects.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/Effects.h
new file mode 100644
index 0000000000..68bec8cc1b
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/Effects.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_EFFECTS_H
+#define ANDROID_FXLAB_EFFECTS_H
+
+
+// The Sample Rate for effects
+static int SAMPLE_RATE = 48000;
+
+// This header should include the various effect descriptions
+#include "descrip/EffectDescription.h"
+#include "descrip/PassthroughDescription.h"
+#include "descrip/VibratoDescription.h"
+#include "descrip/TremoloDescription.h"
+#include "descrip/GainDescription.h"
+#include "descrip/FlangerDescription.h"
+#include "descrip/WhiteChorusDescription.h"
+#include "descrip/FIRDescription.h"
+#include "descrip/IIRDescription.h"
+#include "descrip/AllPassDescription.h"
+#include "descrip/DoublingDescription.h"
+#include "descrip/OverdriveDescription.h"
+#include "descrip/DistortionDescription.h"
+#include "descrip/EchoDescription.h"
+#include "descrip/SlapbackDescription.h"
+
+constexpr std::tuple<
+ Effect::PassthroughDescription,
+ Effect::TremoloDescription,
+ Effect::VibratoDescription,
+ Effect::GainDescription,
+ Effect::FlangerDescription,
+ Effect::WhiteChorusDescription,
+ Effect::FIRDescription,
+ Effect::IIRDescription,
+ Effect::AllPassDescription,
+ Effect::DoublingDescription,
+ Effect::OverdriveDescription,
+ Effect::DistortionDescription,
+ Effect::EchoDescription,
+ Effect::SlapbackDescription
+> EffectsTuple{};
+
+constexpr size_t numEffects = std::tuple_size<decltype(EffectsTuple)>::value;
+
+
+#endif //ANDROID_FXLAB_EFFECTS_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/FlangerEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/FlangerEffect.h
new file mode 100644
index 0000000000..b3538958a5
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/FlangerEffect.h
@@ -0,0 +1,29 @@
+ /*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_FLANGEREFFECT_H
+#define ANDROID_FXLAB_FLANGEREFFECT_H
+
+#include "DelayLineEffect.h"
+
+template<class iter_type>
+class FlangerEffect : public DelayLineEffect<iter_type> {
+public:
+ // feedback should be 0.7071
+ FlangerEffect(float depth_ms, float frequency, float feedback):
+ DelayLineEffect<iter_type>(feedback, feedback, feedback, 0, depth_ms * SAMPLE_RATE / 1000,
+ SineWave {frequency, 1, SAMPLE_RATE}) { }
+};
+#endif //ANDROID_FXLAB_FLANGEREFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/SingleFunctionEffects.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/SingleFunctionEffects.h
new file mode 100644
index 0000000000..4c8f0df0fc
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/SingleFunctionEffects.h
@@ -0,0 +1,56 @@
+ /*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_SINGLEFUNCTIONEFFECTS_H
+#define ANDROID_FXLAB_SINGLEFUNCTIONEFFECTS_H
+
+#include <list>
+
+ namespace SingleFunctionEffects {
+
+template<class floating>
+void _overdrive (floating &x) {
+ static constexpr double third = (1.0 / 3.0);
+ auto abs = std::abs(x);
+ if (abs <= third) {
+ x *= 2;
+ } else if (abs <= 2 * third) {
+ x = std::copysign((3 - (2 - 3 * abs) * (2 - 3 * abs)) * third, x);
+ } else {
+ x = std::copysign(1, x);
+ }
+}
+
+template <class iter_type>
+void overdrive(iter_type beg, iter_type end) {
+ for (; beg != end; ++beg){
+ _overdrive(*beg);
+ }
+}
+
+template <class floating>
+void _distortion (floating &x) {
+ x = std::copysign(-std::expm1(-std::abs(x)), x);
+}
+
+template <class iter_type>
+void distortion(iter_type beg, iter_type end) {
+ for (; beg != end; ++beg) {
+ _distortion(*beg);
+ }
+}
+
+}
+#endif //ANDROID_FXLAB_SINGLEFUNCTIONEFFECTS_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/SlapbackEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/SlapbackEffect.h
new file mode 100644
index 0000000000..cfbd0638cf
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/SlapbackEffect.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_SLAPBACKEFFECT_H
+#define ANDROID_FXLAB_SLAPBACKEFFECT_H
+
+template <class iter_type>
+class SlapbackEffect: public DelayLineEffect<iter_type> {
+public:
+ SlapbackEffect(float feedforward, float delay_ms):
+ DelayLineEffect<iter_type> {1, feedforward, 0,
+ static_cast<int>(delay_ms * SAMPLE_RATE / 1000),
+ 0,
+ std::function<float()>{[](){return 0.0;}}}
+ {}
+};
+#endif //ANDROID_FXLAB_SLAPBACKEFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/TremoloEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/TremoloEffect.h
new file mode 100644
index 0000000000..4b8de1a673
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/TremoloEffect.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_TREMOLOEFFECT_H
+#define ANDROID_FXLAB_TREMOLOEFFECT_H
+
+
+#include "utils/SineWave.h"
+
+class TremoloEffect {
+public:
+ TremoloEffect(float frequency, float height):
+ kCenter(1 - height),
+ kSignal {SineWave{frequency, height, SAMPLE_RATE}} { }
+
+ template <class numeric_type>
+ void operator () (numeric_type &x) {
+ x = x * (kSignal() + kCenter);
+ }
+ template <class iter_type>
+ void operator () (iter_type begin, iter_type end) {
+ for (; begin != end; ++begin) {
+ operator()(*begin);
+ }
+ }
+private:
+ const float kCenter;
+ std::function<float()> kSignal;
+};
+#endif //ANDROID_FXLAB_TREMOLOEFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/VibratroEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/VibratroEffect.h
new file mode 100644
index 0000000000..16f2682399
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/VibratroEffect.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_VIBRATROEFFECT_H
+#define ANDROID_FXLAB_VIBRATROEFFECT_H
+
+#include "DelayLineEffect.h"
+template <class iter_type>
+class VibratoEffect : public DelayLineEffect<iter_type> {
+public:
+ VibratoEffect(float depth_ms, float frequency):
+ DelayLineEffect<iter_type>(0, 1, 0, 1, depth_ms * SAMPLE_RATE / 1000,
+ SineWave {frequency, 1, SAMPLE_RATE}) { }
+};
+#endif //ANDROID_FXLAB_VIBRATROEFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/WhiteChorusEffect.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/WhiteChorusEffect.h
new file mode 100644
index 0000000000..941d1c02ca
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/WhiteChorusEffect.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_WHITECHORUSEFFECT_H
+#define ANDROID_FXLAB_WHITECHORUSEFFECT_H
+
+#include "DelayLineEffect.h"
+#include "utils/WhiteNoise.h"
+
+template <class iter_type>
+class WhiteChorusEffect : public DelayLineEffect<iter_type> {
+public:
+ WhiteChorusEffect(float depth_ms, float delay_ms, float noise_pass):
+ DelayLineEffect<iter_type> {0.7071, 1, -0.7071f,
+ static_cast<int>(delay_ms * SAMPLE_RATE / 1000),
+ static_cast<int>(depth_ms * SAMPLE_RATE / 1000),
+ std::function<float()>{WhiteNoise{static_cast<int>(4800 * noise_pass)}}}
+ {}
+};
+#endif //ANDROID_FXLAB_WHITECHORUSEFFECT_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/AllPassDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/AllPassDescription.h
new file mode 100644
index 0000000000..cba3434fa4
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/AllPassDescription.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_ALLPASSDESCRIPTION_H
+#define ANDROID_FXLAB_ALLPASSDESCRIPTION_H
+
+
+#include "EffectDescription.h"
+#include "../CombFilter.h"
+namespace Effect {
+class AllPassDescription: public EffectDescription<AllPassDescription, 2> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("AllPass");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Comb");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Delay (samples)", 1, 500, 10),
+ ParamType("Scale", 0.01, 0.99, 0.5),
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ CombFilter<iter_type>{paramArr[1], 1, -(paramArr[1]), static_cast<int>(paramArr[0])}
+ };
+ }
+};
+} //namespace Effect
+
+#endif //ANDROID_FXLAB_ALLPASSDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DistortionDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DistortionDescription.h
new file mode 100644
index 0000000000..db88122374
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DistortionDescription.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_DISTORTIONDESCRIPTION_H
+#define ANDROID_FXLAB_DISTORTIONDESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../SingleFunctionEffects.h"
+
+namespace Effect {
+class DistortionDescription: public EffectDescription<DistortionDescription, 1> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Distortion");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Nonlinear");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Drive (db)", -10, 50, 0)
+ };
+ }
+
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ double scale = pow(2.0, paramArr[0] / 10);
+ return DriveControl<iter_type> {SingleFunctionEffects::distortion<iter_type>, scale};
+ }
+};
+}
+#endif //ANDROID_FXLAB_DISTORTIONDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DoublingDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DoublingDescription.h
new file mode 100644
index 0000000000..18d62d3151
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/DoublingDescription.h
@@ -0,0 +1,33 @@
+#ifndef ANDROID_FXLAB_DOUBLINGDESCRIPTION_H
+#define ANDROID_FXLAB_DOUBLINGDESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../DoublingEffect.h"
+
+namespace Effect {
+class DoublingDescription: public EffectDescription<DoublingDescription, 3> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Doubling");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Delay");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Depth (ms)", 10, 100, 40),
+ ParamType("Delay (ms)", 1, 100, 40),
+ ParamType("Noise pass", 1, 10, 4),
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ DoublingEffect<iter_type>{paramArr[0], paramArr[1], paramArr[2]}
+ };
+ }
+};
+} //namespace Effect
+#endif //ANDROID_FXLAB_DOUBLINGDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EchoDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EchoDescription.h
new file mode 100644
index 0000000000..26cb19c670
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EchoDescription.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_ECHODESCRIPTION_H
+#define ANDROID_FXLAB_ECHODESCRIPTION_H
+
+#include "../EchoEffect.h"
+
+namespace Effect {
+
+class EchoDescription: public EffectDescription<EchoDescription, 2> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Echo");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Delay");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Feedback", 0, 1, 0.5),
+ ParamType("Delay (ms)", 50, 500, 100),
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ EchoEffect<iter_type>{paramArr[0], paramArr[1]}
+ };
+ }
+};
+
+} //namespace Effect
+#endif //ANDROID_FXLAB_ECHODESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EffectDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EffectDescription.h
new file mode 100644
index 0000000000..e3955b08c4
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/EffectDescription.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_EFFECTDESCRIPTION_H
+#define ANDROID_FXLAB_EFFECTDESCRIPTION_H
+
+#include <functional>
+#include <array>
+#include <vector>
+#include <string_view>
+
+template<class iter_type>
+using _ef = std::function<void(iter_type, iter_type)>;
+
+// Only Effect Descriptions should use this namespace
+namespace Effect {
+
+ class ParamType {
+ public:
+ constexpr ParamType(std::string_view name, float minVal, float maxVal, float defVal) :
+ kName(name),
+ kMinVal(minVal),
+ kMaxVal(maxVal),
+ kDefVal(defVal) {}
+
+ constexpr ParamType(const ParamType &other) = delete;
+
+ ParamType &operator=(const ParamType &other) = delete;
+
+ constexpr ParamType(ParamType &&other) = default;
+
+ constexpr ParamType &operator=(ParamType &&other) = delete;
+
+ const std::string_view kName;
+ const float kMinVal, kMaxVal, kDefVal;
+ };
+
+
+// EffectType is the description subclass, N is num of params
+// Function implementations in this class contain shared behavior
+// Which can be shadowed.
+ template<class EffectType, size_t N>
+ class EffectDescription {
+ public:
+ // These methods will be shadowed by subclasses
+
+ static constexpr size_t getNumParams() {
+ return N;
+ }
+
+ static constexpr std::array<float, N> getEmptyParams() {
+ return std::array<float, EffectType::getNumParams()>();
+ }
+
+ static constexpr std::string_view getName();
+
+ static constexpr std::string_view getCategory();
+
+ static constexpr std::array<ParamType, N> getParams();
+
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, N> paramArr);
+
+
+ template<class iter_type>
+ static _ef<iter_type> buildDefaultEffect() {
+ auto params = EffectType::getEmptyParams();
+ int i = 0;
+ for (ParamType &mParam: EffectType::getParams()) {
+ params[i++] = mParam.kDefVal;
+ }
+ return EffectType::template buildEffect<iter_type>(params);
+ }
+
+ // The default behavior is new effect, can be shadowed
+ template<class iter_type>
+ static _ef<iter_type> modifyEffect(
+ _ef<iter_type> /* effect */, std::array<float, N> paramArr) {
+ return EffectType::template buildEffect<iter_type>(std::move(paramArr));
+ }
+ template <class iter_type>
+ static _ef<iter_type> modifyEffectVec(
+ _ef<iter_type> effect, std::vector<float> paramVec) {
+ std::array<float, N> arr;
+ std::copy_n(paramVec.begin(), N, arr.begin());
+ return EffectType::template modifyEffect<iter_type>(
+ std::move(effect), std::move(arr));
+ }
+ };
+
+} // namespace effect
+
+
+#endif //ANDROID_FXLAB_EFFECTDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FIRDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FIRDescription.h
new file mode 100644
index 0000000000..6aec5ea407
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FIRDescription.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_FIRDESCRIPTION_H
+#define ANDROID_FXLAB_FIRDESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../CombFilter.h"
+namespace Effect {
+class FIRDescription: public EffectDescription<FIRDescription, 2> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("FIR");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Comb");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Delay (samples)", 1, 500, 10),
+ ParamType("Gain", 0, 0.99, 0.5),
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ CombFilter<iter_type>{1, paramArr[1], 0, static_cast<int>(paramArr[0])}
+ };
+ }
+};
+} //namespace Effect
+#endif //ANDROID_FXLAB_FIRDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FlangerDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FlangerDescription.h
new file mode 100644
index 0000000000..08a822b052
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/FlangerDescription.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_FLANGERDESCRIPTION_H
+#define ANDROID_FXLAB_FLANGERDESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../FlangerEffect.h"
+
+namespace Effect {
+class FlangerDescription : public EffectDescription<FlangerDescription, 3> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Flanger");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Delay");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, 3> {
+ ParamType("Depth (ms)", 0.1, 2, 1),
+ ParamType("Frequency", 0.1, 1, 0.2),
+ ParamType("Feedback", 0, 0.95, 0.7071),
+ };
+ }
+
+ template <class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return std::function<void(iter_type, iter_type)> {
+ FlangerEffect<iter_type>{paramArr[0], paramArr[1], paramArr[2]}
+ };
+ }
+
+};
+} // namespace Effect
+#endif //ANDROID_FXLAB_FLANGERDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/GainDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/GainDescription.h
new file mode 100644
index 0000000000..ec4a203fd0
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/GainDescription.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_GAINDESCRIPTION_H
+#define ANDROID_FXLAB_GAINDESCRIPTION_H
+#include "EffectDescription.h"
+#include <cmath>
+#include <iostream>
+
+namespace Effect {
+class GainDescription : public EffectDescription<GainDescription, 1> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Gain");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("None");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array <ParamType, getNumParams()> {
+ ParamType("Gain", -30, 20, 0)
+ };
+ }
+
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ float scale = paramArr[0] / 10;
+ return _ef<iter_type> {
+ [=](iter_type beg, iter_type end) {
+ for (; beg != end; ++beg) *beg *= pow(2.0, scale);
+ }
+ };
+ }
+};
+} // namespace Effect
+#endif //ANDROID_FXLAB_GAINDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/IIRDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/IIRDescription.h
new file mode 100644
index 0000000000..aab41eeff9
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/IIRDescription.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_IIRDESCRIPTION_H
+#define ANDROID_FXLAB_IIRDESCRIPTION_H
+
+
+#include "../CombFilter.h"
+
+namespace Effect {
+class IIRDescription: public EffectDescription<IIRDescription, 3> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("IIR");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Comb");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Delay (samples)", 1, 500, 10),
+ ParamType("Gain", 0, 0.99, 0.5),
+ ParamType("Scale", 0.25, 0.99, 0.5)
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ CombFilter<iter_type>{paramArr[2], 0, paramArr[1], static_cast<int>(paramArr[0])}
+ };
+ }
+};
+} //namespace Effect
+#
+#endif //ANDROID_FXLAB_IIRDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/OverdriveDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/OverdriveDescription.h
new file mode 100644
index 0000000000..f5ca5e373d
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/OverdriveDescription.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_OVERDRIVEDESCRIPTION_H
+#define ANDROID_FXLAB_OVERDRIVEDESCRIPTION_H
+
+#include <limits>
+#include <cmath>
+#include <iterator>
+
+#include "EffectDescription.h"
+#include "../SingleFunctionEffects.h"
+#include "../DriveControl.h"
+
+namespace Effect {
+class OverdriveDescription : public EffectDescription<OverdriveDescription, 1> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Overdrive");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Nonlinear");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()>{
+ ParamType("Drive (db)", -10, 50, 0)
+ };
+ }
+
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ double scale = pow(2.0, paramArr[0] / 10);
+ return DriveControl<iter_type> {SingleFunctionEffects::overdrive<iter_type>, scale};
+ }
+};
+}
+#endif //ANDROID_FXLAB_OVERDRIVEDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/PassthroughDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/PassthroughDescription.h
new file mode 100644
index 0000000000..9a309ae7fc
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/PassthroughDescription.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_PASSTHROUGHDESCRIPTION_H
+#define ANDROID_FXLAB_PASSTHROUGHDESCRIPTION_H
+
+
+#include "EffectDescription.h"
+
+namespace Effect {
+
+class PassthroughDescription : public EffectDescription<PassthroughDescription, 0> {
+public:
+
+ static constexpr std::string_view getName() {
+ return std::string_view("Passthrough");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("None");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, 0>();
+ }
+
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> ) {
+ return [](iter_type, iter_type) {};
+ }
+
+};
+
+} // namespace Effect
+
+#endif //ANDROID_FXLAB_PASSTHROUGHDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/SlapbackDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/SlapbackDescription.h
new file mode 100644
index 0000000000..cd77656cb0
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/SlapbackDescription.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_SLAPBACKDESCRIPTION_H
+#define ANDROID_FXLAB_SLAPBACKDESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../SlapbackEffect.h"
+
+
+namespace Effect {
+
+class SlapbackDescription: public EffectDescription<SlapbackDescription, 2> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Slapback");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Delay");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Feedforward", 0, 2, 0.5),
+ ParamType("Delay (ms)", 30, 100, 50),
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ SlapbackEffect<iter_type>{paramArr[0], paramArr[1]}
+ };
+ }
+};
+
+} //namespace Effect
+#endif //ANDROID_FXLAB_SLAPBACKDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/TremoloDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/TremoloDescription.h
new file mode 100644
index 0000000000..2abff9b1d0
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/TremoloDescription.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_TREMOLODESCRIPTION_H
+#define ANDROID_FXLAB_TREMOLODESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../TremoloEffect.h"
+namespace Effect {
+class TremoloDescription : public EffectDescription<TremoloDescription, 2> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Tremolo");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("None");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Frequency", 0.1, 5.0, 2),
+ ParamType("Height", 0.05, 0.45, 0.25)
+ };
+ }
+
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr ) {
+ return _ef<iter_type> {
+ TremoloEffect {paramArr[0], paramArr[1]}};
+ }
+};
+} // namespace Effect
+#endif // ANDROID_FXLAB_TREMOLODESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/VibratoDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/VibratoDescription.h
new file mode 100644
index 0000000000..f152faa59f
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/VibratoDescription.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_VIBRATODESCRIPTION_H
+#define ANDROID_FXLAB_VIBRATODESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../VibratroEffect.h"
+
+namespace Effect {
+class VibratoDescription : public EffectDescription<VibratoDescription, 2> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("Vibrato");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Delay");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Depth (ms)", 0, 3, 1),
+ ParamType("Frequency", 0.1, 5, 1)
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ VibratoEffect<iter_type>{paramArr[0], paramArr[1]}
+ };
+ }
+};
+} //namespace Effect
+#endif //ANDROID_FXLAB_VIBRATODESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/WhiteChorusDescription.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/WhiteChorusDescription.h
new file mode 100644
index 0000000000..d1d71d7482
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/descrip/WhiteChorusDescription.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_WHITECHORUSDESCRIPTION_H
+#define ANDROID_FXLAB_WHITECHORUSDESCRIPTION_H
+
+#include "EffectDescription.h"
+#include "../WhiteChorusEffect.h"
+
+namespace Effect {
+class WhiteChorusDescription : public EffectDescription<WhiteChorusDescription, 3> {
+public:
+ static constexpr std::string_view getName() {
+ return std::string_view("White Chorus");
+ }
+
+ static constexpr std::string_view getCategory() {
+ return std::string_view("Delay");
+ }
+
+ static constexpr std::array<ParamType, getNumParams()> getParams() {
+ return std::array<ParamType, getNumParams()> {
+ ParamType("Depth (ms)", 1, 30, 10),
+ ParamType("Delay (ms)", 1, 30, 10),
+ ParamType("Noise pass", 1, 10, 4),
+ };
+ }
+ template<class iter_type>
+ static _ef<iter_type> buildEffect(std::array<float, getNumParams()> paramArr) {
+ return _ef<iter_type> {
+ WhiteChorusEffect<iter_type>{paramArr[0], paramArr[1], paramArr[2]}
+ };
+ }
+};
+} //namespace Effect
+
+#endif //ANDROID_FXLAB_WHITECHORUSDESCRIPTION_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/DelayLine.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/DelayLine.h
new file mode 100644
index 0000000000..d0d753cf14
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/DelayLine.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_DELAYLINE_H
+#define ANDROID_FXLAB_DELAYLINE_H
+
+#include <vector>
+
+
+template<class T>
+class DelayLine {
+public:
+ DelayLine(std::size_t size): N(size), mArr(N, 0) { }
+ void push(const T& value) {
+ mArr[mfront++] = value;
+ if (mfront == N) mfront = 0;
+ }
+ // indexed from last value written backwards
+ // i.e T-1 to T-N
+ const T& operator[](int i) {
+ int index = mfront - i;
+ if (index < 0) index += N;
+ return mArr[index];
+ }
+
+private:
+ const int N;
+ int mfront = 0;
+ std::vector<T> mArr;
+};
+#endif //ANDROID_FXLAB_DELAYLINE_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/PhaseAccumulator.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/PhaseAccumulator.h
new file mode 100644
index 0000000000..cfd3210cce
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/PhaseAccumulator.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_PHASEACCUMULATOR_H
+#define ANDROID_FXLAB_PHASEACCUMULATOR_H
+
+#include <cmath>
+
+
+
+class PhaseAccumulator {
+public:
+ PhaseAccumulator(float frequency, float sampleRate):
+ f(frequency),
+ fs(sampleRate) { }
+ float incrementPhase() {
+ mPhase += kDelta;
+ if (mPhase >= kTwoPi) mPhase -= kTwoPi;
+ return mPhase;
+ }
+private:
+ float mPhase = 0;
+ const float f;
+ const float fs;
+ static constexpr float kTwoPi = M_PI * 2;
+ const float kDelta = kTwoPi * f / fs;
+};
+#endif //ANDROID_FXLAB_PHASEACCUMULATOR_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/SineWave.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/SineWave.h
new file mode 100644
index 0000000000..a9ce09f4c5
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/SineWave.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_SINEWAVE_H
+#define ANDROID_FXLAB_SINEWAVE_H
+
+#include "PhaseAccumulator.h"
+
+class SineWave {
+public:
+ // freq in hz
+ SineWave(float frequency, float amplitude, int sampleRate):
+ mPhasor(frequency, sampleRate),
+ kAmplitude(amplitude) { }
+
+ float operator() () {
+ return kAmplitude * sinf(mPhasor.incrementPhase());
+ }
+
+private:
+ PhaseAccumulator mPhasor;
+ const float kAmplitude;
+};
+#endif //ANDROID_FXLAB_SINEWAVE_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/WhiteNoise.h b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/WhiteNoise.h
new file mode 100644
index 0000000000..aca54b5dcf
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/effects/utils/WhiteNoise.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_WHITENOISE_H
+#define ANDROID_FXLAB_WHITENOISE_H
+class WhiteNoise {
+ const int kScale;
+public:
+ WhiteNoise(int scale): kScale(scale) {}
+ float operator() () {
+ static int counter = 0;
+ static float r_0, r_1 = 0;
+ if (counter == 0) {
+ r_0 = r_1;
+ r_1 = (static_cast <float> (rand()) / static_cast <float> (RAND_MAX)) * 2 - 1;
+ }
+ float ret = r_0 + counter * (r_1 - r_0) / kScale;
+ if (++counter == kScale) counter = 0;
+ if (ret > 0.99) return 0.99f;
+ if (ret < -0.99) return -0.99f;
+ return ret;
+ }
+};
+#endif //ANDROID_FXLAB_WHITENOISE_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/logging_macros.h b/externals/oboe/apps/fxlab/app/src/main/cpp/logging_macros.h
new file mode 100644
index 0000000000..d2f43282ae
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/logging_macros.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __SAMPLE_ANDROID_DEBUG_H__
+#define __SAMPLE_ANDROID_DEBUG_H__
+#include <android/log.h>
+
+#if 1
+#ifndef MODULE_NAME
+#define MODULE_NAME "AUDIO-APP"
+#endif
+
+#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__)
+#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__)
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__)
+#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,MODULE_NAME, __VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,MODULE_NAME, __VA_ARGS__)
+#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,MODULE_NAME, __VA_ARGS__)
+
+#define ASSERT(cond, ...) if (!(cond)) {__android_log_assert(#cond, MODULE_NAME, __VA_ARGS__);}
+#else
+
+#define LOGV(...)
+#define LOGD(...)
+#define LOGI(...)
+#define LOGW(...)
+#define LOGE(...)
+#define LOGF(...)
+#define ASSERT(cond, ...)
+
+#endif
+
+#endif // __SAMPLE_ANDROID_DEBUG_H__
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/native-lib.cpp b/externals/oboe/apps/fxlab/app/src/main/cpp/native-lib.cpp
new file mode 100644
index 0000000000..165de68bac
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/native-lib.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+
+#include <cassert>
+#include <string>
+#include <functional>
+#include <utility>
+#include <vector>
+
+#include "DuplexEngine.h"
+#include "effects/Effects.h"
+#include "FunctionList.h"
+
+
+// JNI Utility functions and globals
+static DuplexEngine *enginePtr = nullptr;
+
+// Actual JNI interface
+extern "C" {
+
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_createAudioEngine(
+ JNIEnv,
+ jobject /* this */) {
+ enginePtr = new DuplexEngine();
+}
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_destroyAudioEngine(
+ JNIEnv,
+ jobject /* this */) {
+ if (!enginePtr) return;
+ delete enginePtr;
+ enginePtr = nullptr;
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_getEffects(JNIEnv *env, jobject) {
+ jclass jcl = env->FindClass("com/mobileer/androidfxlab/datatype/EffectDescription");
+ jclass jparamcl = env->FindClass("com/mobileer/androidfxlab/datatype/ParamDescription");
+ assert (jcl != nullptr && jparamcl != nullptr);
+
+ auto jparamMethodId = env->GetMethodID(jparamcl, "<init>", "(Ljava/lang/String;FFF)V");
+ auto jMethodId = env->GetMethodID(jcl, "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;I[Lcom/mobileer/androidfxlab/datatype/ParamDescription;)V");
+
+ auto arr = env->NewObjectArray(numEffects, jcl, nullptr);
+ auto lambda = [&](auto &arg, int i) {
+ const auto &paramArr = arg.getParams();
+ auto jparamArr = env->NewObjectArray(paramArr.size(), jparamcl, nullptr);
+ int c = 0;
+ for (auto const &elem: paramArr) {
+ jobject j = env->NewObject(jparamcl, jparamMethodId,
+ env->NewStringUTF(std::string(elem.kName).c_str()),
+ elem.kMinVal, elem.kMaxVal, elem.kDefVal);
+ assert(j != nullptr);
+ env->SetObjectArrayElement(jparamArr, c++, j);
+ }
+ jobject j = env->NewObject(jcl, jMethodId,
+ env->NewStringUTF(std::string(arg.getName()).c_str()),
+ env->NewStringUTF(std::string(arg.getCategory()).c_str()),
+ i, jparamArr);
+ assert(j != nullptr);
+ env->SetObjectArrayElement(arr, i, j);
+ };
+ int i = 0;
+ std::apply([&i, &lambda](auto &&... args) mutable { ((lambda(args, i++)), ...); },
+ EffectsTuple);
+ return arr;
+}
+
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_addDefaultEffectNative(JNIEnv *, jobject, jint jid) {
+ if (!enginePtr) return;
+ auto id = static_cast<int>(jid);
+
+ std::visit([id](auto &&stack) {
+ std::function<void(decltype(stack.getType()), decltype(stack.getType()))> f;
+ int i = 0;
+ std::apply([id, &f, &i](auto &&... args) mutable {
+ ((f = (i++ == id) ?
+ args.template buildDefaultEffect<decltype(stack.getType())>() : f), ...);
+ }, EffectsTuple);
+ stack.addEffect(std::move(f));
+ }, enginePtr->functionList);
+}
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_removeEffectNative(JNIEnv *, jobject, jint jind) {
+ if (!enginePtr) return;
+ auto ind = static_cast<size_t>(jind);
+ std::visit([ind](auto &&arg) {
+ arg.removeEffectAt(ind);
+ }, enginePtr->functionList);
+}
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_rotateEffectNative(JNIEnv *, jobject,
+ jint jfrom, jint jto) {
+ if (!enginePtr) return;
+ auto from = static_cast<size_t>(jfrom);
+ auto to = static_cast<size_t>(jto);
+
+ std::visit([from, to](auto &&arg) {
+ arg.rotateEffectAt(from, to);
+ }, enginePtr->functionList);
+}
+
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_modifyEffectNative(
+ JNIEnv *env, jobject, jint jid, jint jindex, jfloatArray params) {
+ if (!enginePtr) return;
+ int id = static_cast<int>(jid);
+ int index = static_cast<size_t>(jindex);
+
+ jfloat *data = env->GetFloatArrayElements(params, nullptr);
+ std::vector<float> arr{data, data + env->GetArrayLength(params)};
+ env->ReleaseFloatArrayElements(params, data, 0);
+ std::visit([&arr, &id, &index](auto &&stack) {
+ std::function<void(decltype(stack.getType()), decltype(stack.getType()))> ef;
+ int i = 0;
+ std::apply([&](auto &&... args) mutable {
+ ((ef = (i++ == id) ?
+ args.modifyEffectVec(ef, arr) : ef), ...);
+ }, EffectsTuple);
+ stack.modifyEffectAt(index, std::move(ef));
+ }, enginePtr->functionList);
+}
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_enableEffectNative(
+ JNIEnv *, jobject, jint jindex, jboolean jenable) {
+ if (!enginePtr) return;
+ auto ind = static_cast<size_t>(jindex);
+ auto enable = static_cast<bool>(jenable);
+ std::visit([ind, enable](auto &&args) {
+ args.enableEffectAt(ind, enable);
+ }, enginePtr->functionList);
+}
+JNIEXPORT void JNICALL
+Java_com_mobileer_androidfxlab_NativeInterface_enablePassthroughNative(
+ JNIEnv *, jobject, jboolean jenable) {
+ if (!enginePtr) return;
+ std::visit([enable = static_cast<bool>(jenable)](auto &&args) {
+ args.mute(!enable);
+ }, enginePtr->functionList);
+}
+} //extern C
+
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/tests/.gitignore b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/.gitignore
new file mode 100644
index 0000000000..47c0d34d7b
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/.gitignore
@@ -0,0 +1,5 @@
+CMakeFiles/
+CMakeCache.txt
+cmake_install.cmake
+Makefile
+runTests
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/tests/CMakeLists.txt b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/CMakeLists.txt
new file mode 100644
index 0000000000..ae1f0e75d3
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.4.1)
+
+project(Effects_Tests)
+# We need C++17 to test
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+# Locate GTest
+find_package(GTest REQUIRED)
+include_directories(${GTEST_INCLUDE_DIRS})
+
+# Link runTests with what we want to test and the GTest and pthread library
+add_executable(runTests testEffects.cpp)
+target_link_libraries(runTests ${GTEST_LIBRARIES} pthread)
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineEffectTest.h b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineEffectTest.h
new file mode 100644
index 0000000000..de9c15a45e
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineEffectTest.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_DELAYLINEEFFECTTEST_H
+#define ANDROID_FXLAB_DELAYLINEEFFECTTEST_H
+
+
+#include <gtest/gtest.h>
+
+#include "../effects/DelayLineEffect.h"
+
+
+namespace {
+ TEST(DelayLineEffectTest, SingleFeedForwardTest) {
+ DelayLineEffect<float*> e1 {0, 1, 0, 1, 0, [](){return 0;}};
+ std::array<float, 5> inputData {1, 0, 0.5, 0.25, 0};
+ for (int i = 0; i < 5; i++){
+ e1(inputData[i]);
+ }
+ EXPECT_EQ(inputData[0], 0);
+ EXPECT_EQ(inputData[1], 1);
+ EXPECT_EQ(inputData[2], 0);
+ EXPECT_EQ(inputData[3], 0.5);
+ EXPECT_EQ(inputData[4], 0.25);
+ }
+ TEST(DelayLineEffectTest, FFandBlendTest) {
+ DelayLineEffect<float*> e1 {1, 1, 0, 1, 0, [](){return 0;}};
+ std::array<float, 5> inputData {1, 0, 0.5, 0.25, 0};
+ for (int i = 0; i < 5; i++) {
+ e1(inputData[i]);
+ }
+ EXPECT_EQ(inputData[0], 1);
+ EXPECT_EQ(inputData[1], 1);
+ EXPECT_EQ(inputData[2], 0.5);
+ EXPECT_EQ(inputData[3], 0.75);
+ EXPECT_EQ(inputData[4], 0.25);
+ }
+}
+#endif //ANDROID_FXLAB_DELAYLINEEFFECTTEST_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineTest.h b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineTest.h
new file mode 100644
index 0000000000..8fb40fe2f4
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/DelayLineTest.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FXLAB_DELAYLINETEST_H
+#define ANDROID_FXLAB_DELAYLINETEST_H
+
+#include "../effects/utils/DelayLine.h"
+#include <gtest/gtest.h>
+
+namespace {
+TEST(DelayLineTest, CreateAndAdd) {
+ DelayLine<float> d1{10};
+ d1.push(1.0);
+ EXPECT_EQ(d1[1], 1.0);
+}
+TEST(DelayLineTest, UnfilledAddSequence) {
+ DelayLine<float> d1{10};
+d1.push(1.0);
+d1.push(2.0);
+ d1.push(3.0);
+ EXPECT_EQ(d1[1], 3.0);
+ EXPECT_EQ(d1[2], 2.0);
+ EXPECT_EQ(d1[3], 1.0);
+}
+TEST(DelayLineTest, FilledAddSequence) {
+ DelayLine<float> d1{4};
+ d1.push(1.0);
+ d1.push(2.0);
+ d1.push(3.0);
+ d1.push(4.0);
+ EXPECT_EQ(d1[1], 4.0);
+ EXPECT_EQ(d1[2], 3.0);
+ EXPECT_EQ(d1[3], 2.0);
+ EXPECT_EQ(d1[4], 1.0);
+ d1.push(5.0);
+ EXPECT_EQ(d1[1], 5.0);
+ EXPECT_EQ(d1[2], 4.0);
+ EXPECT_EQ(d1[3], 3.0);
+ EXPECT_EQ(d1[4], 2.0);
+ d1.push(6.0);
+ EXPECT_EQ(d1[1], 6.0);
+ EXPECT_EQ(d1[2], 5.0);
+ EXPECT_EQ(d1[3], 4.0);
+ EXPECT_EQ(d1[4], 3.0);
+}
+
+} // namespace
+#endif //ANDROID_FXLAB_DELAYLINETEST_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/tests/TypeTests.h b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/TypeTests.h
new file mode 100644
index 0000000000..b7e242ea61
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/TypeTests.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_FXLAB_TYPETESTS_H
+#define ANDROID_FXLAB_TYPETESTS_H
+
+
+#include <gtest/gtest.h>
+#include <iostream>
+#include <unistd.h>
+
+#include "../effects/Effects.h"
+#include "../FunctionList.h"
+namespace {
+TEST(TypeTests, Templating) {
+ TremoloEffect t {1, 2};
+ VibratoEffect<float*> v {1, 2};
+ float x = 5;
+ t(x);
+ auto pass = std::get<0>(EffectsTuple);
+ auto descrip = std::get<1>(EffectsTuple);
+ auto vibdes = std::get<2>(EffectsTuple);
+ auto gaindes = std::get<3>(EffectsTuple);
+ auto f = descrip.buildDefaultEffect<float*>();
+ auto g = vibdes.buildDefaultEffect<float*>();
+ auto h = vibdes.buildDefaultEffect<float*>();
+ f(&x, &x + 1); g(&x, &x + 1); h(&x, &x + 1);
+ auto j = gaindes.buildDefaultEffect<float*>();
+ auto k = gaindes.modifyEffect<float*>(j, std::array<float, 1> {10});
+ float floatArr[4] = {1,2,3, 4};
+ for (int i =0; i < 4; i++) {
+ k(floatArr + i, floatArr + i + 1);
+ }
+ auto arr = std::array<float, 1> {10};
+ auto data = std::array<int, 5> {1, 2, 3, 4, 5};
+ std::function<void(int*, int*)> fe = std::get<Effect::GainDescription>(EffectsTuple).buildEffect<int*>(arr);
+ fe(data.begin(), data.end());
+ EXPECT_EQ(data[0], 2);
+
+}
+}
+#endif //ANDROID_FXLAB_TYPETESTS_H
diff --git a/externals/oboe/apps/fxlab/app/src/main/cpp/tests/testEffects.cpp b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/testEffects.cpp
new file mode 100644
index 0000000000..b40c712d32
--- /dev/null
+++ b/externals/oboe/apps/fxlab/app/src/main/cpp/tests/testEffects.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <gtest/gtest.h>
+
+#include "DelayLineTest.h"
+#include "DelayLineEffectTest.h"
+#include "TypeTests.h"
+// This is the runner for the various unit tests in the test directory
+// Currently it is designed to be run on the development machine via CMAKE
+// Since this tests effects, it should be independent of Android, and simply test locally
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}