Skip to content

Commit 83af4dd

Browse files
committed
fix: base audio context construction + audio player start stop events
1 parent 2bec6fc commit 83af4dd

File tree

7 files changed

+42
-15
lines changed

7 files changed

+42
-15
lines changed

apps/common-app/src/examples/DrumMachine/usePlayer.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ export default function usePlayer(options: PlayerOptions) {
133133
playingInstruments.value = getPlayingInstruments();
134134
}
135135

136+
return () => {
137+
audioContext.close();
138+
};
139+
136140
// \/ Shared values are not necessary in deps array
137141
// eslint-disable-next-line react-hooks/exhaustive-deps
138142
}, [isPlaying, setup]);

packages/react-native-audio-api/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
2121
->openStream(mStream_);
2222

2323
mBus_ = std::make_shared<AudioBus>(getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
24+
isInitialized_ = true;
2425
}
2526

2627
int AudioPlayer::getSampleRate() const {
@@ -38,6 +39,8 @@ void AudioPlayer::start() {
3839
}
3940

4041
void AudioPlayer::stop() {
42+
isInitialized_ = false;
43+
4144
if (mStream_) {
4245
mStream_->requestStop();
4346
mStream_->close();
@@ -49,8 +52,11 @@ DataCallbackResult AudioPlayer::onAudioReady(
4952
AudioStream *oboeStream,
5053
void *audioData,
5154
int32_t numFrames) {
52-
auto buffer = static_cast<float *>(audioData);
55+
if (!isInitialized_) {
56+
return DataCallbackResult::Continue;
57+
}
5358

59+
auto buffer = static_cast<float *>(audioData);
5460
renderAudio_(mBus_.get(), numFrames);
5561

5662
// TODO: optimize this with SIMD?

packages/react-native-audio-api/android/src/main/cpp/AudioPlayer/AudioPlayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class AudioPlayer : public AudioStreamDataCallback {
2828
std::function<void(AudioBus*, int)> renderAudio_;
2929
std::shared_ptr<AudioStream> mStream_;
3030
std::shared_ptr<AudioBus> mBus_;
31+
bool isInitialized_ = false;
3132
};
3233

3334
} // namespace audioapi

packages/react-native-audio-api/common/cpp/core/AudioContext.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@
99

1010
namespace audioapi {
1111

12-
AudioContext::AudioContext() : BaseAudioContext() {}
12+
AudioContext::AudioContext() : BaseAudioContext() {
13+
audioPlayer_->start();
14+
}
1315

1416
void AudioContext::close() {
1517
state_ = ContextState::CLOSED;
16-
17-
if (audioPlayer_) {
18-
audioPlayer_->stop();
19-
}
20-
21-
audioPlayer_.reset();
22-
destination_.reset();
18+
audioPlayer_->stop();
2319
}
20+
2421
} // namespace audioapi

packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ double AudioDestinationNode::getCurrentTime() const {
2424
}
2525

2626
void AudioDestinationNode::renderAudio(AudioBus *destinationBus, int32_t numFrames) {
27-
context_->getNodeManager()->preProcessGraph();
28-
destinationBus->zero();
29-
30-
if (!numFrames) {
27+
if (!numFrames || !destinationBus || !isInitialized_) {
3128
return;
3229
}
3330

31+
context_->getNodeManager()->preProcessGraph();
32+
destinationBus->zero();
33+
3434
AudioBus* processedBus = processAudio(destinationBus, numFrames);
3535

3636
if (processedBus && processedBus != destinationBus) {

packages/react-native-audio-api/common/cpp/core/BaseAudioContext.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,19 @@ BaseAudioContext::BaseAudioContext() {
3030
sampleRate_ = audioPlayer_->getSampleRate();
3131
bufferSizeInFrames_ = audioPlayer_->getBufferSizeInFrames();
3232

33-
audioPlayer_->start();
3433
nodeManager_ = std::make_shared<AudioNodeManager>();
3534
destination_ = std::make_shared<AudioDestinationNode>(this);
3635
}
3736

37+
BaseAudioContext::~BaseAudioContext() {
38+
if (isRunning()) {
39+
return;
40+
}
41+
42+
state_ = ContextState::CLOSED;
43+
audioPlayer_->stop();
44+
}
45+
3846
std::string BaseAudioContext::getState() {
3947
return BaseAudioContext::toString(state_);
4048
}
@@ -96,7 +104,7 @@ std::shared_ptr<PeriodicWave> BaseAudioContext::createPeriodicWave(
96104
}
97105

98106
std::function<void(AudioBus *, int)> BaseAudioContext::renderAudio() {
99-
if (state_ == ContextState::CLOSED) {
107+
if (isClosed()) {
100108
return [](AudioBus *, int) {};
101109
}
102110

@@ -109,6 +117,14 @@ AudioNodeManager* BaseAudioContext::getNodeManager() {
109117
return nodeManager_.get();
110118
}
111119

120+
bool BaseAudioContext::isRunning() const {
121+
return state_ == ContextState::RUNNING;
122+
}
123+
124+
bool BaseAudioContext::isClosed() const {
125+
return state_ == ContextState::CLOSED;
126+
}
127+
112128
std::string BaseAudioContext::toString(ContextState state) {
113129
switch (state) {
114130
case ContextState::SUSPENDED:

packages/react-native-audio-api/common/cpp/core/BaseAudioContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class IOSAudioPlayer;
3131
class BaseAudioContext {
3232
public:
3333
BaseAudioContext();
34+
~BaseAudioContext();
3435
std::string getState();
3536
[[nodiscard]] int getSampleRate() const;
3637
[[nodiscard]] double getCurrentTime() const;
@@ -54,6 +55,8 @@ class BaseAudioContext {
5455
std::function<void(AudioBus *, int)> renderAudio();
5556

5657
AudioNodeManager* getNodeManager();
58+
bool isRunning() const;
59+
bool isClosed() const;
5760

5861
protected:
5962
static std::string toString(ContextState state);

0 commit comments

Comments
 (0)