diff options
| author | swurl <swurl@swurl.xyz> | 2025-05-31 02:33:02 -0400 |
|---|---|---|
| committer | swurl <swurl@swurl.xyz> | 2025-05-31 02:33:02 -0400 |
| commit | 6c655321e6b04b8648802e296bb5ca11d290ae68 (patch) | |
| tree | 5c906511e4a2910ce8b806bb9d763b524c28619e /externals/oboe/apps/fxlab/app/src/main/cpp | |
| parent | c0cceff365f754f8859f4c9a0362ebdba7ea388b (diff) | |
Move dead submodules in-tree
Signed-off-by: swurl <swurl@swurl.xyz>
Diffstat (limited to 'externals/oboe/apps/fxlab/app/src/main/cpp')
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 ¶mArr = 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(); +} |
