Skip to content

Commit

Permalink
fix: base audio context construction + audio player start stop events (
Browse files Browse the repository at this point in the history
  • Loading branch information
michalsek authored Nov 29, 2024
1 parent 2bec6fc commit 261b8ac
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 15 deletions.
4 changes: 4 additions & 0 deletions apps/common-app/src/examples/DrumMachine/usePlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ export default function usePlayer(options: PlayerOptions) {
playingInstruments.value = getPlayingInstruments();
}

return () => {
audioContext.close();
};

// \/ Shared values are not necessary in deps array
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPlaying, setup]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
->openStream(mStream_);

mBus_ = std::make_shared<AudioBus>(getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
isInitialized_ = true;
}

int AudioPlayer::getSampleRate() const {
Expand All @@ -38,6 +39,8 @@ void AudioPlayer::start() {
}

void AudioPlayer::stop() {
isInitialized_ = false;

if (mStream_) {
mStream_->requestStop();
mStream_->close();
Expand All @@ -49,8 +52,11 @@ DataCallbackResult AudioPlayer::onAudioReady(
AudioStream *oboeStream,
void *audioData,
int32_t numFrames) {
auto buffer = static_cast<float *>(audioData);
if (!isInitialized_) {
return DataCallbackResult::Continue;
}

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

// TODO: optimize this with SIMD?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class AudioPlayer : public AudioStreamDataCallback {
std::function<void(AudioBus*, int)> renderAudio_;
std::shared_ptr<AudioStream> mStream_;
std::shared_ptr<AudioBus> mBus_;
bool isInitialized_ = false;
};

} // namespace audioapi
13 changes: 5 additions & 8 deletions packages/react-native-audio-api/common/cpp/core/AudioContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@

namespace audioapi {

AudioContext::AudioContext() : BaseAudioContext() {}
AudioContext::AudioContext() : BaseAudioContext() {
audioPlayer_->start();
}

void AudioContext::close() {
state_ = ContextState::CLOSED;

if (audioPlayer_) {
audioPlayer_->stop();
}

audioPlayer_.reset();
destination_.reset();
audioPlayer_->stop();
}

} // namespace audioapi
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ double AudioDestinationNode::getCurrentTime() const {
}

void AudioDestinationNode::renderAudio(AudioBus *destinationBus, int32_t numFrames) {
context_->getNodeManager()->preProcessGraph();
destinationBus->zero();

if (!numFrames) {
if (!numFrames || !destinationBus || !isInitialized_) {
return;
}

context_->getNodeManager()->preProcessGraph();
destinationBus->zero();

AudioBus* processedBus = processAudio(destinationBus, numFrames);

if (processedBus && processedBus != destinationBus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@ BaseAudioContext::BaseAudioContext() {
sampleRate_ = audioPlayer_->getSampleRate();
bufferSizeInFrames_ = audioPlayer_->getBufferSizeInFrames();

audioPlayer_->start();
nodeManager_ = std::make_shared<AudioNodeManager>();
destination_ = std::make_shared<AudioDestinationNode>(this);
}

BaseAudioContext::~BaseAudioContext() {
if (isRunning()) {
return;
}

state_ = ContextState::CLOSED;
audioPlayer_->stop();
}

std::string BaseAudioContext::getState() {
return BaseAudioContext::toString(state_);
}
Expand Down Expand Up @@ -96,7 +104,7 @@ std::shared_ptr<PeriodicWave> BaseAudioContext::createPeriodicWave(
}

std::function<void(AudioBus *, int)> BaseAudioContext::renderAudio() {
if (state_ == ContextState::CLOSED) {
if (isClosed()) {
return [](AudioBus *, int) {};
}

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

bool BaseAudioContext::isRunning() const {
return state_ == ContextState::RUNNING;
}

bool BaseAudioContext::isClosed() const {
return state_ == ContextState::CLOSED;
}

std::string BaseAudioContext::toString(ContextState state) {
switch (state) {
case ContextState::SUSPENDED:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class IOSAudioPlayer;
class BaseAudioContext {
public:
BaseAudioContext();
~BaseAudioContext();
std::string getState();
[[nodiscard]] int getSampleRate() const;
[[nodiscard]] double getCurrentTime() const;
Expand All @@ -54,6 +55,8 @@ class BaseAudioContext {
std::function<void(AudioBus *, int)> renderAudio();

AudioNodeManager* getNodeManager();
bool isRunning() const;
bool isClosed() const;

protected:
static std::string toString(ContextState state);
Expand Down

0 comments on commit 261b8ac

Please sign in to comment.