From 4b3e83e2bbbc0e22e8d56fc8304f9594e2958e5a Mon Sep 17 00:00:00 2001 From: Maciej Makowski Date: Wed, 17 Jul 2024 11:55:07 +0200 Subject: [PATCH] feat: implement getters and setters for oscillator wave type --- android/src/main/cpp/OscillatorNode.cpp | 38 ++++++++++++------- android/src/main/cpp/OscillatorNode.h | 10 +++-- .../nodes/oscillator/OscillatorNode.kt | 8 ++++ .../audiocontext/nodes/oscillator/WaveType.kt | 19 +++++++--- cpp/OscillatorNodeHostObject.cpp | 19 ++++++++++ cpp/OscillatorNodeHostObject.h | 1 + example/src/App.tsx | 1 + src/types.ts | 2 +- 8 files changed, 75 insertions(+), 23 deletions(-) diff --git a/android/src/main/cpp/OscillatorNode.cpp b/android/src/main/cpp/OscillatorNode.cpp index 5d7ca83a..6ce07ae2 100644 --- a/android/src/main/cpp/OscillatorNode.cpp +++ b/android/src/main/cpp/OscillatorNode.cpp @@ -1,4 +1,5 @@ #include "OscillatorNode.h" +#include "android/log.h" namespace audiocontext { @@ -14,33 +15,44 @@ namespace audiocontext { } void OscillatorNode::start() { - static const auto method = javaClassStatic()->getMethod("start"); + static const auto method = javaClassLocal()->getMethod("start"); method(javaObject_.get()); } void OscillatorNode::stop() { - static const auto method = javaClassStatic()->getMethod("stop"); + static const auto method = javaClassLocal()->getMethod("stop"); method(javaObject_.get()); } - void OscillatorNode::setFrequency(jdouble frequency) { - static const auto method = javaClassStatic()->getMethod("setFrequency"); + double OscillatorNode::getFrequency() { + static const auto method = javaClassLocal()->getMethod("getFrequency"); + return method(javaObject_.get()); + } + + double OscillatorNode::getDetune() { + static const auto method = javaClassLocal()->getMethod("getDetune"); + return method(javaObject_.get()); + } + + std::string OscillatorNode::getWaveType() { + static const auto method = javaClassLocal()->getMethod("getWaveType"); + return method(javaObject_.get())->toStdString(); + } + + void OscillatorNode::setFrequency(double frequency) { + static const auto method = javaClassLocal()->getMethod("setFrequency"); method(javaObject_.get(), frequency); } - void OscillatorNode::setDetune(jdouble detune) { - static const auto method = javaClassStatic()->getMethod("setDetune"); + void OscillatorNode::setDetune(double detune) { + static const auto method = javaClassLocal()->getMethod("setDetune"); method(javaObject_.get(), detune); } - jdouble OscillatorNode::getFrequency() { - static const auto method = javaClassLocal()->getMethod("getFrequency"); - return method(javaObject_.get()); - } + void OscillatorNode::setWaveType(const std::string& waveType) { + static const auto method = javaClassLocal()->getMethod("setWaveType"); + method(javaObject_.get(), *make_jstring(waveType)); - jdouble OscillatorNode::getDetune() { - static const auto method = javaClassStatic()->getMethod("getDetune"); - return method(javaObject_.get()); } void OscillatorNode::connect(const AudioDestinationNode &destination) { diff --git a/android/src/main/cpp/OscillatorNode.h b/android/src/main/cpp/OscillatorNode.h index 8a86dbd3..cafe8404 100644 --- a/android/src/main/cpp/OscillatorNode.h +++ b/android/src/main/cpp/OscillatorNode.h @@ -31,10 +31,12 @@ namespace audiocontext { void start(); void stop(); - void setFrequency(jdouble frequency); - void setDetune(jdouble detune); - jdouble getFrequency(); - jdouble getDetune(); + double getFrequency(); + double getDetune(); + std::string getWaveType(); + void setFrequency(double frequency); + void setDetune(double detune); + void setWaveType(const std::string& waveType); void connect(const AudioDestinationNode &destination); jsi::Object createOscillatorNodeHostObject(); diff --git a/android/src/main/java/com/audiocontext/nodes/oscillator/OscillatorNode.kt b/android/src/main/java/com/audiocontext/nodes/oscillator/OscillatorNode.kt index 2600872d..abad5e59 100644 --- a/android/src/main/java/com/audiocontext/nodes/oscillator/OscillatorNode.kt +++ b/android/src/main/java/com/audiocontext/nodes/oscillator/OscillatorNode.kt @@ -53,6 +53,14 @@ class OscillatorNode(context: BaseAudioContext, reactContext: ReactApplicationCo external fun initHybrid(l: Long): HybridData? + fun getWaveType(): String { + return WaveType.toString(waveType) + } + + fun setWaveType(type: String) { + waveType = WaveType.fromString(type) + } + override fun start() { if(isPlaying) { return diff --git a/android/src/main/java/com/audiocontext/nodes/oscillator/WaveType.kt b/android/src/main/java/com/audiocontext/nodes/oscillator/WaveType.kt index aa666460..88e34dc4 100644 --- a/android/src/main/java/com/audiocontext/nodes/oscillator/WaveType.kt +++ b/android/src/main/java/com/audiocontext/nodes/oscillator/WaveType.kt @@ -37,15 +37,24 @@ enum class WaveType { companion object { fun fromString(type: String): WaveType { - return when (type.uppercase()) { - "SINE" -> SINE - "SQUARE" -> SQUARE - "SAWTOOTH" -> SAWTOOTH - "TRIANGLE" -> TRIANGLE + return when (type.lowercase()) { + "sine" -> SINE + "square" -> SQUARE + "sawtooth" -> SAWTOOTH + "triangle" -> TRIANGLE else -> throw IllegalArgumentException("Unknown wave type: $type") } } + fun toString(type: WaveType): String { + return when (type) { + SINE -> "sine" + SQUARE -> "square" + SAWTOOTH -> "sawtooth" + TRIANGLE -> "triangle" + } + } + fun getWaveBufferElement(wavePhase: Double, waveType: WaveType): Short { return waveType.getWaveValue(wavePhase) } diff --git a/cpp/OscillatorNodeHostObject.cpp b/cpp/OscillatorNodeHostObject.cpp index 0669ff93..514ad5f5 100644 --- a/cpp/OscillatorNodeHostObject.cpp +++ b/cpp/OscillatorNodeHostObject.cpp @@ -10,6 +10,7 @@ namespace audiocontext { propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "stop")); propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "frequency")); propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "detune")); + propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "type")); return propertyNames; } @@ -32,6 +33,10 @@ namespace audiocontext { return detune(runtime, propNameId); } + if (propName == "type") { + return waveType(runtime, propNameId); + } + if (propName == "connect") { return connect(runtime, propNameId); } @@ -54,6 +59,12 @@ namespace audiocontext { return; } + if (propName == "type") { + auto waveType = value.asString(runtime).utf8(runtime); + oscillator_->setWaveType(waveType); + return; + } + throw std::runtime_error("Not yet implemented!"); } @@ -88,6 +99,14 @@ namespace audiocontext { }); } + jsi::Value + OscillatorNodeHostObject::waveType(jsi::Runtime &runtime, const jsi::PropNameID &propNameId) { + return jsi::Function::createFromHostFunction(runtime, propNameId, 0, [this](jsi::Runtime& rt, const jsi::Value& thisValue, const jsi::Value* args, size_t count) -> jsi::Value { + auto waveType = oscillator_->getWaveType(); + return jsi::String::createFromUtf8(rt, waveType); + }); + } + jsi::Value OscillatorNodeHostObject::connect(jsi::Runtime &runtime, const jsi::PropNameID &propNameId) { return jsi::Function::createFromHostFunction(runtime, propNameId, 1, [this](jsi::Runtime& rt, const jsi::Value& thisValue, const jsi::Value* args, size_t count) -> jsi::Value { diff --git a/cpp/OscillatorNodeHostObject.h b/cpp/OscillatorNodeHostObject.h index c91d1044..f2b85a88 100644 --- a/cpp/OscillatorNodeHostObject.h +++ b/cpp/OscillatorNodeHostObject.h @@ -25,6 +25,7 @@ namespace audiocontext { jsi::Value stop(jsi::Runtime& runtime, const jsi::PropNameID& propNameId); jsi::Value frequency(jsi::Runtime& runtime, const jsi::PropNameID& propNameId); jsi::Value detune(jsi::Runtime& runtime, const jsi::PropNameID& propNameId); + jsi::Value waveType(jsi::Runtime& runtime, const jsi::PropNameID& propNameId); jsi::Value connect(jsi::Runtime& runtime, const jsi::PropNameID& propNameId); }; } // namespace audiocontext diff --git a/example/src/App.tsx b/example/src/App.tsx index 1802fc94..b6376618 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -14,6 +14,7 @@ const App = () => { oscillatorRef.current = audioContextRef.current.createOscillator(); secondaryOscillatorRef.current = audioContextRef.current.createOscillator(); secondaryOscillatorRef.current.frequency = 300; + secondaryOscillatorRef.current.type = 'square'; const destination = audioContextRef.current.destination(); oscillatorRef.current.connect(destination); diff --git a/src/types.ts b/src/types.ts index f1cbf218..2b804db4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,6 +20,6 @@ type WaveType = 'sine' | 'square' | 'sawtooth' | 'triangle'; export interface Oscillator extends AudioScheduledSourceNode { frequency: number; - wave: WaveType; + type: WaveType; detune: number; }