Skip to content

Commit

Permalink
Merge branch 'main' into docs/readme-roadmap
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejmakowski2003 authored Jul 31, 2024
2 parents ec52098 + 74e3819 commit 823f5fe
Show file tree
Hide file tree
Showing 25 changed files with 265 additions and 31 deletions.
18 changes: 18 additions & 0 deletions android/src/main/cpp/AudioContext/AudioContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,22 @@ namespace audiocontext

return std::shared_ptr<StereoPannerNode>(stereoPannerCppInstance);
}

std::string AudioContext::getState()
{
static const auto method = javaClassLocal()->getMethod<JString()>("getState");
return method(javaObject_.get())->toStdString();
}

int AudioContext::getSampleRate()
{
static const auto method = javaClassLocal()->getMethod<jint()>("getSampleRate");
return method(javaObject_.get());
}

double AudioContext::getCurrentTime()
{
static const auto method = javaClassLocal()->getMethod<jdouble()>("getCurrentTime");
return method(javaObject_.get());
}
} // namespace audiocontext
4 changes: 3 additions & 1 deletion android/src/main/cpp/AudioContext/AudioContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ namespace audiocontext
std::shared_ptr<OscillatorNode> createOscillator();
std::shared_ptr<GainNode> createGain();
std::shared_ptr<StereoPannerNode> createStereoPanner();

std::string getState();
int getSampleRate();
double getCurrentTime();

void install(jlong jsContext);

Expand Down
10 changes: 10 additions & 0 deletions android/src/main/cpp/AudioNode/AudioNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ namespace audiocontext {

AudioNode::AudioNode(alias_ref<AudioNode::jhybridobject> &jThis): javaObject_(make_global(jThis)) {}

int AudioNode::getNumberOfInputs() {
static const auto method = javaClassLocal()->getMethod<int()>("getNumberOfInputs");
return method(javaObject_.get());
}

int AudioNode::getNumberOfOutputs() {
static const auto method = javaClassLocal()->getMethod<int()>("getNumberOfOutputs");
return method(javaObject_.get());
}

void AudioNode::connect(const std::shared_ptr<AudioNode> node) {
static const auto method = javaClassLocal()->getMethod<void(AudioNode::javaobject)>(
"connect");
Expand Down
2 changes: 2 additions & 0 deletions android/src/main/cpp/AudioNode/AudioNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ namespace audiocontext {
});
}

int getNumberOfInputs();
int getNumberOfOutputs();
void connect(const std::shared_ptr<AudioNode> node);
void disconnect(const std::shared_ptr<AudioNode> node);

Expand Down
15 changes: 15 additions & 0 deletions android/src/main/cpp/AudioParam/AudioParam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,19 @@ namespace audiocontext {
static const auto method = javaClassLocal()->getMethod<void(double)>("setValue");
method(javaObject_.get(), value);
}

double AudioParam::getDefaultValue() {
static const auto method = javaClassLocal()->getMethod<double()>("getDefaultValue");
return method(javaObject_.get());
}

double AudioParam::getMinValue() {
static const auto method = javaClassLocal()->getMethod<double()>("getMinValue");
return method(javaObject_.get());
}

double AudioParam::getMaxValue() {
static const auto method = javaClassLocal()->getMethod<double()>("getMaxValue");
return method(javaObject_.get());
}
}
3 changes: 3 additions & 0 deletions android/src/main/cpp/AudioParam/AudioParam.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ namespace audiocontext {

double getValue();
void setValue(double value);
double getDefaultValue();
double getMinValue();
double getMaxValue();

protected:
friend HybridBase;
Expand Down
5 changes: 0 additions & 5 deletions android/src/main/cpp/OscillatorNode/OscillatorNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@ namespace audiocontext {
static auto constexpr kJavaDescriptor = "Lcom/audiocontext/nodes/oscillator/OscillatorNode;";

void start(double time);

void stop(double time);

std::shared_ptr<AudioParam> getFrequencyParam();

std::shared_ptr<AudioParam> getDetuneParam();

std::string getWaveType();

void setWaveType(const std::string &waveType);
};
}// namespace audiocontext
13 changes: 13 additions & 0 deletions android/src/main/java/com/audiocontext/context/AudioContext.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.audiocontext.context

import android.os.SystemClock
import com.audiocontext.nodes.AudioDestinationNode
import com.audiocontext.nodes.GainNode
import com.audiocontext.nodes.StereoPannerNode
Expand All @@ -8,8 +9,11 @@ import com.facebook.jni.HybridData

class AudioContext() : BaseAudioContext {
override val sampleRate: Int = 44100
get() = field
override val destination: AudioDestinationNode = AudioDestinationNode(this)
get() = field
override var state = ContextState.RUNNING
private val contextStartTime: Long

private val mHybridData: HybridData?;

Expand All @@ -21,11 +25,20 @@ class AudioContext() : BaseAudioContext {

init {
mHybridData = initHybrid()
contextStartTime = SystemClock.elapsedRealtimeNanos()
}

external fun initHybrid(): HybridData?
external fun install(jsContext: Long)

fun getCurrentTime(): Double {
return (SystemClock.elapsedRealtimeNanos() - contextStartTime)/1_000_000_000.0
}

fun getState(): String {
return ContextState.toString(state)
}

override fun createOscillator(): OscillatorNode {
return OscillatorNode(this)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.audiocontext.nodes.oscillator.OscillatorNode
interface BaseAudioContext {
val sampleRate: Int
val destination: AudioDestinationNode
var state: ContextState

abstract fun createOscillator(): OscillatorNode
abstract fun createGain(): GainNode
Expand Down
23 changes: 23 additions & 0 deletions android/src/main/java/com/audiocontext/context/ContextState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.audiocontext.context

enum class ContextState {
RUNNING,
CLOSED;

companion object {
fun fromString(state: String): ContextState {
return when (state.lowercase()) {
"running" -> RUNNING
"closed" -> CLOSED
else -> throw IllegalArgumentException("Unknown context state: $state")
}
}

fun toString(state: ContextState): String {
return when (state) {
RUNNING -> "running"
CLOSED -> "closed"
}
}
}
}
6 changes: 4 additions & 2 deletions android/src/main/java/com/audiocontext/nodes/AudioNode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import com.facebook.jni.HybridData


abstract class AudioNode(val context: BaseAudioContext) {
abstract val numberOfInputs: Int;
abstract val numberOfOutputs: Int;
open val numberOfInputs: Int = 0
get() = field
open val numberOfOutputs: Int = 0
get() = field
private val connectedNodes = mutableListOf<AudioNode>()

private val mHybridData: HybridData?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ package com.audiocontext.nodes.parameters

import com.facebook.jni.HybridData

class AudioParam(val defaultValue: Double, private val maxValue: Double, private val minValue: Double) {
class AudioParam(defaultValue: Double, maxValue: Double, minValue: Double) {
private var value: Double = defaultValue
private val defaultValue: Double = defaultValue
get() = field
private val maxValue: Double = maxValue
get() = field
private val minValue: Double = minValue
get() = field

private val mHybridData: HybridData?;

Expand Down
23 changes: 19 additions & 4 deletions cpp/AudioContext/AudioContextHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ namespace audiocontext {
std::vector<jsi::PropNameID> AudioContextHostObject::getPropertyNames(jsi::Runtime& runtime) {
std::vector<jsi::PropNameID> propertyNames;
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "destination"));
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "state"));
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "sampleRate"));
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "currentTime"));
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "createOscillator"));
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "createGain"));
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "createStereoPanner"));
Expand All @@ -20,6 +23,22 @@ namespace audiocontext {
jsi::Value AudioContextHostObject::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId) {
auto propName = propNameId.utf8(runtime);

if(propName == "destination") {
return jsi::Object::createFromHostObject(runtime, destinationNode_);
}

if(propName == "state") {
return jsi::String::createFromUtf8(runtime, wrapper_->getState());
}

if(propName == "sampleRate") {
return jsi::Value(wrapper_->getSampleRate());
}

if(propName == "currentTime") {
return jsi::Value(wrapper_->getCurrentTime());
}

if(propName == "createOscillator") {
return jsi::Function::createFromHostFunction(runtime, propNameId, 0, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
auto oscillator = wrapper_->createOscillator();
Expand All @@ -28,10 +47,6 @@ namespace audiocontext {
});
}

if(propName == "destination") {
return jsi::Object::createFromHostObject(runtime, destinationNode_);
}

if(propName == "createGain") {
return jsi::Function::createFromHostFunction(runtime, propNameId, 0, [this](jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* arguments, size_t count) -> jsi::Value {
auto gain = wrapper_->createGain();
Expand Down
5 changes: 5 additions & 0 deletions cpp/AudioContext/AudioContextWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,15 @@ namespace audiocontext {
#endif
private:
std::shared_ptr<AudioDestinationNodeWrapper> destinationNode_;
std::string state_;
int sampleRate_;
public:
std::shared_ptr<OscillatorNodeWrapper> createOscillator();
std::shared_ptr<AudioDestinationNodeWrapper> getDestination();
std::shared_ptr<GainNodeWrapper> createGain();
std::shared_ptr<StereoPannerNodeWrapper> createStereoPanner();
std::string getState();
int getSampleRate();
double getCurrentTime();
};
} // namespace audiocontext
23 changes: 18 additions & 5 deletions cpp/AudioContext/android/AudioContextWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
namespace audiocontext {

AudioContextWrapper::AudioContextWrapper(const std::shared_ptr<AudioContext> &audiocontext) : audiocontext_(audiocontext) {
auto destinationNode = audiocontext_->getDestination();
destinationNode_ = std::make_shared<AudioDestinationNodeWrapper>(destinationNode);
auto destination = audiocontext_->getDestination();
destinationNode_ = std::make_shared<AudioDestinationNodeWrapper>(destination);
state_ = audiocontext_->getState();
sampleRate_ = audiocontext_->getSampleRate();
}

std::shared_ptr<OscillatorNodeWrapper> AudioContextWrapper::createOscillator() {
Expand All @@ -14,8 +16,7 @@ namespace audiocontext {
}

std::shared_ptr<AudioDestinationNodeWrapper> AudioContextWrapper::getDestination() {
auto destination = audiocontext_->getDestination();
return std::make_shared<AudioDestinationNodeWrapper>(destination);
return destinationNode_;
}

std::shared_ptr<GainNodeWrapper> AudioContextWrapper::createGain() {
Expand All @@ -27,5 +28,17 @@ namespace audiocontext {
auto panner = audiocontext_->createStereoPanner();
return std::make_shared<StereoPannerNodeWrapper>(panner);
}

std::string AudioContextWrapper::getState() {
return state_;
}

int AudioContextWrapper::getSampleRate() {
return sampleRate_;
}

double AudioContextWrapper::getCurrentTime() {
return audiocontext_->getCurrentTime();
}
} // namespace audiocontext
#endif
#endif
21 changes: 21 additions & 0 deletions cpp/AudioNode/AudioNodeHostObject.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "AudioNodeHostObject.h"
#include "AudioContextHostObject.h"

namespace audiocontext {
using namespace facebook;
Expand All @@ -7,6 +8,9 @@ namespace audiocontext {
std::vector<jsi::PropNameID> propertyNames;
propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "connect"));
propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "disconnect"));
propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "numberOfInputs"));
propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "numberOfOutputs"));
propertyNames.push_back(jsi::PropNameID::forAscii(runtime, "context"));
return propertyNames;
}

Expand All @@ -33,6 +37,23 @@ namespace audiocontext {
});
}

if (propName == "numberOfInputs")
{
return jsi::Value(wrapper_->getNumberOfInputs());
}

if (propName == "numberOfOutputs")
{
return jsi::Value(wrapper_->getNumberOfOutputs());
}

if (propName == "context")
{
auto context = runtime.global().getPropertyAsObject(runtime, "__AudioContext");
auto hostObject = context.getHostObject<AudioContextHostObject>(runtime);
return jsi::Object::createFromHostObject(runtime, hostObject);
}

throw std::runtime_error("Not yet implemented!");
}

Expand Down
7 changes: 6 additions & 1 deletion cpp/AudioNode/AudioNodeWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ namespace audiocontext {
protected:
std::shared_ptr<AudioNode> node_;
public:
explicit AudioNodeWrapper(const std::shared_ptr<AudioNode> &node) : node_(node) {}
explicit AudioNodeWrapper(const std::shared_ptr<AudioNode> &node);
#else
public:
explicit AudioNodeWrapper() {}
#endif
private:
int numberOfInputs_;
int numberOfOutputs_;
public:
int getNumberOfInputs() const;
int getNumberOfOutputs() const;
void connect(const std::shared_ptr<AudioNodeWrapper> &node) const;
void disconnect(const std::shared_ptr<AudioNodeWrapper> &node) const;
};
Expand Down
13 changes: 13 additions & 0 deletions cpp/AudioNode/android/AudioNodeWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@

namespace audiocontext {

AudioNodeWrapper::AudioNodeWrapper(const std::shared_ptr<AudioNode> &node) : node_(node) {
numberOfInputs_ = node->getNumberOfInputs();
numberOfOutputs_ = node->getNumberOfOutputs();
}

int AudioNodeWrapper::getNumberOfInputs() const {
return numberOfInputs_;
}

int AudioNodeWrapper::getNumberOfOutputs() const {
return numberOfOutputs_;
}

void AudioNodeWrapper::connect(const std::shared_ptr<AudioNodeWrapper> &node) const {
node_->connect(node->node_);
}
Expand Down
Loading

0 comments on commit 823f5fe

Please sign in to comment.