react-native-audio-api 0.9.0-nightly-96a5bcd-20251007 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/cpp/audioapi/android/core/{utils/AudioDecoder.cpp → AudioDecoder.cpp} +75 -79
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +43 -99
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +101 -1
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +3 -0
- package/common/cpp/audioapi/core/AudioContext.cpp +2 -0
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +35 -0
- package/common/cpp/audioapi/core/BaseAudioContext.h +12 -4
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +2 -0
- package/common/cpp/audioapi/core/utils/AudioDecoder.h +90 -36
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +282 -241
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.h +19 -57
- package/common/cpp/test/CMakeLists.txt +1 -1
- package/ios/audioapi/ios/core/AudioDecoder.mm +156 -0
- package/lib/commonjs/api.js +1 -14
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/BaseAudioContext.js +18 -11
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
- package/lib/module/api.js +1 -2
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +18 -11
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/typescript/api.d.ts +1 -3
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +6 -3
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +3 -6
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api.ts +0 -5
- package/src/core/BaseAudioContext.ts +29 -26
- package/src/interfaces.ts +6 -18
- package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.cpp +0 -107
- package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.h +0 -28
- package/common/cpp/audioapi/core/types/AudioFormat.h +0 -16
- package/ios/audioapi/ios/core/utils/AudioDecoder.mm +0 -160
- package/lib/commonjs/core/AudioDecoder.js +0 -48
- package/lib/commonjs/core/AudioDecoder.js.map +0 -1
- package/lib/module/core/AudioDecoder.js +0 -42
- package/lib/module/core/AudioDecoder.js.map +0 -1
- package/lib/typescript/core/AudioDecoder.d.ts +0 -4
- package/lib/typescript/core/AudioDecoder.d.ts.map +0 -1
- package/src/core/AudioDecoder.ts +0 -78
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
#include <audioapi/core/types/ContextState.h>
|
|
4
4
|
#include <audioapi/core/types/OscillatorType.h>
|
|
5
5
|
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
6
|
-
|
|
7
|
-
#include <complex>
|
|
8
|
-
#include <cstddef>
|
|
6
|
+
|
|
9
7
|
#include <functional>
|
|
10
8
|
#include <memory>
|
|
11
9
|
#include <string>
|
|
12
10
|
#include <utility>
|
|
13
11
|
#include <vector>
|
|
12
|
+
#include <complex>
|
|
13
|
+
#include <cstddef>
|
|
14
|
+
#include <cassert>
|
|
14
15
|
|
|
15
16
|
namespace audioapi {
|
|
16
17
|
|
|
@@ -26,6 +27,7 @@ class BiquadFilterNode;
|
|
|
26
27
|
class AudioDestinationNode;
|
|
27
28
|
class AudioBufferSourceNode;
|
|
28
29
|
class AudioBufferQueueSourceNode;
|
|
30
|
+
class AudioDecoder;
|
|
29
31
|
class AnalyserNode;
|
|
30
32
|
class AudioEventHandlerRegistry;
|
|
31
33
|
class IAudioEventHandlerRegistry;
|
|
@@ -66,6 +68,10 @@ class BaseAudioContext {
|
|
|
66
68
|
int length);
|
|
67
69
|
std::shared_ptr<AnalyserNode> createAnalyser();
|
|
68
70
|
|
|
71
|
+
std::shared_ptr<AudioBuffer> decodeAudioDataSource(const std::string &path);
|
|
72
|
+
std::shared_ptr<AudioBuffer> decodeAudioData(const void *data, size_t size);
|
|
73
|
+
std::shared_ptr<AudioBuffer> decodeWithPCMInBase64(const std::string &data, float playbackSpeed);
|
|
74
|
+
|
|
69
75
|
std::shared_ptr<PeriodicWave> getBasicWaveForm(OscillatorType type);
|
|
70
76
|
[[nodiscard]] float getNyquistFrequency() const;
|
|
71
77
|
AudioNodeManager *getNodeManager();
|
|
@@ -79,7 +85,9 @@ class BaseAudioContext {
|
|
|
79
85
|
|
|
80
86
|
std::shared_ptr<AudioDestinationNode> destination_;
|
|
81
87
|
// init in AudioContext or OfflineContext constructor
|
|
82
|
-
|
|
88
|
+
std::shared_ptr<AudioDecoder> audioDecoder_ {};
|
|
89
|
+
// init in AudioContext or OfflineContext constructor
|
|
90
|
+
float sampleRate_ {};
|
|
83
91
|
ContextState state_ = ContextState::RUNNING;
|
|
84
92
|
std::shared_ptr<AudioNodeManager> nodeManager_;
|
|
85
93
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#include <audioapi/core/AudioContext.h>
|
|
4
4
|
#include <audioapi/core/destinations/AudioDestinationNode.h>
|
|
5
5
|
#include <audioapi/core/sources/AudioBuffer.h>
|
|
6
|
+
#include <audioapi/core/utils/AudioDecoder.h>
|
|
6
7
|
#include <audioapi/core/utils/AudioNodeManager.h>
|
|
7
8
|
#include <audioapi/core/utils/Constants.h>
|
|
8
9
|
#include <audioapi/core/utils/Locker.h>
|
|
@@ -29,6 +30,7 @@ OfflineAudioContext::OfflineAudioContext(
|
|
|
29
30
|
numberOfChannels_(numberOfChannels),
|
|
30
31
|
currentSampleFrame_(0) {
|
|
31
32
|
sampleRate_ = sampleRate;
|
|
33
|
+
audioDecoder_ = std::make_shared<AudioDecoder>(sampleRate_);
|
|
32
34
|
resultBus_ = std::make_shared<AudioBus>(
|
|
33
35
|
static_cast<int>(length_), numberOfChannels_, sampleRate_);
|
|
34
36
|
}
|
|
@@ -1,68 +1,124 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <audioapi/core/types/AudioFormat.h>
|
|
4
3
|
#include <audioapi/libs/audio-stretch/stretch.h>
|
|
5
4
|
#include <audioapi/libs/miniaudio/miniaudio.h>
|
|
6
|
-
#include <algorithm>
|
|
7
|
-
#include <cstring>
|
|
8
5
|
#include <memory>
|
|
9
6
|
#include <string>
|
|
10
7
|
#include <vector>
|
|
8
|
+
#include <cstring>
|
|
9
|
+
#include <algorithm>
|
|
11
10
|
|
|
12
11
|
namespace audioapi {
|
|
13
12
|
|
|
14
|
-
class
|
|
13
|
+
enum class AudioFormat {
|
|
14
|
+
UNKNOWN,
|
|
15
|
+
WAV,
|
|
16
|
+
OGG,
|
|
17
|
+
FLAC,
|
|
18
|
+
AAC,
|
|
19
|
+
MP3,
|
|
20
|
+
M4A,
|
|
21
|
+
MP4,
|
|
22
|
+
MOV
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
class AudioBus;
|
|
15
26
|
|
|
16
27
|
static constexpr int CHUNK_SIZE = 4096;
|
|
17
28
|
|
|
18
29
|
class AudioDecoder {
|
|
19
30
|
public:
|
|
20
|
-
AudioDecoder()
|
|
31
|
+
explicit AudioDecoder(float sampleRate) : sampleRate_(sampleRate) {}
|
|
21
32
|
|
|
22
|
-
[[nodiscard]]
|
|
23
|
-
|
|
24
|
-
decodeWithMemoryBlock(
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
[[nodiscard]] std::shared_ptr<AudioBus> decodeWithFilePath(
|
|
34
|
+
const std::string &path) const;
|
|
35
|
+
[[nodiscard]] std::shared_ptr<AudioBus> decodeWithMemoryBlock(
|
|
36
|
+
const void *data,
|
|
37
|
+
size_t size) const;
|
|
38
|
+
[[nodiscard]] std::shared_ptr<AudioBus> decodeWithPCMInBase64(
|
|
39
|
+
const std::string &data,
|
|
40
|
+
float playbackSpeed) const;
|
|
27
41
|
|
|
28
42
|
private:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
float sampleRate_;
|
|
44
|
+
int numChannels_ = 2;
|
|
45
|
+
|
|
46
|
+
static std::vector<int16_t> readAllPcmFrames(
|
|
47
|
+
ma_decoder &decoder,
|
|
48
|
+
int numChannels,
|
|
49
|
+
ma_uint64 &outFramesRead);
|
|
50
|
+
static std::shared_ptr<AudioBus> makeAudioBusFromInt16Buffer(
|
|
51
|
+
const std::vector<int16_t> &buffer,
|
|
52
|
+
int numChannels,
|
|
53
|
+
float sampleRate);
|
|
54
|
+
|
|
55
|
+
void changePlaybackSpeedIfNeeded(
|
|
56
|
+
std::vector<int16_t> &buffer,
|
|
57
|
+
size_t framesDecoded,
|
|
58
|
+
int numChannels,
|
|
59
|
+
float playbackSpeed) const {
|
|
60
|
+
if (playbackSpeed == 1.0f) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
auto stretcher = stretch_init(
|
|
65
|
+
static_cast<int>(sampleRate_ / 333.0f),
|
|
66
|
+
static_cast<int>(sampleRate_ / 55.0f),
|
|
67
|
+
numChannels,
|
|
68
|
+
0x1);
|
|
32
69
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
int maxOutputFrames = stretch_output_capacity(
|
|
71
|
+
stretcher, static_cast<int>(framesDecoded), 1 / playbackSpeed);
|
|
72
|
+
std::vector<int16_t> stretchedBuffer(maxOutputFrames);
|
|
73
|
+
|
|
74
|
+
int outputFrames = stretch_samples(
|
|
75
|
+
stretcher,
|
|
76
|
+
buffer.data(),
|
|
77
|
+
static_cast<int>(framesDecoded),
|
|
78
|
+
stretchedBuffer.data(),
|
|
79
|
+
1 / playbackSpeed);
|
|
80
|
+
|
|
81
|
+
outputFrames +=
|
|
82
|
+
stretch_flush(stretcher, stretchedBuffer.data() + (outputFrames));
|
|
83
|
+
stretchedBuffer.resize(outputFrames);
|
|
84
|
+
|
|
85
|
+
buffer = stretchedBuffer;
|
|
86
|
+
|
|
87
|
+
stretch_deinit(stretcher);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static AudioFormat detectAudioFormat(const void* data, size_t size) {
|
|
91
|
+
if (size < 12) return AudioFormat::UNKNOWN;
|
|
92
|
+
const auto* bytes = static_cast<const unsigned char*>(data);
|
|
37
93
|
|
|
38
94
|
// WAV/RIFF
|
|
39
95
|
if (std::memcmp(bytes, "RIFF", 4) == 0 && std::memcmp(bytes + 8, "WAVE", 4) == 0)
|
|
40
|
-
|
|
96
|
+
return AudioFormat::WAV;
|
|
41
97
|
|
|
42
98
|
// OGG
|
|
43
99
|
if (std::memcmp(bytes, "OggS", 4) == 0)
|
|
44
|
-
|
|
100
|
+
return AudioFormat::OGG;
|
|
45
101
|
|
|
46
102
|
// FLAC
|
|
47
103
|
if (std::memcmp(bytes, "fLaC", 4) == 0)
|
|
48
|
-
|
|
104
|
+
return AudioFormat::FLAC;
|
|
49
105
|
|
|
50
106
|
// AAC starts with 0xFF 0xF1 or 0xFF 0xF9
|
|
51
107
|
if (bytes[0] == 0xFF && (bytes[1] & 0xF6) == 0xF0)
|
|
52
|
-
|
|
108
|
+
return AudioFormat::AAC;
|
|
53
109
|
|
|
54
110
|
// MP3: "ID3" or 11-bit frame sync (0xFF 0xE0)
|
|
55
111
|
if (std::memcmp(bytes, "ID3", 3) == 0)
|
|
56
|
-
|
|
112
|
+
return AudioFormat::MP3;
|
|
57
113
|
if (bytes[0] == 0xFF && (bytes[1] & 0xE0) == 0xE0)
|
|
58
|
-
|
|
114
|
+
return AudioFormat::MP3;
|
|
59
115
|
|
|
60
116
|
if (std::memcmp(bytes + 4, "ftyp", 4) == 0) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
117
|
+
if (std::memcmp(bytes + 8, "M4A ", 4) == 0)
|
|
118
|
+
return AudioFormat::M4A;
|
|
119
|
+
else if (std::memcmp(bytes + 8, "qt ", 4) == 0)
|
|
120
|
+
return AudioFormat::MOV;
|
|
121
|
+
return AudioFormat::MP4;
|
|
66
122
|
}
|
|
67
123
|
return AudioFormat::UNKNOWN;
|
|
68
124
|
}
|
|
@@ -70,21 +126,19 @@ class AudioDecoder {
|
|
|
70
126
|
static inline bool pathHasExtension(const std::string &path, const std::vector<std::string> &extensions) {
|
|
71
127
|
std::string pathLower = path;
|
|
72
128
|
std::transform(pathLower.begin(), pathLower.end(), pathLower.begin(), ::tolower);
|
|
73
|
-
for (const auto
|
|
74
|
-
|
|
75
|
-
|
|
129
|
+
for (const auto& ext : extensions) {
|
|
130
|
+
if (pathLower.ends_with(ext))
|
|
131
|
+
return true;
|
|
76
132
|
}
|
|
77
133
|
return false;
|
|
78
134
|
}
|
|
79
135
|
|
|
136
|
+
|
|
80
137
|
[[nodiscard]] static inline int16_t floatToInt16(float sample) {
|
|
81
|
-
return static_cast<int16_t>(sample *
|
|
138
|
+
return static_cast<int16_t>(sample * 32768.0f);
|
|
82
139
|
}
|
|
83
140
|
[[nodiscard]] static inline float int16ToFloat(int16_t sample) {
|
|
84
|
-
return static_cast<float>(sample) /
|
|
85
|
-
}
|
|
86
|
-
[[nodiscard]] static inline float uint8ToFloat(uint8_t byte1, uint8_t byte2) {
|
|
87
|
-
return static_cast<float>(static_cast<int16_t>((byte2 << 8) | byte1)) / INT16_MAX;
|
|
141
|
+
return static_cast<float>(sample) / 32768.0f;
|
|
88
142
|
}
|
|
89
143
|
};
|
|
90
144
|
|