Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions apps/common-app/src/examples/AudioTag/AudioTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { useRef } from 'react';
import { View } from 'react-native';
import { Audio } from 'react-native-audio-api/development/react';

import { Container } from '../../components';
import { AudioContext } from 'react-native-audio-api';

const DEMO_AUDIO_URL =
'https://software-mansion.github.io/react-native-audio-api/audio/music/example-music-02.mp3';
// '/data/data/com.fabricexample/cache/audio.wav';

const AudioTag: React.FC = () => {
const audioContext = useRef(new AudioContext());
return (
<Container disablePadding>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<View style={{ width: '90%' }}>
<Audio source={DEMO_AUDIO_URL} volume={1} controls context={audioContext.current} />
</View>
</View>
</Container>
);
};

export default AudioTag;
1 change: 1 addition & 0 deletions apps/common-app/src/examples/AudioTag/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AudioTag';
8 changes: 8 additions & 0 deletions apps/common-app/src/examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import PlaybackSpeed from './PlaybackSpeed/PlaybackSpeed';
import Record from './Record/Record';
import Streaming from './Streaming/Streaming';
import Worklets from './Worklets/Worklets';
import AudioStream from './AudioTag/AudioTag';

type NavigationParamList = {
Oscillator: undefined;
Expand All @@ -26,6 +27,7 @@ type NavigationParamList = {
Record: undefined;
Worklets: undefined;
Streamer: undefined;
AudioTag: undefined;
};

export type ExampleKey = keyof NavigationParamList;
Expand Down Expand Up @@ -110,4 +112,10 @@ export const Examples: Example[] = [
Icon: icons.Radio,
screen: Streaming,
},
{
key: 'AudioTag',
title: 'Audio Tag',
Icon: icons.Tag,
screen: AudioStream,
}
] as const;
6 changes: 3 additions & 3 deletions apps/fabric-example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2514,7 +2514,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
FBLazyVector: e97c19a5a442429d1988f182a1940fb08df514da
hermes-engine: ca0c1d4fe0200e05fedd8d7c0c283b54cd461436
hermes-engine: 471e81260adadffc041e40c5eea01333addabb53
RCTDeprecation: af44b104091a34482596cd9bd7e8d90c4e9b4bd7
RCTRequired: bb77b070f75f53398ce43c0aaaa58337cebe2bf6
RCTSwiftUI: afc0a0a635860da1040a0b894bfd529da06d7810
Expand All @@ -2523,7 +2523,7 @@ SPEC CHECKSUMS:
React: 1ba7d364ade7d883a1ec055bfc3606f35fdee17b
React-callinvoker: bc2a26f8d84fb01f003fc6de6c9337b64715f95b
React-Core: 7840d3a80b43a95c5e80ef75146bd70925ebab0f
React-Core-prebuilt: e44365cf4785c3aa56ababc9ab204fe8bc6b17d0
React-Core-prebuilt: 6586031f606ff8ab466cac9e8284053a91342881
React-CoreModules: 2eb010400b63b89e53a324ffb3c112e4c7c3ce42
React-cxxreact: a558e92199d26f145afa9e62c4233cf8e7950efe
React-debug: 755200a6e7f5e6e0a40ff8d215493d43cce285fc
Expand Down Expand Up @@ -2587,7 +2587,7 @@ SPEC CHECKSUMS:
ReactAppDependencyProvider: e96e93b493d8d86eeaee3e590ba0be53f6abe46f
ReactCodegen: f66521b131699d6af0790f10653933b3f1f79a6f
ReactCommon: 07572bf9e687c8a52fbe4a3641e9e3a1a477c78e
ReactNativeDependencies: 3467a1fea6f7a524df13b30430bebcc254d9aee2
ReactNativeDependencies: a5d71d95f2654107eb45e6ece04caba36beac2bd
RNAudioAPI: fa5c075d2fcdb1ad9a695754b38f07c8c3074396
RNGestureHandler: 07de6f059e0ee5744ae9a56feb07ee345338cc31
RNReanimated: d75c81956bf7531fe08ba4390149002ab8bdd127
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
#include <audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.h>
#include <audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.h>
#include <audioapi/HostObjects/sources/AudioFileSourceNodeHostObject.h>
#include <audioapi/HostObjects/sources/ConstantSourceNodeHostObject.h>
#include <audioapi/HostObjects/sources/OscillatorNodeHostObject.h>
#include <audioapi/HostObjects/sources/RecorderAdapterNodeHostObject.h>
Expand Down Expand Up @@ -58,6 +59,7 @@ BaseAudioContextHostObject::BaseAudioContextHostObject(
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBiquadFilter),
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createIIRFilter),
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBufferSource),
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createFileSource),
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createBufferQueueSource),
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createPeriodicWave),
JSI_EXPORT_FUNCTION(BaseAudioContextHostObject, createConvolver),
Expand Down Expand Up @@ -250,6 +252,26 @@ JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createBufferSource) {
return jsi::Object::createFromHostObject(runtime, bufferSourceHostObject);
}

JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createFileSource) {
AudioFileSourceOptions options;
if (count > 0 && !args[0].isUndefined() && !args[0].isNull()) {
if (args[0].isString()) {
options.filePath = args[0].getString(runtime).utf8(runtime);
} else {
auto obj = args[0].asObject(runtime);
if (obj.isArrayBuffer(runtime)) {
auto arrayBuffer = obj.getArrayBuffer(runtime);
auto *data = arrayBuffer.data(runtime);
auto size = arrayBuffer.size(runtime);
options.data = std::vector<uint8_t>(data, data + size);
}
}
}
const auto fileSourceHostObject =
std::make_shared<AudioFileSourceNodeHostObject>(context_, options);
return jsi::Object::createFromHostObject(runtime, fileSourceHostObject);
}

JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createBufferQueueSource) {
const auto options = args[0].asObject(runtime);
const auto baseAudioBufferSourceOptions =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class BaseAudioContextHostObject : public JsiHostObject {
JSI_HOST_FUNCTION_DECL(createBiquadFilter);
JSI_HOST_FUNCTION_DECL(createIIRFilter);
JSI_HOST_FUNCTION_DECL(createBufferSource);
JSI_HOST_FUNCTION_DECL(createFileSource);
JSI_HOST_FUNCTION_DECL(createBufferQueueSource);
JSI_HOST_FUNCTION_DECL(createPeriodicWave);
JSI_HOST_FUNCTION_DECL(createAnalyser);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include <audioapi/HostObjects/sources/AudioFileSourceNodeHostObject.h>

#include <audioapi/core/BaseAudioContext.h>
#include <audioapi/core/sources/AudioFileSourceNode.h>
#include <audioapi/types/NodeOptions.h>
#include <memory>
#include <utility>

namespace audioapi {

AudioFileSourceNodeHostObject::AudioFileSourceNodeHostObject(
const std::shared_ptr<BaseAudioContext> &context,
const AudioFileSourceOptions &options)
: AudioNodeHostObject(context->createFileSource(options), options) {
addGetters(
JSI_EXPORT_PROPERTY_GETTER(AudioFileSourceNodeHostObject, volume),
JSI_EXPORT_PROPERTY_GETTER(AudioFileSourceNodeHostObject, loop),
JSI_EXPORT_PROPERTY_GETTER(AudioFileSourceNodeHostObject, currentTime),
JSI_EXPORT_PROPERTY_GETTER(AudioFileSourceNodeHostObject, duration));
addSetters(
JSI_EXPORT_PROPERTY_SETTER(AudioFileSourceNodeHostObject, onPositionChanged),
JSI_EXPORT_PROPERTY_SETTER(AudioFileSourceNodeHostObject, onEnded),
JSI_EXPORT_PROPERTY_SETTER(AudioFileSourceNodeHostObject, volume),
JSI_EXPORT_PROPERTY_SETTER(AudioFileSourceNodeHostObject, loop));

addFunctions(
JSI_EXPORT_FUNCTION(AudioFileSourceNodeHostObject, pause),
JSI_EXPORT_FUNCTION(AudioFileSourceNodeHostObject, start),
JSI_EXPORT_FUNCTION(AudioFileSourceNodeHostObject, seekToTime));
}

AudioFileSourceNodeHostObject::~AudioFileSourceNodeHostObject() {
setOnPositionChangedCallbackId(0);
setOnEndedCallbackId(0);
}

JSI_PROPERTY_GETTER_IMPL(AudioFileSourceNodeHostObject, volume) {
auto node = std::static_pointer_cast<AudioFileSourceNode>(node_);
return {node->getVolume()};
}

JSI_PROPERTY_SETTER_IMPL(AudioFileSourceNodeHostObject, volume) {
auto node = std::static_pointer_cast<AudioFileSourceNode>(node_);
node->setVolume(static_cast<float>(value.getNumber()));
}

JSI_PROPERTY_GETTER_IMPL(AudioFileSourceNodeHostObject, loop) {
auto node = std::static_pointer_cast<AudioFileSourceNode>(node_);
return {node->getLoop()};
}

JSI_PROPERTY_SETTER_IMPL(AudioFileSourceNodeHostObject, loop) {
auto node = std::static_pointer_cast<AudioFileSourceNode>(node_);
node->setLoop(value.getBool());
}

JSI_PROPERTY_GETTER_IMPL(AudioFileSourceNodeHostObject, currentTime) {
auto node = std::static_pointer_cast<AudioFileSourceNode>(node_);
return {node->getCurrentTime()};
}

JSI_PROPERTY_GETTER_IMPL(AudioFileSourceNodeHostObject, duration) {
auto node = std::static_pointer_cast<AudioFileSourceNode>(node_);
return {node->getDuration()};
}

JSI_HOST_FUNCTION_IMPL(AudioFileSourceNodeHostObject, start) {
auto audioFileSourceNode = std::static_pointer_cast<AudioFileSourceNode>(node_);
auto event = [audioFileSourceNode](BaseAudioContext &) {
audioFileSourceNode->start();
};
audioFileSourceNode->scheduleAudioEvent(std::move(event));

return jsi::Value::undefined();
}

JSI_HOST_FUNCTION_IMPL(AudioFileSourceNodeHostObject, pause) {
auto audioFileSourceNode = std::static_pointer_cast<AudioFileSourceNode>(node_);
audioFileSourceNode->pause();
return jsi::Value::undefined();
}

JSI_HOST_FUNCTION_IMPL(AudioFileSourceNodeHostObject, seekToTime) {
auto audioFileSourceNode = std::static_pointer_cast<AudioFileSourceNode>(node_);
if (count < 1 || !args[0].isNumber()) {
return jsi::Value::undefined();
}
const double t = args[0].getNumber();

auto event = [audioFileSourceNode, t](BaseAudioContext &) {
audioFileSourceNode->seekToTime(t);
};
audioFileSourceNode->scheduleAudioEvent(std::move(event));

return jsi::Value::undefined();
}

JSI_PROPERTY_SETTER_IMPL(AudioFileSourceNodeHostObject, onPositionChanged) {
auto callbackId = std::stoull(value.getString(runtime).utf8(runtime));
setOnPositionChangedCallbackId(callbackId);
}

void AudioFileSourceNodeHostObject::setOnPositionChangedCallbackId(uint64_t callbackId) {
auto sourceNode = std::static_pointer_cast<AudioFileSourceNode>(node_);

auto event = [sourceNode, callbackId](BaseAudioContext &) {
sourceNode->setOnPositionChangedCallbackId(callbackId);
};

sourceNode->unregisterOnPositionChangedCallback(onPositionChangedCallbackId_);
sourceNode->scheduleAudioEvent(std::move(event));
onPositionChangedCallbackId_ = callbackId;
}

JSI_PROPERTY_SETTER_IMPL(AudioFileSourceNodeHostObject, onEnded) {
auto callbackId = std::stoull(value.getString(runtime).utf8(runtime));
setOnEndedCallbackId(callbackId);
}

void AudioFileSourceNodeHostObject::setOnEndedCallbackId(uint64_t callbackId) {
auto sourceNode = std::static_pointer_cast<AudioFileSourceNode>(node_);

auto event = [sourceNode, callbackId](BaseAudioContext &) {
sourceNode->setOnEndedCallbackId(callbackId);
};

sourceNode->unregisterOnEndedCallback(onEndedCallbackId_);
sourceNode->scheduleAudioEvent(std::move(event));
onEndedCallbackId_ = callbackId;
}

} // namespace audioapi
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include <audioapi/HostObjects/AudioNodeHostObject.h>

#include <memory>

namespace audioapi {
using namespace facebook;

struct AudioFileSourceOptions;
class BaseAudioContext;

class AudioFileSourceNodeHostObject : public AudioNodeHostObject {
public:
explicit AudioFileSourceNodeHostObject(
const std::shared_ptr<BaseAudioContext> &context,
const AudioFileSourceOptions &options);

~AudioFileSourceNodeHostObject() override;

JSI_PROPERTY_GETTER_DECL(volume);
JSI_PROPERTY_SETTER_DECL(volume);
JSI_PROPERTY_GETTER_DECL(loop);
JSI_PROPERTY_SETTER_DECL(loop);
JSI_PROPERTY_GETTER_DECL(currentTime);
JSI_PROPERTY_GETTER_DECL(duration);
JSI_PROPERTY_SETTER_DECL(onPositionChanged);
JSI_PROPERTY_SETTER_DECL(onEnded);

JSI_HOST_FUNCTION_DECL(pause);
JSI_HOST_FUNCTION_DECL(start);
JSI_HOST_FUNCTION_DECL(seekToStart);
JSI_HOST_FUNCTION_DECL(seekToTime);

private:
uint64_t onPositionChangedCallbackId_ = 0;
uint64_t onEndedCallbackId_ = 0;

void setOnPositionChangedCallbackId(uint64_t callbackId);
void setOnEndedCallbackId(uint64_t callbackId);
};

} // namespace audioapi
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <audioapi/core/effects/WorkletProcessingNode.h>
#include <audioapi/core/sources/AudioBufferQueueSourceNode.h>
#include <audioapi/core/sources/AudioBufferSourceNode.h>
#include <audioapi/core/sources/AudioFileSourceNode.h>
#include <audioapi/core/sources/ConstantSourceNode.h>
#include <audioapi/core/sources/OscillatorNode.h>
#include <audioapi/core/sources/RecorderAdapterNode.h>
Expand Down Expand Up @@ -177,6 +178,15 @@ std::shared_ptr<AudioBufferSourceNode> BaseAudioContext::createBufferSource(
return bufferSource;
}

#if !RN_AUDIO_API_TEST
std::shared_ptr<AudioFileSourceNode> BaseAudioContext::createFileSource(
const AudioFileSourceOptions &options) {
auto fileSource = std::make_shared<AudioFileSourceNode>(shared_from_this(), options);
// graphManager_->addProcessingNode(fileSource);
return fileSource;
}
#endif // RN_AUDIO_API_TEST

std::shared_ptr<IIRFilterNode> BaseAudioContext::createIIRFilter(const IIRFilterOptions &options) {
auto iirFilter = std::make_shared<IIRFilterNode>(shared_from_this(), options);
graphManager_->addProcessingNode(iirFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class IIRFilterNode;
class AudioDestinationNode;
class AudioBufferSourceNode;
class AudioBufferQueueSourceNode;
class AudioFileSourceNode;
class AnalyserNode;
class AudioEventHandlerRegistry;
class ConvolverNode;
Expand All @@ -47,6 +48,7 @@ struct BiquadFilterOptions;
struct OscillatorOptions;
struct BaseAudioBufferSourceOptions;
struct AudioBufferSourceOptions;
struct AudioFileSourceOptions;
struct StreamerOptions;
struct DelayOptions;
struct IIRFilterOptions;
Expand Down Expand Up @@ -93,6 +95,9 @@ class BaseAudioContext : public std::enable_shared_from_this<BaseAudioContext> {
std::shared_ptr<BiquadFilterNode> createBiquadFilter(const BiquadFilterOptions &options);
std::shared_ptr<AudioBufferSourceNode> createBufferSource(
const AudioBufferSourceOptions &options);
#if !RN_AUDIO_API_TEST
std::shared_ptr<AudioFileSourceNode> createFileSource(const AudioFileSourceOptions &options);
#endif // RN_AUDIO_API_TEST
std::shared_ptr<AudioBufferQueueSourceNode> createBufferQueueSource(
const BaseAudioBufferSourceOptions &options);
std::shared_ptr<PeriodicWave> createPeriodicWave(
Expand Down
Loading
Loading