Skip to content

Commit c1974d3

Browse files
maciejmakowski2003Maciej Makowski
andauthored
Fix/android/audio recorder/missing last audio chunk (#437)
* feat: added core audio event handler class * feat: added more core for audio event handler * fix: removed almost all singleton classes * ci: yarn format * fix: merged AudioAPIModule with AudioManagerModule * ci: yarn format * refactor: refactored android modules structure * ci: yarn format * fix: refactored oldArch java specs * feat: added core audio event handler class * feat: added more core for audio event handler * refactor: small refactoring of responsibilities * ci: yarn format * fix: removed trash changes * feat: sth works * feat: implemented removeAudioEventListener * ci: yarn format * refactor: huge refactoring * fix: small fix * feat: added event subscription class * refactor: removed unused checks * refactor: removed onError and onStatusChange from recorder * ci: yarn format * fix: removed unused prop * feat: base for audio events emitter on android * feat: passing value to events almost done * feat: events form native works * fix: fixed package json lint:ios command * feat: new recorder api works on android * ci: yarn format * feat: new recorder api works * ci: yarn format * refactor: refactored duplicated code * fix: fixed bug * ci: yarn format --------- Co-authored-by: Maciej Makowski <maciej.makowski2608@gmail.com>
1 parent 5536206 commit c1974d3

File tree

11 files changed

+79
-27
lines changed

11 files changed

+79
-27
lines changed

packages/react-native-audio-api/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <audioapi/events/AudioEventHandlerRegistry.h>
44
#include <audioapi/utils/AudioArray.h>
55
#include <audioapi/utils/AudioBus.h>
6+
#include <audioapi/utils/CircularAudioArray.h>
67

78
namespace audioapi {
89

@@ -21,7 +22,6 @@ AndroidAudioRecorder::AndroidAudioRecorder(
2122
->setSampleRateConversionQuality(SampleRateConversionQuality::Medium)
2223
->setDataCallback(this)
2324
->setSampleRate(static_cast<int>(sampleRate))
24-
->setFramesPerDataCallback(bufferLength)
2525
->openStream(mStream_);
2626
}
2727

@@ -36,29 +36,50 @@ AndroidAudioRecorder::~AndroidAudioRecorder() {
3636
}
3737

3838
void AndroidAudioRecorder::start() {
39+
if (isRunning_.load()) {
40+
return;
41+
}
42+
3943
if (mStream_) {
4044
mStream_->requestStart();
4145
}
46+
47+
isRunning_.store(true);
4248
}
4349

4450
void AndroidAudioRecorder::stop() {
51+
if (!isRunning_.load()) {
52+
return;
53+
}
54+
55+
isRunning_.store(false);
56+
4557
if (mStream_) {
4658
mStream_->requestStop();
4759
}
60+
61+
sendRemainingData();
4862
}
4963

5064
DataCallbackResult AndroidAudioRecorder::onAudioReady(
5165
oboe::AudioStream *oboeStream,
5266
void *audioData,
5367
int32_t numFrames) {
54-
auto buffer = static_cast<float *>(audioData);
68+
if (isRunning_.load()) {
69+
auto *inputChannel = static_cast<float *>(audioData);
70+
circularBuffer_->push_back(inputChannel, numFrames);
71+
}
5572

56-
auto bus = std::make_shared<AudioBus>(bufferLength_, 1, sampleRate_);
57-
memcpy(bus->getChannel(0)->getData(), buffer, numFrames * sizeof(float));
58-
auto when = static_cast<double>(
59-
oboeStream->getTimestamp(CLOCK_MONOTONIC).value().timestamp);
73+
while (circularBuffer_->getNumberOfAvailableFrames() >= bufferLength_) {
74+
auto bus = std::make_shared<AudioBus>(bufferLength_, 1, sampleRate_);
75+
auto *outputChannel = bus->getChannel(0)->getData();
6076

61-
invokeOnAudioReadyCallback(bus, numFrames, when);
77+
circularBuffer_->pop_front(outputChannel, bufferLength_);
78+
auto when = static_cast<double>(
79+
oboeStream->getTimestamp(CLOCK_MONOTONIC).value().timestamp);
80+
81+
invokeOnAudioReadyCallback(bus, bufferLength_, when);
82+
}
6283

6384
return DataCallbackResult::Continue;
6485
}

packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class AudioFocusListener(
1515
) : AudioManager.OnAudioFocusChangeListener {
1616
private var playOnAudioFocus = false
1717
private var focusRequest: AudioFocusRequest? = null
18+
private val audioAPIModule: WeakReference<AudioAPIModule> = WeakReference(audioAPIModule)
1819

1920
override fun onAudioFocusChange(focusChange: Int) {
2021
Log.d("AudioFocusListener", "onAudioFocusChange: $focusChange")

packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class MediaSessionCallback(
1313
private val audioAPIModule: WeakReference<AudioAPIModule>,
1414
private val lockScreenManager: WeakReference<LockScreenManager>,
1515
) : MediaSessionCompat.Callback() {
16+
private val audioAPIModule: WeakReference<AudioAPIModule> = WeakReference(audioAPIModule)
17+
1618
override fun onPlay() {
1719
lockScreenManager.get()?.updatePlaybackState(PlaybackStateCompat.STATE_PLAYING)
1820
audioAPIModule.get()?.invokeHandlerWithEventNameAndEventBody("remotePlay", mapOf())

packages/react-native-audio-api/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class VolumeChangeListener(
1313
private val audioManager: WeakReference<AudioManager>,
1414
private val audioAPIModule: WeakReference<AudioAPIModule>,
1515
) : BroadcastReceiver() {
16+
private val audioAPIModule: WeakReference<AudioAPIModule> = WeakReference(audioAPIModule)
17+
1618
override fun onReceive(
1719
context: Context?,
1820
intent: Intent?,

packages/react-native-audio-api/common/cpp/audioapi/core/inputs/AudioRecorder.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include <audioapi/core/inputs/AudioRecorder.h>
33
#include <audioapi/core/sources/AudioBuffer.h>
44
#include <audioapi/events/AudioEventHandlerRegistry.h>
5+
#include <audioapi/utils/AudioBus.h>
6+
#include <audioapi/utils/CircularAudioArray.h>
57

68
namespace audioapi {
79

@@ -11,7 +13,11 @@ AudioRecorder::AudioRecorder(
1113
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
1214
: sampleRate_(sampleRate),
1315
bufferLength_(bufferLength),
14-
audioEventHandlerRegistry_(audioEventHandlerRegistry) {}
16+
audioEventHandlerRegistry_(audioEventHandlerRegistry) {
17+
circularBuffer_ =
18+
std::make_shared<CircularAudioArray>(std::max(2 * bufferLength, 2048));
19+
isRunning_.store(false);
20+
}
1521

1622
void AudioRecorder::setOnAudioReadyCallbackId(uint64_t callbackId) {
1723
onAudioReadyCallbackId_ = callbackId;
@@ -34,4 +40,17 @@ void AudioRecorder::invokeOnAudioReadyCallback(
3440
"audioReady", onAudioReadyCallbackId_, body);
3541
}
3642

43+
void AudioRecorder::sendRemainingData() {
44+
auto bus = std::make_shared<AudioBus>(
45+
circularBuffer_->getNumberOfAvailableFrames(), 1, sampleRate_);
46+
auto *outputChannel = bus->getChannel(0)->getData();
47+
auto availableFrames =
48+
static_cast<int>(circularBuffer_->getNumberOfAvailableFrames());
49+
50+
circularBuffer_->pop_front(
51+
outputChannel, circularBuffer_->getNumberOfAvailableFrames());
52+
53+
invokeOnAudioReadyCallback(bus, availableFrames, 0);
54+
}
55+
3756
} // namespace audioapi

packages/react-native-audio-api/common/cpp/audioapi/core/inputs/AudioRecorder.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace audioapi {
66
class AudioBus;
7+
class CircularAudioArray;
78
class AudioEventHandlerRegistry;
89

910
class AudioRecorder {
@@ -18,6 +19,7 @@ class AudioRecorder {
1819

1920
void setOnAudioReadyCallbackId(uint64_t callbackId);
2021
void invokeOnAudioReadyCallback(const std::shared_ptr<AudioBus> &bus, int numFrames, double when);
22+
void sendRemainingData();
2123

2224
virtual void start() = 0;
2325
virtual void stop() = 0;
@@ -26,6 +28,9 @@ class AudioRecorder {
2628
float sampleRate_;
2729
int bufferLength_;
2830

31+
std::atomic<bool> isRunning_;
32+
std::shared_ptr<CircularAudioArray> circularBuffer_;
33+
2934
std::shared_ptr<AudioEventHandlerRegistry> audioEventHandlerRegistry_;
3035
uint64_t onAudioReadyCallbackId_ = 0;
3136
};

packages/react-native-audio-api/common/cpp/audioapi/core/sources/OscillatorNode.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ void OscillatorNode::processNode(
7070
for (size_t i = startOffset; i < offsetLength; i += 1) {
7171
auto detuneRatio = std::pow(
7272
2.0f, detuneParamValues->getChannel(0)->getData()[i] / 1200.0f);
73-
auto detunedFrequency = frequencyParamValues->getChannel(0)->getData()[i] * detuneRatio;
73+
auto detunedFrequency =
74+
frequencyParamValues->getChannel(0)->getData()[i] * detuneRatio;
7475
auto phaseIncrement = detunedFrequency * periodicWave_->getScale();
7576

7677
float sample =

packages/react-native-audio-api/ios/audioapi/ios/core/IOSAudioRecorder.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ class IOSAudioRecorder : public AudioRecorder {
2828

2929
private:
3030
NativeAudioRecorder *audioRecorder_;
31-
std::atomic<bool> isRunning_;
32-
33-
std::shared_ptr<CircularAudioArray> circularBuffer_;
34-
35-
void sendRemainingData();
3631
};
3732

3833
} // namespace audioapi

packages/react-native-audio-api/ios/audioapi/ios/core/IOSAudioRecorder.mm

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
1818
: AudioRecorder(sampleRate, bufferLength, audioEventHandlerRegistry)
1919
{
20-
circularBuffer_ = std::make_shared<CircularAudioArray>(std::max(2 * bufferLength, 2048));
21-
2220
AudioReceiverBlock audioReceiverBlock = ^(const AudioBufferList *inputBuffer, int numFrames, AVAudioTime *when) {
2321
if (isRunning_.load()) {
2422
auto *inputChannel = static_cast<float *>(inputBuffer->mBuffers[0].mData);
@@ -70,15 +68,4 @@
7068
sendRemainingData();
7169
}
7270

73-
void IOSAudioRecorder::sendRemainingData()
74-
{
75-
auto bus = std::make_shared<AudioBus>(circularBuffer_->getNumberOfAvailableFrames(), 1, sampleRate_);
76-
auto *outputChannel = bus->getChannel(0)->getData();
77-
auto availableFrames = static_cast<int>(circularBuffer_->getNumberOfAvailableFrames());
78-
79-
circularBuffer_->pop_front(outputChannel, circularBuffer_->getNumberOfAvailableFrames());
80-
81-
invokeOnAudioReadyCallback(bus, availableFrames, 0);
82-
}
83-
8471
} // namespace audioapi
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#import <Foundation/Foundation.h>
4+
5+
@interface IOSAudioEventHandlerRegistry : NSObject
6+
7+
-

0 commit comments

Comments
 (0)