react-native-audio-api 0.0.1 → 0.1.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.
Files changed (116) hide show
  1. package/README.md +58 -1
  2. package/RNAudioAPI.podspec +41 -0
  3. package/android/CMakeLists.txt +63 -0
  4. package/android/build.gradle +194 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +3 -0
  7. package/android/src/main/AndroidManifestNew.xml +2 -0
  8. package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.cpp +22 -0
  9. package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.h +48 -0
  10. package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +45 -0
  11. package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +30 -0
  12. package/android/src/main/cpp/OnLoad.cpp +9 -0
  13. package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +14 -0
  14. package/android/src/main/java/com/swmansion/audioapi/module/AudioAPIInstaller.kt +21 -0
  15. package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +25 -0
  16. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +52 -0
  17. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +45 -0
  18. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerWrapper.h +38 -0
  19. package/common/cpp/AudioAPIInstaller/android/AudioAPIInstallerWrapper.cpp +16 -0
  20. package/common/cpp/AudioAPIInstaller/ios/AudioAPIInstallerWrapper.cpp +12 -0
  21. package/common/cpp/HostObjects/AudioBufferHostObject.cpp +143 -0
  22. package/common/cpp/HostObjects/AudioBufferHostObject.h +33 -0
  23. package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +67 -0
  24. package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.h +37 -0
  25. package/common/cpp/HostObjects/AudioContextHostObject.cpp +191 -0
  26. package/common/cpp/HostObjects/AudioContextHostObject.h +43 -0
  27. package/common/cpp/HostObjects/AudioDestinationNodeHostObject.cpp +33 -0
  28. package/common/cpp/HostObjects/AudioDestinationNodeHostObject.h +31 -0
  29. package/common/cpp/HostObjects/AudioNodeHostObject.cpp +108 -0
  30. package/common/cpp/HostObjects/AudioNodeHostObject.h +29 -0
  31. package/common/cpp/HostObjects/AudioParamHostObject.cpp +115 -0
  32. package/common/cpp/HostObjects/AudioParamHostObject.h +34 -0
  33. package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.cpp +73 -0
  34. package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.h +31 -0
  35. package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +81 -0
  36. package/common/cpp/HostObjects/BiquadFilterNodeHostObject.h +42 -0
  37. package/common/cpp/HostObjects/Constants.h +22 -0
  38. package/common/cpp/HostObjects/GainNodeHostObject.cpp +41 -0
  39. package/common/cpp/HostObjects/GainNodeHostObject.h +32 -0
  40. package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +67 -0
  41. package/common/cpp/HostObjects/OscillatorNodeHostObject.h +40 -0
  42. package/common/cpp/HostObjects/StereoPannerNodeHostObject.cpp +41 -0
  43. package/common/cpp/HostObjects/StereoPannerNodeHostObject.h +36 -0
  44. package/common/cpp/core/AudioBuffer.cpp +115 -0
  45. package/common/cpp/core/AudioBuffer.h +42 -0
  46. package/common/cpp/core/AudioBufferSourceNode.cpp +58 -0
  47. package/common/cpp/core/AudioBufferSourceNode.h +26 -0
  48. package/common/cpp/core/AudioContext.cpp +90 -0
  49. package/common/cpp/core/AudioContext.h +73 -0
  50. package/common/cpp/core/AudioDestinationNode.cpp +35 -0
  51. package/common/cpp/core/AudioDestinationNode.h +24 -0
  52. package/common/cpp/core/AudioNode.cpp +68 -0
  53. package/common/cpp/core/AudioNode.h +74 -0
  54. package/common/cpp/core/AudioParam.cpp +136 -0
  55. package/common/cpp/core/AudioParam.h +50 -0
  56. package/common/cpp/core/AudioScheduledSourceNode.cpp +39 -0
  57. package/common/cpp/core/AudioScheduledSourceNode.h +30 -0
  58. package/common/cpp/core/BiquadFilterNode.cpp +364 -0
  59. package/common/cpp/core/BiquadFilterNode.h +128 -0
  60. package/common/cpp/core/GainNode.cpp +30 -0
  61. package/common/cpp/core/GainNode.h +23 -0
  62. package/common/cpp/core/OscillatorNode.cpp +66 -0
  63. package/common/cpp/core/OscillatorNode.h +112 -0
  64. package/common/cpp/core/ParamChange.cpp +46 -0
  65. package/common/cpp/core/ParamChange.h +34 -0
  66. package/common/cpp/core/StereoPannerNode.cpp +58 -0
  67. package/common/cpp/core/StereoPannerNode.h +26 -0
  68. package/common/cpp/utils/VectorMath.cpp +609 -0
  69. package/common/cpp/utils/VectorMath.h +65 -0
  70. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +35 -0
  71. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +25 -0
  72. package/common/cpp/wrappers/AudioBufferWrapper.cpp +46 -0
  73. package/common/cpp/wrappers/AudioBufferWrapper.h +30 -0
  74. package/common/cpp/wrappers/AudioContextWrapper.cpp +70 -0
  75. package/common/cpp/wrappers/AudioContextWrapper.h +40 -0
  76. package/common/cpp/wrappers/AudioDestinationNodeWrapper.h +16 -0
  77. package/common/cpp/wrappers/AudioNodeWrapper.cpp +37 -0
  78. package/common/cpp/wrappers/AudioNodeWrapper.h +25 -0
  79. package/common/cpp/wrappers/AudioParamWrapper.cpp +42 -0
  80. package/common/cpp/wrappers/AudioParamWrapper.h +25 -0
  81. package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.cpp +23 -0
  82. package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.h +23 -0
  83. package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +51 -0
  84. package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +32 -0
  85. package/common/cpp/wrappers/GainNodeWrapper.cpp +14 -0
  86. package/common/cpp/wrappers/GainNodeWrapper.h +20 -0
  87. package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +38 -0
  88. package/common/cpp/wrappers/OscillatorNodeWrapper.h +28 -0
  89. package/common/cpp/wrappers/StereoPannerNodeWrapper.cpp +16 -0
  90. package/common/cpp/wrappers/StereoPannerNodeWrapper.h +21 -0
  91. package/ios/AudioAPIModule.h +5 -0
  92. package/ios/AudioAPIModule.mm +44 -0
  93. package/ios/AudioPlayer/AudioPlayer.h +27 -0
  94. package/ios/AudioPlayer/AudioPlayer.m +121 -0
  95. package/ios/AudioPlayer/IOSAudioPlayer.h +29 -0
  96. package/ios/AudioPlayer/IOSAudioPlayer.mm +34 -0
  97. package/lib/module/index.js +39 -0
  98. package/lib/module/index.js.map +1 -0
  99. package/lib/module/modules/global.d.js +2 -0
  100. package/lib/module/modules/global.d.js.map +1 -0
  101. package/lib/module/types.js +2 -0
  102. package/lib/module/types.js.map +1 -0
  103. package/lib/module/utils/install.js +22 -0
  104. package/lib/module/utils/install.js.map +1 -0
  105. package/lib/typescript/index.d.ts +18 -0
  106. package/lib/typescript/index.d.ts.map +1 -0
  107. package/lib/typescript/types.d.ts +76 -0
  108. package/lib/typescript/types.d.ts.map +1 -0
  109. package/lib/typescript/utils/install.d.ts +7 -0
  110. package/lib/typescript/utils/install.d.ts.map +1 -0
  111. package/package.json +104 -5
  112. package/src/index.ts +79 -0
  113. package/src/modules/global.d.ts +10 -0
  114. package/src/types.ts +108 -0
  115. package/src/utils/install.ts +39 -0
  116. package/index.ts +0 -1
@@ -0,0 +1,44 @@
1
+ #import "AudioAPIModule.h"
2
+
3
+ #import <React/RCTBridge+Private.h>
4
+ #import <React/RCTUtils.h>
5
+ #import <jsi/jsi.h>
6
+
7
+ #import "../common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h"
8
+ #import "../common/cpp/AudioAPIInstaller/AudioAPIInstallerWrapper.h"
9
+
10
+ @implementation AudioAPIModule
11
+
12
+ RCT_EXPORT_MODULE(AudioAPIModule)
13
+
14
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
15
+ {
16
+ NSLog(@"Installing JSI bindings for react-native-audio-api...");
17
+ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)[RCTBridge currentBridge];
18
+
19
+ if (cxxBridge == nil) {
20
+ NSLog(@"Error during getting bridge!");
21
+ return @false;
22
+ }
23
+
24
+ using namespace facebook;
25
+
26
+ auto jsRuntime = (jsi::Runtime *)cxxBridge.runtime;
27
+
28
+ if (jsRuntime == nil) {
29
+ NSLog(@"Error during getting jsRuntime!");
30
+ return @false;
31
+ }
32
+
33
+ auto &runtime = *jsRuntime;
34
+
35
+ auto wrapper = std::make_shared<audioapi::AudioAPIInstallerWrapper>();
36
+ auto hostObject = std::make_shared<audioapi::AudioAPIInstallerHostObject>(wrapper);
37
+ auto object = jsi::Object::createFromHostObject(runtime, hostObject);
38
+ runtime.global().setProperty(runtime, "__AudioAPIInstaller", std::move(object));
39
+
40
+ NSLog(@"Successfully installed JSI bindings for react-native-audio-api!");
41
+ return @true;
42
+ }
43
+
44
+ @end
@@ -0,0 +1,27 @@
1
+ #pragma once
2
+
3
+ #import <AVFoundation/AVFoundation.h>
4
+ #import <Foundation/Foundation.h>
5
+
6
+ typedef void (^RenderAudioBlock)(float *audioData, int numFrames);
7
+
8
+ @interface AudioPlayer : NSObject
9
+
10
+ @property (nonatomic, strong) AVAudioEngine *audioEngine;
11
+ @property (nonatomic, weak) AVAudioSession *audioSession;
12
+ @property (nonatomic, strong) AVAudioFormat *format;
13
+ @property (nonatomic, strong) AVAudioSourceNode *sourceNode;
14
+ @property (nonatomic, copy) RenderAudioBlock renderAudio;
15
+ @property (nonatomic, assign) float *buffer;
16
+
17
+ - (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio;
18
+
19
+ - (int)getSampleRate;
20
+
21
+ - (void)start;
22
+
23
+ - (void)stop;
24
+
25
+ - (void)cleanup;
26
+
27
+ @end
@@ -0,0 +1,121 @@
1
+ #import <AudioPlayer.h>
2
+
3
+ @implementation AudioPlayer
4
+
5
+ - (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio
6
+ {
7
+ if (self = [super init]) {
8
+ self.renderAudio = [renderAudio copy];
9
+ self.audioEngine = [[AVAudioEngine alloc] init];
10
+ self.audioEngine.mainMixerNode.outputVolume = 1;
11
+
12
+ self.audioSession = AVAudioSession.sharedInstance;
13
+ NSError *error = nil;
14
+
15
+ // TODO:
16
+ // We will probably want to change it to AVAudioSessionCategoryPlayAndRecord in the future.
17
+ // Eventually we to make this a dynamic setting, if user of the lib wants to use recording features.
18
+ // But setting a recording category might require some setup first, so lets skip it for now :)
19
+ [self.audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];
20
+
21
+ if (error != nil) {
22
+ @throw error;
23
+ }
24
+
25
+ [self.audioSession setActive:true error:&error];
26
+
27
+ if (error != nil) {
28
+ @throw error;
29
+ }
30
+
31
+ _format = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:[self.audioSession sampleRate] channels:2];
32
+
33
+ __weak typeof(self) weakSelf = self;
34
+ _sourceNode = [[AVAudioSourceNode alloc] initWithFormat:self.format
35
+ renderBlock:^OSStatus(
36
+ BOOL *isSilence,
37
+ const AudioTimeStamp *timestamp,
38
+ AVAudioFrameCount frameCount,
39
+ AudioBufferList *outputData) {
40
+ return [weakSelf renderCallbackWithIsSilence:isSilence
41
+ timestamp:timestamp
42
+ frameCount:frameCount
43
+ outputData:outputData];
44
+ }];
45
+
46
+ self.buffer = nil;
47
+ }
48
+
49
+ return self;
50
+ }
51
+
52
+ - (int)getSampleRate
53
+ {
54
+ return [self.audioSession sampleRate];
55
+ }
56
+
57
+ - (void)start
58
+ {
59
+ [self.audioEngine attachNode:self.sourceNode];
60
+ [self.audioEngine connect:self.sourceNode to:self.audioEngine.mainMixerNode format:self.format];
61
+
62
+ if (!self.audioEngine.isRunning) {
63
+ NSError *error = nil;
64
+ if (![self.audioEngine startAndReturnError:&error]) {
65
+ NSLog(@"Error starting audio engine: %@", [error localizedDescription]);
66
+ }
67
+ }
68
+ }
69
+
70
+ - (void)stop
71
+ {
72
+ [self.audioEngine detachNode:self.sourceNode];
73
+
74
+ if (self.audioEngine.isRunning) {
75
+ [self.audioEngine stop];
76
+ }
77
+
78
+ NSError *error = nil;
79
+ [self.audioSession setActive:false error:&error];
80
+
81
+ if (error != nil) {
82
+ @throw error;
83
+ }
84
+ }
85
+
86
+ - (void)cleanup
87
+ {
88
+ self.audioEngine = nil;
89
+ self.audioSession = nil;
90
+ self.renderAudio = nil;
91
+
92
+ free(_buffer);
93
+ }
94
+
95
+ - (OSStatus)renderCallbackWithIsSilence:(BOOL *)isSilence
96
+ timestamp:(const AudioTimeStamp *)timestamp
97
+ frameCount:(AVAudioFrameCount)frameCount
98
+ outputData:(AudioBufferList *)outputData
99
+ {
100
+ if (outputData->mNumberBuffers < 2) {
101
+ return noErr; // Ensure we have stereo output
102
+ }
103
+
104
+ if (!self.buffer) {
105
+ self.buffer = malloc(frameCount * 2 * sizeof(float));
106
+ }
107
+
108
+ float *leftBuffer = (float *)outputData->mBuffers[0].mData;
109
+ float *rightBuffer = (float *)outputData->mBuffers[1].mData;
110
+
111
+ self.renderAudio(self.buffer, frameCount);
112
+
113
+ for (int frame = 0; frame < frameCount; frame += 1) {
114
+ leftBuffer[frame] = self.buffer[frame * 2];
115
+ rightBuffer[frame] = self.buffer[frame * 2 + 1];
116
+ }
117
+
118
+ return noErr;
119
+ }
120
+
121
+ @end
@@ -0,0 +1,29 @@
1
+ #pragma once
2
+
3
+ #ifdef __OBJC__ // when compiled as Objective-C++
4
+ #import <AudioPlayer.h>
5
+ #else // when compiled as C++
6
+ typedef struct objc_object AudioPlayer;
7
+ #endif // __OBJC__
8
+
9
+ #include <functional>
10
+
11
+ namespace audioapi {
12
+
13
+ class AudioContext;
14
+
15
+ class IOSAudioPlayer {
16
+ protected:
17
+ AudioPlayer *audioPlayer_;
18
+ std::function<void(float *, int)> renderAudio_;
19
+
20
+ public:
21
+ explicit IOSAudioPlayer(const std::function<void(float *, int)> &renderAudio);
22
+ ~IOSAudioPlayer();
23
+
24
+ int getSampleRate() const;
25
+ void start();
26
+ void stop();
27
+ void renderAudio(float *audioData, int32_t numFrames);
28
+ };
29
+ } // namespace audioapi
@@ -0,0 +1,34 @@
1
+ #include <IOSAudioPlayer.h>
2
+
3
+ namespace audioapi {
4
+
5
+ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(float *, int)> &renderAudio) : renderAudio_(renderAudio)
6
+ {
7
+ RenderAudioBlock renderAudioBlock = ^(float *audioData, int numFrames) {
8
+ renderAudio_(audioData, numFrames);
9
+ };
10
+
11
+ audioPlayer_ = [[AudioPlayer alloc] initWithRenderAudioBlock:renderAudioBlock];
12
+ }
13
+
14
+ IOSAudioPlayer::~IOSAudioPlayer()
15
+ {
16
+ stop();
17
+ [audioPlayer_ cleanup];
18
+ }
19
+
20
+ int IOSAudioPlayer::getSampleRate() const
21
+ {
22
+ return [audioPlayer_ getSampleRate];
23
+ }
24
+
25
+ void IOSAudioPlayer::start()
26
+ {
27
+ return [audioPlayer_ start];
28
+ }
29
+
30
+ void IOSAudioPlayer::stop()
31
+ {
32
+ return [audioPlayer_ stop];
33
+ }
34
+ } // namespace audioapi
@@ -0,0 +1,39 @@
1
+ import { installModule } from './utils/install';
2
+ if (global.__AudioAPIInstaller == null) {
3
+ installModule();
4
+ }
5
+ export class AudioContext {
6
+ constructor() {
7
+ this.__AudioContext = global.__AudioAPIInstaller.createAudioContext();
8
+ this.destination = this.__AudioContext.destination;
9
+ this.sampleRate = this.__AudioContext.sampleRate;
10
+ }
11
+ get currentTime() {
12
+ return this.__AudioContext.currentTime;
13
+ }
14
+ get state() {
15
+ return this.__AudioContext.state;
16
+ }
17
+ createOscillator() {
18
+ return this.__AudioContext.createOscillator();
19
+ }
20
+ createGain() {
21
+ return this.__AudioContext.createGain();
22
+ }
23
+ createStereoPanner() {
24
+ return this.__AudioContext.createStereoPanner();
25
+ }
26
+ createBiquadFilter() {
27
+ return this.__AudioContext.createBiquadFilter();
28
+ }
29
+ createBufferSource() {
30
+ return this.__AudioContext.createBufferSource();
31
+ }
32
+ createBuffer(numOfChannels, length, sampleRate) {
33
+ return this.__AudioContext.createBuffer(numOfChannels, length, sampleRate);
34
+ }
35
+ close() {
36
+ this.__AudioContext.close();
37
+ }
38
+ }
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["installModule","global","__AudioAPIInstaller","AudioContext","constructor","__AudioContext","createAudioContext","destination","sampleRate","currentTime","state","createOscillator","createGain","createStereoPanner","createBiquadFilter","createBufferSource","createBuffer","numOfChannels","length","close"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAWA,SAASA,aAAa,QAAQ,iBAAiB;AAE/C,IAAIC,MAAM,CAACC,mBAAmB,IAAI,IAAI,EAAE;EACtCF,aAAa,CAAC,CAAC;AACjB;AAEA,OAAO,MAAMG,YAAY,CAA6B;EAKpDC,WAAWA,CAAA,EAAG;IACZ,IAAI,CAACC,cAAc,GAAGJ,MAAM,CAACC,mBAAmB,CAACI,kBAAkB,CAAC,CAAC;IAErE,IAAI,CAACC,WAAW,GAAG,IAAI,CAACF,cAAc,CAACE,WAAW;IAClD,IAAI,CAACC,UAAU,GAAG,IAAI,CAACH,cAAc,CAACG,UAAU;EAClD;EAEA,IAAWC,WAAWA,CAAA,EAAG;IACvB,OAAO,IAAI,CAACJ,cAAc,CAACI,WAAW;EACxC;EAEA,IAAWC,KAAKA,CAAA,EAAG;IACjB,OAAO,IAAI,CAACL,cAAc,CAACK,KAAK;EAClC;EAEAC,gBAAgBA,CAAA,EAAmB;IACjC,OAAO,IAAI,CAACN,cAAc,CAACM,gBAAgB,CAAC,CAAC;EAC/C;EAEAC,UAAUA,CAAA,EAAa;IACrB,OAAO,IAAI,CAACP,cAAc,CAACO,UAAU,CAAC,CAAC;EACzC;EAEAC,kBAAkBA,CAAA,EAAqB;IACrC,OAAO,IAAI,CAACR,cAAc,CAACQ,kBAAkB,CAAC,CAAC;EACjD;EAEAC,kBAAkBA,CAAA,EAAqB;IACrC,OAAO,IAAI,CAACT,cAAc,CAACS,kBAAkB,CAAC,CAAC;EACjD;EAEAC,kBAAkBA,CAAA,EAA0B;IAC1C,OAAO,IAAI,CAACV,cAAc,CAACU,kBAAkB,CAAC,CAAC;EACjD;EAEAC,YAAYA,CACVC,aAAqB,EACrBC,MAAc,EACdV,UAAkB,EACL;IACb,OAAO,IAAI,CAACH,cAAc,CAACW,YAAY,CAACC,aAAa,EAAEC,MAAM,EAAEV,UAAU,CAAC;EAC5E;EAEAW,KAAKA,CAAA,EAAS;IACZ,IAAI,CAACd,cAAc,CAACc,KAAK,CAAC,CAAC;EAC7B;AACF","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=global.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["modules/global.d.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,22 @@
1
+ import { TurboModuleRegistry } from 'react-native';
2
+ export function installModule() {
3
+ const AudioAPIModule = TurboModuleRegistry.getEnforcing('AudioAPIModule');
4
+ if (AudioAPIModule == null) {
5
+ throw new Error(`Failed to install react-native-audio-api: The native module could not be found.`);
6
+ }
7
+ runInstall(AudioAPIModule);
8
+ verifyInstallation();
9
+ return AudioAPIModule;
10
+ }
11
+ function runInstall(Module) {
12
+ const result = Module.install();
13
+ if (result !== true) {
14
+ throw new Error(`Failed to install react-native-audio-api: The native Audio API Module could not be installed! Looks like something went wrong when installing JSI bindings: ${result}`);
15
+ }
16
+ }
17
+ function verifyInstallation() {
18
+ if (global.__AudioAPIInstaller == null) {
19
+ throw new Error('Failed to install react-native-audio-api, the native initializer private does not exist. Are you trying to use Audio API from different JS Runtimes?');
20
+ }
21
+ }
22
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","installModule","AudioAPIModule","getEnforcing","Error","runInstall","verifyInstallation","Module","result","install","global","__AudioAPIInstaller"],"sourceRoot":"../../../src","sources":["utils/install.ts"],"mappings":"AAAA,SAASA,mBAAmB,QAAqB,cAAc;AAM/D,OAAO,SAASC,aAAaA,CAAA,EAAG;EAC9B,MAAMC,cAAc,GAClBF,mBAAmB,CAACG,YAAY,CAAqB,gBAAgB,CAAC;EAExE,IAAID,cAAc,IAAI,IAAI,EAAE;IAC1B,MAAM,IAAIE,KAAK,CACb,iFACF,CAAC;EACH;EAEAC,UAAU,CAACH,cAAc,CAAC;EAC1BI,kBAAkB,CAAC,CAAC;EAEpB,OAAOJ,cAAc;AACvB;AAEA,SAASG,UAAUA,CAACE,MAAW,EAAE;EAC/B,MAAMC,MAAM,GAAGD,MAAM,CAACE,OAAO,CAAC,CAAC;EAE/B,IAAID,MAAM,KAAK,IAAI,EAAE;IACnB,MAAM,IAAIJ,KAAK,CACb,+JAA+JI,MAAM,EACvK,CAAC;EACH;AACF;AAEA,SAASF,kBAAkBA,CAAA,EAAG;EAC5B,IAAII,MAAM,CAACC,mBAAmB,IAAI,IAAI,EAAE;IACtC,MAAM,IAAIP,KAAK,CACb,sJACF,CAAC;EACH;AACF","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ import type { BaseAudioContext, AudioDestinationNode, GainNode, StereoPannerNode, OscillatorNode, BiquadFilterNode, AudioBufferSourceNode, AudioBuffer, WaveType } from './types';
2
+ export declare class AudioContext implements BaseAudioContext {
3
+ readonly destination: AudioDestinationNode;
4
+ readonly sampleRate: number;
5
+ private readonly __AudioContext;
6
+ constructor();
7
+ get currentTime(): number;
8
+ get state(): import("./types").ContextState;
9
+ createOscillator(): OscillatorNode;
10
+ createGain(): GainNode;
11
+ createStereoPanner(): StereoPannerNode;
12
+ createBiquadFilter(): BiquadFilterNode;
13
+ createBufferSource(): AudioBufferSourceNode;
14
+ createBuffer(numOfChannels: number, length: number, sampleRate: number): AudioBuffer;
15
+ close(): void;
16
+ }
17
+ export type { GainNode, StereoPannerNode, OscillatorNode, BiquadFilterNode, AudioBufferSourceNode, AudioBuffer, WaveType, };
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,WAAW,EACX,QAAQ,EACT,MAAM,SAAS,CAAC;AAOjB,qBAAa,YAAa,YAAW,gBAAgB;IACnD,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmB;;IASlD,IAAW,WAAW,WAErB;IAED,IAAW,KAAK,mCAEf;IAED,gBAAgB,IAAI,cAAc;IAIlC,UAAU,IAAI,QAAQ;IAItB,kBAAkB,IAAI,gBAAgB;IAItC,kBAAkB,IAAI,gBAAgB;IAItC,kBAAkB,IAAI,qBAAqB;IAI3C,YAAY,CACV,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,WAAW;IAId,KAAK,IAAI,IAAI;CAGd;AAED,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,WAAW,EACX,QAAQ,GACT,CAAC"}
@@ -0,0 +1,76 @@
1
+ export interface BaseAudioContext {
2
+ readonly destination: AudioDestinationNode;
3
+ readonly state: ContextState;
4
+ readonly sampleRate: number;
5
+ readonly currentTime: number;
6
+ createOscillator(): OscillatorNode;
7
+ createGain(): GainNode;
8
+ createStereoPanner(): StereoPannerNode;
9
+ createBiquadFilter: () => BiquadFilterNode;
10
+ createBufferSource: () => AudioBufferSourceNode;
11
+ createBuffer: (channels: number, length: number, sampleRate: number) => AudioBuffer;
12
+ close(): void;
13
+ }
14
+ type channelCountMode = 'max' | 'clamped-max' | 'explicit';
15
+ type channelInterpretation = 'speakers' | 'discrete';
16
+ export interface AudioNode {
17
+ readonly context: BaseAudioContext;
18
+ readonly numberOfInputs: number;
19
+ readonly numberOfOutputs: number;
20
+ readonly channelCount: number;
21
+ readonly channelCountMode: channelCountMode;
22
+ readonly channelInterpretation: channelInterpretation;
23
+ connect: (node: AudioNode) => void;
24
+ disconnect: (node: AudioNode) => void;
25
+ }
26
+ export interface AudioParam {
27
+ value: number;
28
+ defaultValue: number;
29
+ minValue: number;
30
+ maxValue: number;
31
+ setValueAtTime: (value: number, startTime: number) => void;
32
+ linearRampToValueAtTime: (value: number, endTime: number) => void;
33
+ exponentialRampToValueAtTime: (value: number, endTime: number) => void;
34
+ }
35
+ export interface AudioDestinationNode extends AudioNode {
36
+ }
37
+ export interface AudioScheduledSourceNode extends AudioNode {
38
+ start: (time: number) => void;
39
+ stop: (time: number) => void;
40
+ }
41
+ export type WaveType = 'sine' | 'square' | 'sawtooth' | 'triangle';
42
+ export interface OscillatorNode extends AudioScheduledSourceNode {
43
+ frequency: AudioParam;
44
+ type: WaveType;
45
+ detune: AudioParam;
46
+ }
47
+ export interface GainNode extends AudioNode {
48
+ gain: AudioParam;
49
+ }
50
+ export interface StereoPannerNode extends AudioNode {
51
+ pan: AudioParam;
52
+ }
53
+ type FilterType = 'lowpass' | 'highpass' | 'bandpass' | 'lowshelf' | 'highshelf' | 'peaking' | 'notch' | 'allpass';
54
+ export interface BiquadFilterNode extends AudioNode {
55
+ frequency: AudioParam;
56
+ detune: AudioParam;
57
+ Q: AudioParam;
58
+ gain: AudioParam;
59
+ type: FilterType;
60
+ }
61
+ export type ContextState = 'running' | 'closed' | 'suspended';
62
+ export interface AudioBuffer {
63
+ readonly length: number;
64
+ readonly duration: number;
65
+ readonly sampleRate: number;
66
+ readonly numberOfChannels: number;
67
+ getChannelData(channel: number): number[];
68
+ copyFromChannel(destination: number[], channelNumber: number, startInChannel: number): void;
69
+ copyToChannel(source: number[], channelNumber: number, startInChannel: number): void;
70
+ }
71
+ export interface AudioBufferSourceNode extends AudioScheduledSourceNode {
72
+ buffer: AudioBuffer;
73
+ loop: boolean;
74
+ }
75
+ export {};
76
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { TurboModule } from 'react-native';
2
+ interface AudioAPIModuleSpec extends TurboModule {
3
+ install(): boolean;
4
+ }
5
+ export declare function installModule(): AudioAPIModuleSpec;
6
+ export {};
7
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/utils/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhE,UAAU,kBAAmB,SAAQ,WAAW;IAC9C,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,wBAAgB,aAAa,uBAc5B"}
package/package.json CHANGED
@@ -1,11 +1,110 @@
1
1
  {
2
2
  "name": "react-native-audio-api",
3
- "version": "0.0.1",
4
- "description": "react-native-audio-api provides system for controlling audio in react-native environment compatible with Web Audio API specification",
5
- "main": "index.js",
3
+ "version": "0.1.0",
4
+ "description": "react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification",
5
+ "main": "lib/commonjs/index",
6
+ "module": "lib/module/index",
7
+ "react-native": "src/index",
8
+ "source": "src/index",
9
+ "types": "lib/typescript/index.d.ts",
10
+ "files": [
11
+ "src/",
12
+ "lib/",
13
+ "common/",
14
+ "android",
15
+ "ios",
16
+ "cpp",
17
+ "*.podspec",
18
+ "!ios/build",
19
+ "!android/build",
20
+ "!android/gradle",
21
+ "!android/gradlew",
22
+ "!android/gradlew.bat",
23
+ "!android/local.properties",
24
+ "!**/__tests__",
25
+ "!**/__fixtures__",
26
+ "!**/__mocks__",
27
+ "!**/.*"
28
+ ],
6
29
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
30
+ "test": "jest",
31
+ "typecheck": "tsc --noEmit",
32
+ "lint": "yarn lint:js && yarn lint:cpp && yarn lint:kotlin",
33
+ "format": "yarn format:android && yarn format:ios && yarn format:common && yarn format:kotlin",
34
+ "lint:js": "eslint \"**/*.{js,ts,tsx}\"",
35
+ "lint:cpp": "./scripts/cpplint.sh",
36
+ "lint:kotlin": "ktlint 'android/src/main/java/**'",
37
+ "format:android": "find android/src/ -iname \"*.h\" -o -iname \"*.cpp\" | xargs clang-format -i",
38
+ "format:ios": "find ios/ -iname \"*.h\" -o -iname \"*.m\" -o -iname \"*.mm\" -o -iname \"*.cpp\" | xargs clang-format -i --Werror",
39
+ "format:common": "find common/cpp/ -iname \"*.h\" -o -iname \"*.cpp\" | xargs clang-format -i",
40
+ "format:kotlin": "ktlint -F 'android/src/main/java/**'",
41
+ "build": "bob build",
42
+ "prepack": "cp ../../README.md ./README.md",
43
+ "postpack": "rm ./README.md"
8
44
  },
45
+ "keywords": [
46
+ "react-native",
47
+ "audio",
48
+ "audio-api"
49
+ ],
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/software-mansion-labs/react-native-audio-api.git"
53
+ },
54
+ "author": "Software Mansion Labs (https://github.com/software-mansion-labs)",
9
55
  "license": "MIT",
10
- "readmeFilename": "README.md"
56
+ "bugs": {
57
+ "url": "https://github.com/software-mansion-labs/react-native-audio-api/issues"
58
+ },
59
+ "homepage": "https://github.com/software-mansion-labs/react-native-audio-api#readme",
60
+ "publishConfig": {
61
+ "registry": "https://registry.npmjs.org/"
62
+ },
63
+ "peerDependencies": {
64
+ "react": "*",
65
+ "react-native": "*"
66
+ },
67
+ "devDependencies": {
68
+ "@commitlint/config-conventional": "^17.0.2",
69
+ "@evilmartians/lefthook": "^1.5.0",
70
+ "@react-native/eslint-config": "^0.73.1",
71
+ "@types/jest": "^29.5.5",
72
+ "@types/react": "^18.2.44",
73
+ "commitlint": "^17.0.2",
74
+ "del-cli": "^5.1.0",
75
+ "eslint": "^8.51.0",
76
+ "eslint-config-prettier": "^9.0.0",
77
+ "eslint-plugin-prettier": "^5.0.1",
78
+ "eslint-plugin-react": "^7.34.3",
79
+ "jest": "^29.7.0",
80
+ "prettier": "^3.0.3",
81
+ "react": "18.2.0",
82
+ "react-native": "0.74.3",
83
+ "react-native-builder-bob": "^0.24.0",
84
+ "turbo": "^1.10.7",
85
+ "typescript": "^5.2.2"
86
+ },
87
+ "react-native-builder-bob": {
88
+ "source": "src",
89
+ "output": "lib",
90
+ "targets": [
91
+ [
92
+ "module",
93
+ {
94
+ "esm": true
95
+ }
96
+ ],
97
+ "typescript"
98
+ ]
99
+ },
100
+ "codegenConfig": {
101
+ "name": "RNAudioAPISpec",
102
+ "type": "modules",
103
+ "jsSrcsDir": "src"
104
+ },
105
+ "create-react-native-library": {
106
+ "type": "module-legacy",
107
+ "languages": "cpp",
108
+ "version": "0.37.1"
109
+ }
11
110
  }
package/src/index.ts ADDED
@@ -0,0 +1,79 @@
1
+ import type {
2
+ BaseAudioContext,
3
+ AudioDestinationNode,
4
+ GainNode,
5
+ StereoPannerNode,
6
+ OscillatorNode,
7
+ BiquadFilterNode,
8
+ AudioBufferSourceNode,
9
+ AudioBuffer,
10
+ WaveType,
11
+ } from './types';
12
+ import { installModule } from './utils/install';
13
+
14
+ if (global.__AudioAPIInstaller == null) {
15
+ installModule();
16
+ }
17
+
18
+ export class AudioContext implements BaseAudioContext {
19
+ readonly destination: AudioDestinationNode;
20
+ readonly sampleRate: number;
21
+ private readonly __AudioContext: BaseAudioContext;
22
+
23
+ constructor() {
24
+ this.__AudioContext = global.__AudioAPIInstaller.createAudioContext();
25
+
26
+ this.destination = this.__AudioContext.destination;
27
+ this.sampleRate = this.__AudioContext.sampleRate;
28
+ }
29
+
30
+ public get currentTime() {
31
+ return this.__AudioContext.currentTime;
32
+ }
33
+
34
+ public get state() {
35
+ return this.__AudioContext.state;
36
+ }
37
+
38
+ createOscillator(): OscillatorNode {
39
+ return this.__AudioContext.createOscillator();
40
+ }
41
+
42
+ createGain(): GainNode {
43
+ return this.__AudioContext.createGain();
44
+ }
45
+
46
+ createStereoPanner(): StereoPannerNode {
47
+ return this.__AudioContext.createStereoPanner();
48
+ }
49
+
50
+ createBiquadFilter(): BiquadFilterNode {
51
+ return this.__AudioContext.createBiquadFilter();
52
+ }
53
+
54
+ createBufferSource(): AudioBufferSourceNode {
55
+ return this.__AudioContext.createBufferSource();
56
+ }
57
+
58
+ createBuffer(
59
+ numOfChannels: number,
60
+ length: number,
61
+ sampleRate: number
62
+ ): AudioBuffer {
63
+ return this.__AudioContext.createBuffer(numOfChannels, length, sampleRate);
64
+ }
65
+
66
+ close(): void {
67
+ this.__AudioContext.close();
68
+ }
69
+ }
70
+
71
+ export type {
72
+ GainNode,
73
+ StereoPannerNode,
74
+ OscillatorNode,
75
+ BiquadFilterNode,
76
+ AudioBufferSourceNode,
77
+ AudioBuffer,
78
+ WaveType,
79
+ };
@@ -0,0 +1,10 @@
1
+ import type { BaseAudioContext } from '../types';
2
+
3
+ type AudioAPIInstaller = {
4
+ createAudioContext: () => BaseAudioContext;
5
+ };
6
+
7
+ declare global {
8
+ function nativeCallSyncHook(): unknown;
9
+ var __AudioAPIInstaller: AudioAPI;
10
+ }