Skip to content

Commit ae02cc2

Browse files
author
Maciej Makowski
committed
Merge branch 'main' into feat/android/playing-from-audio-source
2 parents 0cdc22a + 3bbc3ce commit ae02cc2

File tree

17 files changed

+184
-50
lines changed

17 files changed

+184
-50
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,4 @@ react-native-audio-api*.tgz
8383
# Android
8484
.kotlin
8585

86+
.env

apps/common-app/src/examples/AudioFile/AudioFile.tsx

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import React from 'react';
1+
import React, { useCallback } from 'react';
22
import { useState, useRef, useEffect, FC } from 'react';
33
import { Container, Button } from '../../components';
44

55
import {
6+
AudioBuffer,
67
AudioContext,
78
AudioBufferSourceNode,
8-
AudioBuffer,
99
} from 'react-native-audio-api';
10+
import { ActivityIndicator } from 'react-native';
11+
12+
const assetUrl =
13+
'https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview18/v4/9c/db/54/9cdb54b3-5c52-3063-b1ad-abe42955edb5/mzaf_520282131402737225.plus.aac.p.m4a';
1014

1115
const AudioFile: FC = () => {
1216
const [isPlaying, setIsPlaying] = useState(false);
@@ -22,28 +26,28 @@ const AudioFile: FC = () => {
2226

2327
audioBufferSourceNodeRef.current =
2428
audioContextRef.current.createBufferSource();
25-
audioBufferSourceNodeRef.current.buffer;
29+
2630
audioBufferSourceNodeRef.current.connect(
2731
audioContextRef.current.destination
2832
);
2933
};
3034

31-
const fetchAudioBuffer = async () => {
35+
const fetchAudioBuffer = useCallback(async () => {
3236
if (!audioContextRef.current) {
3337
audioContextRef.current = new AudioContext();
3438
}
3539

36-
setAudioBuffer(
37-
audioContextRef.current.decodeAudioDataSource(
38-
'/Users/maciejmakowski/projects/react-native-audio-api/apps/common-app/src/examples/AudioFile/runaway_kanye_west.mp3'
39-
)
40-
// audioContextRef.current.decodeAudioDataSource(
41-
// 'https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview18/v4/9c/db/54/9cdb54b3-5c52-3063-b1ad-abe42955edb5/mzaf_520282131402737225.plus.aac.p.m4a'
42-
// )
43-
);
44-
};
40+
const buffer =
41+
await audioContextRef.current.decodeAudioDataSource(assetUrl);
42+
43+
setAudioBuffer(buffer);
44+
}, []);
4545

4646
const handlePress = () => {
47+
if (!audioBuffer) {
48+
return;
49+
}
50+
4751
if (isPlaying) {
4852
audioBufferSourceNodeRef.current?.stop();
4953
} else {
@@ -65,11 +69,12 @@ const AudioFile: FC = () => {
6569
return () => {
6670
audioContextRef.current?.close();
6771
};
68-
}, []);
72+
}, [fetchAudioBuffer]);
6973

7074
return (
7175
<Container centered>
7276
<Button title={isPlaying ? 'Stop' : 'Play'} onPress={handlePress} />
77+
{!audioBuffer && <ActivityIndicator color="#FFFFFF" />}
7378
</Container>
7479
);
7580
};

apps/fabric-example/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,8 +2063,8 @@ SPEC CHECKSUMS:
20632063
RNReanimated: 77242c6d67416988a2fd9f5cf574bb3e60016362
20642064
RNScreens: e389d6a6a66a4f0d3662924ecae803073ccce8ec
20652065
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
2066-
Yoga: f8ec45ce98bba1bc93dd28f2ee37215180e6d2b6
2066+
Yoga: 1d66db49f38fd9e576a1d7c3b081e46ab4c28b9e
20672067

20682068
PODFILE CHECKSUM: 75ad38075e71875257a2590065853ea6a608b897
20692069

2070-
COCOAPODS: 1.15.2
2070+
COCOAPODS: 1.16.2

packages/react-native-audio-api/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ namespace audioapi {
44
using namespace facebook;
55

66
AudioAPIInstallerHostObject::AudioAPIInstallerHostObject(
7-
const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper)
8-
: wrapper_(wrapper) {}
7+
const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper, jsi::Runtime* runtime, const std::shared_ptr<facebook::react::CallInvoker> &jsInvoker)
8+
: wrapper_(wrapper) {
9+
promiseVendor_ = std::make_shared<JsiPromise::PromiseVendor>(runtime, jsInvoker);
10+
}
911

1012
std::vector<jsi::PropNameID> AudioAPIInstallerHostObject::getPropertyNames(
1113
jsi::Runtime &runtime) {
@@ -32,7 +34,7 @@ jsi::Value AudioAPIInstallerHostObject::get(
3234
size_t count) -> jsi::Value {
3335
auto audioContext = wrapper_->createAudioContext();
3436
auto audioContextHostObject =
35-
AudioContextHostObject::createFromWrapper(audioContext);
37+
AudioContextHostObject::createFromWrapper(audioContext, promiseVendor_);
3638
return jsi::Object::createFromHostObject(
3739
runtime, audioContextHostObject);
3840
});

packages/react-native-audio-api/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#pragma once
22

3+
#include <ReactCommon/CallInvoker.h>
34
#include <jsi/jsi.h>
45
#include <memory>
56
#include <utility>
67
#include <vector>
78

9+
810
#include "AudioAPIInstallerWrapper.h"
911
#include "AudioContextHostObject.h"
12+
#include "JsiPromise.h"
1013

1114
namespace audioapi {
1215
using namespace facebook;
@@ -16,7 +19,7 @@ class AudioAPIInstallerWrapper;
1619
class AudioAPIInstallerHostObject : public jsi::HostObject {
1720
public:
1821
explicit AudioAPIInstallerHostObject(
19-
const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper);
22+
const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper, jsi::Runtime* runtime, const std::shared_ptr<react::CallInvoker> &jsInvoker);
2023

2124
#ifdef ANDROID
2225
static void createAndInstallFromWrapper(
@@ -41,5 +44,6 @@ class AudioAPIInstallerHostObject : public jsi::HostObject {
4144

4245
private:
4346
std::shared_ptr<AudioAPIInstallerWrapper> wrapper_;
47+
std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor_;
4448
};
4549
} // namespace audioapi

packages/react-native-audio-api/common/cpp/HostObjects/AudioBufferHostObject.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ jsi::Value AudioBufferHostObject::get(
128128
});
129129
}
130130

131+
// `decodeAudioData` is a method that returns a promise to AudioBufferHostObject
132+
// It seems that async/await checks for the presence of `then` method on the object
133+
if (propName == "then") {
134+
return jsi::Value::undefined();
135+
}
136+
131137
throw std::runtime_error("Not yet implemented!");
132138
}
133139

packages/react-native-audio-api/common/cpp/HostObjects/AudioContextHostObject.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ namespace audioapi {
44
using namespace facebook;
55

66
AudioContextHostObject::AudioContextHostObject(
7-
const std::shared_ptr<AudioContextWrapper> &wrapper)
8-
: BaseAudioContextHostObject(wrapper) {}
7+
const std::shared_ptr<AudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor)
8+
: BaseAudioContextHostObject(wrapper, promiseVendor) {}
99

1010
std::vector<jsi::PropNameID> AudioContextHostObject::getPropertyNames(
1111
jsi::Runtime &runtime) {

packages/react-native-audio-api/common/cpp/HostObjects/AudioContextHostObject.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <memory>
55
#include <vector>
66

7+
#include"JsiPromise.h"
78
#include "AudioContextWrapper.h"
89
#include "BaseAudioContextHostObject.h"
910

@@ -13,7 +14,7 @@ using namespace facebook;
1314
class AudioContextHostObject : public BaseAudioContextHostObject {
1415
public:
1516
explicit AudioContextHostObject(
16-
const std::shared_ptr<AudioContextWrapper> &wrapper);
17+
const std::shared_ptr<AudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor);
1718

1819
jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override;
1920

@@ -25,8 +26,8 @@ class AudioContextHostObject : public BaseAudioContextHostObject {
2526
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
2627

2728
static std::shared_ptr<AudioContextHostObject> createFromWrapper(
28-
const std::shared_ptr<AudioContextWrapper> &wrapper) {
29-
return std::make_shared<AudioContextHostObject>(wrapper);
29+
const std::shared_ptr<AudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor) {
30+
return std::make_shared<AudioContextHostObject>(wrapper, promiseVendor);
3031
}
3132

3233
private:

packages/react-native-audio-api/common/cpp/HostObjects/BaseAudioContextHostObject.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
#include <thread>
2+
13
#include "BaseAudioContextHostObject.h"
24

35
namespace audioapi {
46
using namespace facebook;
57

68
BaseAudioContextHostObject::BaseAudioContextHostObject(
7-
const std::shared_ptr<BaseAudioContextWrapper> &wrapper)
8-
: wrapper_(wrapper) {
9+
const std::shared_ptr<BaseAudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor)
10+
: wrapper_(wrapper), promiseVendor_(promiseVendor) {
911
auto destinationNodeWrapper = wrapper_->getDestination();
1012
destination_ =
1113
AudioDestinationNodeHostObject::createFromWrapper(destinationNodeWrapper);
@@ -203,22 +205,25 @@ jsi::Value BaseAudioContextHostObject::get(
203205
}
204206

205207
if (propName == "decodeAudioDataSource") {
206-
return jsi::Function::createFromHostFunction(
207-
runtime,
208-
propNameId,
209-
1,
210-
[this](
211-
jsi::Runtime &runtime,
212-
const jsi::Value &thisValue,
213-
const jsi::Value *arguments,
214-
size_t count) -> jsi::Value {
215-
std::string source = arguments[0].getString(runtime).utf8(runtime);
216-
auto buffer = wrapper_->decodeAudioDataSource(source);
217-
auto audioBufferHostObject =
218-
AudioBufferHostObject::createFromWrapper(buffer);
219-
return jsi::Object::createFromHostObject(
220-
runtime, audioBufferHostObject);
221-
});
208+
auto decode = [this](jsi::Runtime& runtime,
209+
const jsi::Value&,
210+
const jsi::Value* arguments,
211+
size_t count) -> jsi::Value {
212+
auto sourcePath = arguments[0].getString(runtime).utf8(runtime);
213+
214+
auto promise = promiseVendor_->createPromise([this, &runtime, sourcePath](std::shared_ptr<JsiPromise::Promise> promise) {
215+
std::thread([this, &runtime, sourcePath, promise = std::move(promise)]() {
216+
auto results = wrapper_->decodeAudioDataSource(sourcePath);
217+
auto audioBufferHostObject = AudioBufferHostObject::createFromWrapper(results);
218+
219+
promise->resolve(jsi::Object::createFromHostObject(runtime, audioBufferHostObject));
220+
}).detach();
221+
});
222+
223+
return promise;
224+
};
225+
226+
return jsi::Function::createFromHostFunction(runtime, propNameId, 1, decode);
222227
}
223228

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

packages/react-native-audio-api/common/cpp/HostObjects/BaseAudioContextHostObject.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <utility>
66
#include <vector>
77

8+
#include "JsiPromise.h"
89
#include "AudioBufferHostObject.h"
910
#include "AudioBufferSourceNodeHostObject.h"
1011
#include "AudioDestinationNodeHostObject.h"
@@ -21,7 +22,7 @@ using namespace facebook;
2122
class BaseAudioContextHostObject : public jsi::HostObject {
2223
public:
2324
explicit BaseAudioContextHostObject(
24-
const std::shared_ptr<BaseAudioContextWrapper> &wrapper);
25+
const std::shared_ptr<BaseAudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor);
2526

2627
jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override;
2728

@@ -35,5 +36,6 @@ class BaseAudioContextHostObject : public jsi::HostObject {
3536
protected:
3637
std::shared_ptr<BaseAudioContextWrapper> wrapper_;
3738
std::shared_ptr<AudioDestinationNodeHostObject> destination_;
39+
std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor_;
3840
};
3941
} // namespace audioapi

0 commit comments

Comments
 (0)