react-native-audio-api 0.6.0-rc.5 → 0.6.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 (201) hide show
  1. package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +35 -2
  2. package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +4 -0
  3. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +31 -17
  4. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +1 -3
  5. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +56 -2
  6. package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +0 -12
  7. package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +35 -12
  8. package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +30 -29
  9. package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +20 -22
  10. package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +19 -9
  11. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +30 -11
  12. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +34 -27
  13. package/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt +10 -5
  14. package/android/src/oldarch/NativeAudioAPIModuleSpec.java +39 -0
  15. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +20 -14
  16. package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +2 -3
  17. package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +24 -11
  18. package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +1 -0
  19. package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +10 -89
  20. package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +3 -24
  21. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +2 -2
  22. package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +2 -3
  23. package/common/cpp/audioapi/core/AudioContext.cpp +4 -1
  24. package/common/cpp/audioapi/core/AudioContext.h +1 -1
  25. package/common/cpp/audioapi/core/AudioNode.cpp +31 -2
  26. package/common/cpp/audioapi/core/AudioNode.h +7 -1
  27. package/common/cpp/audioapi/core/AudioParam.cpp +84 -2
  28. package/common/cpp/audioapi/core/AudioParam.h +14 -1
  29. package/common/cpp/audioapi/core/BaseAudioContext.cpp +6 -1
  30. package/common/cpp/audioapi/core/BaseAudioContext.h +7 -1
  31. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +3 -2
  32. package/common/cpp/audioapi/core/OfflineAudioContext.h +1 -1
  33. package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +28 -26
  34. package/common/cpp/audioapi/core/effects/GainNode.cpp +9 -9
  35. package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +5 -2
  36. package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +56 -0
  37. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +13 -13
  38. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +14 -10
  39. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +1 -1
  40. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +7 -6
  41. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +5 -3
  42. package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +15 -10
  43. package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +35 -1
  44. package/common/cpp/audioapi/core/utils/AudioNodeManager.h +15 -1
  45. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +108 -0
  46. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +62 -0
  47. package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +48 -0
  48. package/common/cpp/audioapi/jsi/JsiPromise.cpp +3 -4
  49. package/ios/audioapi/ios/AudioAPIModule.h +13 -0
  50. package/ios/audioapi/ios/AudioAPIModule.mm +115 -6
  51. package/ios/audioapi/ios/core/IOSAudioRecorder.h +2 -10
  52. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +6 -17
  53. package/ios/audioapi/ios/core/NativeAudioPlayer.m +2 -0
  54. package/ios/audioapi/ios/core/NativeAudioRecorder.m +7 -3
  55. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +7 -0
  56. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +12 -0
  57. package/ios/audioapi/ios/system/AudioEngine.h +5 -0
  58. package/ios/audioapi/ios/system/AudioEngine.mm +7 -15
  59. package/ios/audioapi/ios/system/AudioSessionManager.h +1 -1
  60. package/ios/audioapi/ios/system/AudioSessionManager.mm +2 -18
  61. package/ios/audioapi/ios/system/LockScreenManager.h +3 -3
  62. package/ios/audioapi/ios/system/LockScreenManager.mm +36 -48
  63. package/ios/audioapi/ios/system/NotificationManager.h +3 -3
  64. package/ios/audioapi/ios/system/NotificationManager.mm +21 -29
  65. package/lib/commonjs/api.js +4 -4
  66. package/lib/commonjs/api.js.map +1 -1
  67. package/lib/commonjs/core/AudioBufferSourceNode.js +2 -2
  68. package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
  69. package/lib/commonjs/core/AudioNode.js +8 -2
  70. package/lib/commonjs/core/AudioNode.js.map +1 -1
  71. package/lib/commonjs/core/AudioParam.js +2 -1
  72. package/lib/commonjs/core/AudioParam.js.map +1 -1
  73. package/lib/commonjs/core/AudioRecorder.js +11 -28
  74. package/lib/commonjs/core/AudioRecorder.js.map +1 -1
  75. package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -1
  76. package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
  77. package/lib/commonjs/core/BiquadFilterNode.js +4 -4
  78. package/lib/commonjs/core/BiquadFilterNode.js.map +1 -1
  79. package/lib/commonjs/core/GainNode.js +1 -1
  80. package/lib/commonjs/core/GainNode.js.map +1 -1
  81. package/lib/commonjs/core/OscillatorNode.js +2 -2
  82. package/lib/commonjs/core/OscillatorNode.js.map +1 -1
  83. package/lib/commonjs/core/StereoPannerNode.js +1 -1
  84. package/lib/commonjs/core/StereoPannerNode.js.map +1 -1
  85. package/lib/commonjs/events/AudioEventEmitter.js +22 -0
  86. package/lib/commonjs/events/AudioEventEmitter.js.map +1 -0
  87. package/lib/commonjs/events/AudioEventSubscription.js +20 -0
  88. package/lib/commonjs/events/AudioEventSubscription.js.map +1 -0
  89. package/lib/commonjs/events/index.js +21 -0
  90. package/lib/commonjs/events/index.js.map +1 -0
  91. package/lib/commonjs/events/types.js +6 -0
  92. package/lib/commonjs/events/types.js.map +1 -0
  93. package/lib/commonjs/hooks/useSytemVolume.js +1 -1
  94. package/lib/commonjs/hooks/useSytemVolume.js.map +1 -1
  95. package/lib/commonjs/specs/NativeAudioAPIModule.js +3 -3
  96. package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
  97. package/lib/commonjs/specs/index.js +2 -16
  98. package/lib/commonjs/specs/index.js.map +1 -1
  99. package/lib/commonjs/system/AudioManager.js +22 -28
  100. package/lib/commonjs/system/AudioManager.js.map +1 -1
  101. package/lib/module/api.js +2 -2
  102. package/lib/module/api.js.map +1 -1
  103. package/lib/module/core/AudioBufferSourceNode.js +2 -2
  104. package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
  105. package/lib/module/core/AudioNode.js +7 -2
  106. package/lib/module/core/AudioNode.js.map +1 -1
  107. package/lib/module/core/AudioParam.js +2 -1
  108. package/lib/module/core/AudioParam.js.map +1 -1
  109. package/lib/module/core/AudioRecorder.js +11 -28
  110. package/lib/module/core/AudioRecorder.js.map +1 -1
  111. package/lib/module/core/AudioScheduledSourceNode.js +4 -1
  112. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
  113. package/lib/module/core/BiquadFilterNode.js +4 -4
  114. package/lib/module/core/BiquadFilterNode.js.map +1 -1
  115. package/lib/module/core/GainNode.js +1 -1
  116. package/lib/module/core/GainNode.js.map +1 -1
  117. package/lib/module/core/OscillatorNode.js +2 -2
  118. package/lib/module/core/OscillatorNode.js.map +1 -1
  119. package/lib/module/core/StereoPannerNode.js +1 -1
  120. package/lib/module/core/StereoPannerNode.js.map +1 -1
  121. package/lib/module/events/AudioEventEmitter.js +16 -0
  122. package/lib/module/events/AudioEventEmitter.js.map +1 -0
  123. package/lib/module/events/AudioEventSubscription.js +15 -0
  124. package/lib/module/events/AudioEventSubscription.js.map +1 -0
  125. package/lib/module/events/index.js +6 -0
  126. package/lib/module/events/index.js.map +1 -0
  127. package/lib/module/events/types.js +4 -0
  128. package/lib/module/events/types.js.map +1 -0
  129. package/lib/module/hooks/useSytemVolume.js +1 -1
  130. package/lib/module/hooks/useSytemVolume.js.map +1 -1
  131. package/lib/module/specs/NativeAudioAPIModule.js +3 -2
  132. package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
  133. package/lib/module/specs/index.js +2 -3
  134. package/lib/module/specs/index.js.map +1 -1
  135. package/lib/module/system/AudioManager.js +23 -29
  136. package/lib/module/system/AudioManager.js.map +1 -1
  137. package/lib/typescript/api.d.ts +2 -1
  138. package/lib/typescript/api.d.ts.map +1 -1
  139. package/lib/typescript/core/AudioNode.d.ts +2 -1
  140. package/lib/typescript/core/AudioNode.d.ts.map +1 -1
  141. package/lib/typescript/core/AudioParam.d.ts +4 -2
  142. package/lib/typescript/core/AudioParam.d.ts.map +1 -1
  143. package/lib/typescript/core/AudioRecorder.d.ts +4 -14
  144. package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
  145. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +3 -1
  146. package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
  147. package/lib/typescript/events/AudioEventEmitter.d.ts +10 -0
  148. package/lib/typescript/events/AudioEventEmitter.d.ts.map +1 -0
  149. package/lib/typescript/events/AudioEventSubscription.d.ts +11 -0
  150. package/lib/typescript/events/AudioEventSubscription.d.ts.map +1 -0
  151. package/lib/typescript/events/index.d.ts +4 -0
  152. package/lib/typescript/events/index.d.ts.map +1 -0
  153. package/lib/typescript/events/types.d.ts +50 -0
  154. package/lib/typescript/events/types.d.ts.map +1 -0
  155. package/lib/typescript/hooks/useSytemVolume.d.ts.map +1 -1
  156. package/lib/typescript/interfaces.d.ts +10 -10
  157. package/lib/typescript/interfaces.d.ts.map +1 -1
  158. package/lib/typescript/specs/NativeAudioAPIModule.d.ts +15 -3
  159. package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
  160. package/lib/typescript/specs/index.d.ts +2 -3
  161. package/lib/typescript/specs/index.d.ts.map +1 -1
  162. package/lib/typescript/system/AudioManager.d.ts +6 -4
  163. package/lib/typescript/system/AudioManager.d.ts.map +1 -1
  164. package/lib/typescript/system/types.d.ts +0 -34
  165. package/lib/typescript/system/types.d.ts.map +1 -1
  166. package/lib/typescript/types.d.ts +0 -1
  167. package/lib/typescript/types.d.ts.map +1 -1
  168. package/package.json +3 -3
  169. package/src/api.ts +6 -3
  170. package/src/core/AudioBufferSourceNode.ts +2 -2
  171. package/src/core/AudioNode.ts +8 -3
  172. package/src/core/AudioParam.ts +5 -2
  173. package/src/core/AudioRecorder.ts +22 -62
  174. package/src/core/AudioScheduledSourceNode.ts +13 -2
  175. package/src/core/BiquadFilterNode.ts +4 -4
  176. package/src/core/GainNode.ts +1 -1
  177. package/src/core/OscillatorNode.ts +2 -2
  178. package/src/core/StereoPannerNode.ts +1 -1
  179. package/src/events/AudioEventEmitter.ts +29 -0
  180. package/src/events/AudioEventSubscription.ts +26 -0
  181. package/src/events/index.ts +4 -0
  182. package/src/events/types.ts +64 -0
  183. package/src/hooks/useSytemVolume.ts +2 -1
  184. package/src/interfaces.ts +19 -20
  185. package/src/specs/NativeAudioAPIModule.ts +23 -2
  186. package/src/specs/index.ts +2 -4
  187. package/src/system/AudioManager.ts +35 -43
  188. package/src/system/types.ts +0 -42
  189. package/src/types.ts +0 -8
  190. package/android/src/main/java/com/swmansion/audioapi/AudioManagerModule.kt +0 -77
  191. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionEventEmitter.kt +0 -88
  192. package/android/src/oldarch/NativeAudioManagerModuleSpec.java +0 -99
  193. package/ios/audioapi/ios/AudioManagerModule.h +0 -18
  194. package/ios/audioapi/ios/AudioManagerModule.mm +0 -108
  195. package/lib/commonjs/specs/NativeAudioManagerModule.js +0 -42
  196. package/lib/commonjs/specs/NativeAudioManagerModule.js.map +0 -1
  197. package/lib/module/specs/NativeAudioManagerModule.js +0 -39
  198. package/lib/module/specs/NativeAudioManagerModule.js.map +0 -1
  199. package/lib/typescript/specs/NativeAudioManagerModule.d.ts +0 -18
  200. package/lib/typescript/specs/NativeAudioManagerModule.d.ts.map +0 -1
  201. package/src/specs/NativeAudioManagerModule.ts +0 -53
@@ -1,12 +1,16 @@
1
- #import "AudioAPIModule.h"
2
-
3
1
  #import <React/RCTBridge+Private.h>
4
-
2
+ #import <audioapi/ios/AudioAPIModule.h>
5
3
  #ifdef RCT_NEW_ARCH_ENABLED
6
4
  #import <React/RCTCallInvoker.h>
7
5
  #endif // RCT_NEW_ARCH_ENABLED
8
6
 
9
- #include <audioapi/AudioAPIModuleInstaller.h>
7
+ #import <audioapi/AudioAPIModuleInstaller.h>
8
+ #import <audioapi/ios/system/AudioEngine.h>
9
+ #import <audioapi/ios/system/AudioSessionManager.h>
10
+ #import <audioapi/ios/system/LockScreenManager.h>
11
+ #import <audioapi/ios/system/NotificationManager.h>
12
+
13
+ #import <audioapi/events/AudioEventHandlerRegistry.h>
10
14
 
11
15
  using namespace audioapi;
12
16
  using namespace facebook::react;
@@ -24,7 +28,9 @@ using namespace facebook::react;
24
28
  @end
25
29
  #endif // RCT_NEW_ARCH_ENABLED
26
30
 
27
- @implementation AudioAPIModule
31
+ @implementation AudioAPIModule {
32
+ std::shared_ptr<AudioEventHandlerRegistry> _eventHandler;
33
+ }
28
34
 
29
35
  #if defined(RCT_NEW_ARCH_ENABLED)
30
36
  @synthesize callInvoker = _callInvoker;
@@ -32,8 +38,25 @@ using namespace facebook::react;
32
38
 
33
39
  RCT_EXPORT_MODULE(AudioAPIModule);
34
40
 
41
+ - (void)invalidate
42
+ {
43
+ [self.audioEngine cleanup];
44
+ [self.notificationManager cleanup];
45
+ [self.audioSessionManager cleanup];
46
+ [self.lockScreenManager cleanup];
47
+
48
+ _eventHandler = nullptr;
49
+
50
+ [super invalidate];
51
+ }
52
+
35
53
  RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
36
54
  {
55
+ self.audioSessionManager = [[AudioSessionManager alloc] init];
56
+ self.audioEngine = [[AudioEngine alloc] initWithAudioSessionManager:self.audioSessionManager];
57
+ self.lockScreenManager = [[LockScreenManager alloc] initWithAudioAPIModule:self];
58
+ self.notificationManager = [[NotificationManager alloc] initWithAudioAPIModule:self];
59
+
37
60
  auto jsiRuntime = reinterpret_cast<facebook::jsi::Runtime *>(self.bridge.runtime);
38
61
 
39
62
  #if defined(RCT_NEW_ARCH_ENABLED)
@@ -44,12 +67,68 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
44
67
 
45
68
  assert(jsiRuntime != nullptr);
46
69
 
47
- audioapi::AudioAPIModuleInstaller::injectJSIBindings(jsiRuntime, jsCallInvoker);
70
+ _eventHandler = std::make_shared<AudioEventHandlerRegistry>(jsiRuntime, jsCallInvoker);
71
+
72
+ self.audioSessionManager = [[AudioSessionManager alloc] init];
73
+ self.audioEngine = [[AudioEngine alloc] initWithAudioSessionManager:self.audioSessionManager];
74
+ self.lockScreenManager = [[LockScreenManager alloc] initWithAudioAPIModule:self];
75
+ self.notificationManager = [[NotificationManager alloc] initWithAudioAPIModule:self];
76
+
77
+ audioapi::AudioAPIModuleInstaller::injectJSIBindings(jsiRuntime, jsCallInvoker, _eventHandler);
48
78
 
49
79
  NSLog(@"Successfully installed JSI bindings for react-native-audio-api!");
50
80
  return @true;
51
81
  }
52
82
 
83
+ RCT_EXPORT_METHOD(setLockScreenInfo : (NSDictionary *)info)
84
+ {
85
+ [self.lockScreenManager setLockScreenInfo:info];
86
+ }
87
+
88
+ RCT_EXPORT_METHOD(resetLockScreenInfo)
89
+ {
90
+ [self.lockScreenManager resetLockScreenInfo];
91
+ }
92
+
93
+ RCT_EXPORT_METHOD(enableRemoteCommand : (NSString *)name enabled : (BOOL)enabled)
94
+ {
95
+ [self.lockScreenManager enableRemoteCommand:name enabled:enabled];
96
+ }
97
+
98
+ RCT_EXPORT_METHOD(setAudioSessionOptions : (NSString *)category mode : (NSString *)mode options : (NSArray *)options)
99
+ {
100
+ [self.audioSessionManager setAudioSessionOptions:category mode:mode options:options];
101
+ }
102
+
103
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getDevicePreferredSampleRate)
104
+ {
105
+ return [self.audioSessionManager getDevicePreferredSampleRate];
106
+ }
107
+
108
+ RCT_EXPORT_METHOD(observeAudioInterruptions : (BOOL)enabled)
109
+ {
110
+ [self.notificationManager observeAudioInterruptions:enabled];
111
+ }
112
+
113
+ RCT_EXPORT_METHOD(observeVolumeChanges : (BOOL)enabled)
114
+ {
115
+ [self.notificationManager observeVolumeChanges:(BOOL)enabled];
116
+ }
117
+
118
+ RCT_EXPORT_METHOD(requestRecordingPermissions : (nonnull RCTPromiseResolveBlock)
119
+ resolve reject : (nonnull RCTPromiseRejectBlock)reject)
120
+ {
121
+ NSString *res = [self.audioSessionManager requestRecordingPermissions];
122
+ resolve(res);
123
+ }
124
+
125
+ RCT_EXPORT_METHOD(checkRecordingPermissions : (nonnull RCTPromiseResolveBlock)
126
+ resolve reject : (nonnull RCTPromiseRejectBlock)reject)
127
+ {
128
+ NSString *res = [self.audioSessionManager checkRecordingPermissions];
129
+ resolve(res);
130
+ }
131
+
53
132
  #ifdef RCT_NEW_ARCH_ENABLED
54
133
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
55
134
  (const facebook::react::ObjCTurboModule::InitParams &)params
@@ -58,4 +137,34 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
58
137
  }
59
138
  #endif // RCT_NEW_ARCH_ENABLED
60
139
 
140
+ - (void)invokeHandlerWithEventName:(NSString *)eventName eventBody:(NSDictionary *)eventBody
141
+ {
142
+ auto name = [eventName UTF8String];
143
+
144
+ std::unordered_map<std::string, EventValue> body = {};
145
+
146
+ for (NSString *key in eventBody) {
147
+ id value = eventBody[key];
148
+ std::string stdKey = [key UTF8String];
149
+
150
+ if ([value isKindOfClass:[NSString class]]) {
151
+ std::string stdValue = [value UTF8String];
152
+ body[stdKey] = EventValue(stdValue);
153
+ } else if ([value isKindOfClass:[NSNumber class]]) {
154
+ const char *type = [value objCType];
155
+ if (strcmp(type, @encode(int)) == 0) {
156
+ body[stdKey] = EventValue([value intValue]);
157
+ } else if (strcmp(type, @encode(double)) == 0) {
158
+ body[stdKey] = EventValue([value doubleValue]);
159
+ } else if (strcmp(type, @encode(float)) == 0) {
160
+ body[stdKey] = EventValue([value floatValue]);
161
+ } else if (strcmp(type, @encode(BOOL)) == 0) {
162
+ body[stdKey] = EventValue([value boolValue]);
163
+ }
164
+ }
165
+ }
166
+
167
+ _eventHandler->invokeHandlerWithEventBody(name, body);
168
+ }
169
+
61
170
  @end
@@ -7,7 +7,6 @@ typedef struct objc_object NativeAudioRecorder;
7
7
  #endif // __OBJC__
8
8
 
9
9
  #include <audioapi/core/inputs/AudioRecorder.h>
10
- #include <functional>
11
10
 
12
11
  namespace audioapi {
13
12
 
@@ -19,10 +18,8 @@ class IOSAudioRecorder : public AudioRecorder {
19
18
  IOSAudioRecorder(
20
19
  float sampleRate,
21
20
  int bufferLength,
22
- const std::function<void(void)> &onError,
23
- const std::function<void(void)> &onStatusChange,
24
- const std::function<void(std::shared_ptr<AudioBus>, int, double)>
25
- &onAudioReady);
21
+ const std::shared_ptr<AudioEventHandlerRegistry>
22
+ &audioEventHandlerRegistry);
26
23
 
27
24
  ~IOSAudioRecorder() override;
28
25
 
@@ -31,11 +28,6 @@ class IOSAudioRecorder : public AudioRecorder {
31
28
 
32
29
  private:
33
30
  NativeAudioRecorder *audioRecorder_;
34
- std::atomic<bool> isRunning_;
35
-
36
- std::shared_ptr<CircularAudioArray> circularBuffer_;
37
-
38
- void sendRemainingData();
39
31
  };
40
32
 
41
33
  } // namespace audioapi
@@ -2,23 +2,21 @@
2
2
 
3
3
  #include <audioapi/core/Constants.h>
4
4
  #include <audioapi/dsp/VectorMath.h>
5
+ #include <audioapi/events/AudioEventHandlerRegistry.h>
5
6
  #include <audioapi/ios/core/IOSAudioRecorder.h>
6
7
  #include <audioapi/utils/AudioArray.h>
7
8
  #include <audioapi/utils/AudioBus.h>
8
9
  #include <audioapi/utils/CircularAudioArray.h>
10
+ #include <unordered_map>
9
11
 
10
12
  namespace audioapi {
11
13
 
12
14
  IOSAudioRecorder::IOSAudioRecorder(
13
15
  float sampleRate,
14
16
  int bufferLength,
15
- const std::function<void(void)> &onError,
16
- const std::function<void(void)> &onStatusChange,
17
- const std::function<void(std::shared_ptr<AudioBus>, int, double)> &onAudioReady)
18
- : AudioRecorder(sampleRate, bufferLength, onError, onStatusChange, onAudioReady)
17
+ const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
18
+ : AudioRecorder(sampleRate, bufferLength, audioEventHandlerRegistry)
19
19
  {
20
- circularBuffer_ = std::make_shared<CircularAudioArray>(std::max(2 * bufferLength, 2048));
21
-
22
20
  AudioReceiverBlock audioReceiverBlock = ^(const AudioBufferList *inputBuffer, int numFrames, AVAudioTime *when) {
23
21
  if (isRunning_.load()) {
24
22
  auto *inputChannel = static_cast<float *>(inputBuffer->mBuffers[0].mData);
@@ -30,7 +28,8 @@ IOSAudioRecorder::IOSAudioRecorder(
30
28
  auto *outputChannel = bus->getChannel(0)->getData();
31
29
 
32
30
  circularBuffer_->pop_front(outputChannel, bufferLength_);
33
- onAudioReady_(bus, bufferLength_, [when sampleTime] / [when sampleRate]);
31
+
32
+ invokeOnAudioReadyCallback(bus, bufferLength_, [when sampleTime] / [when sampleRate]);
34
33
  }
35
34
  };
36
35
 
@@ -69,14 +68,4 @@ void IOSAudioRecorder::stop()
69
68
  sendRemainingData();
70
69
  }
71
70
 
72
- void IOSAudioRecorder::sendRemainingData()
73
- {
74
- auto bus = std::make_shared<AudioBus>(circularBuffer_->getNumberOfAvailableFrames(), 1, sampleRate_);
75
- auto *outputChannel = bus->getChannel(0)->getData();
76
- auto availableFrames = circularBuffer_->getNumberOfAvailableFrames();
77
-
78
- circularBuffer_->pop_front(outputChannel, circularBuffer_->getNumberOfAvailableFrames());
79
- onAudioReady_(bus, availableFrames, 0);
80
- }
81
-
82
71
  } // namespace audioapi
@@ -37,6 +37,7 @@
37
37
  NSLog(@"[AudioPlayer] start");
38
38
 
39
39
  AudioEngine *audioEngine = [AudioEngine sharedInstance];
40
+ assert(audioEngine != nil);
40
41
  self.sourceNodeId = [audioEngine attachSourceNode:self.sourceNode format:self.format];
41
42
  }
42
43
 
@@ -45,6 +46,7 @@
45
46
  NSLog(@"[AudioPlayer] stop");
46
47
 
47
48
  AudioEngine *audioEngine = [AudioEngine sharedInstance];
49
+ assert(audioEngine != nil);
48
50
  [audioEngine detachSourceNodeWithId:self.sourceNodeId];
49
51
  self.sourceNodeId = nil;
50
52
  }
@@ -14,7 +14,7 @@
14
14
 
15
15
  self.receiverBlock = [receiverBlock copy];
16
16
 
17
- float devicePrefferedSampleRate = [[[AudioSessionManager sharedInstance] getDevicePreferredSampleRate] floatValue];
17
+ float devicePrefferedSampleRate = [[AVAudioSession sharedInstance] sampleRate];
18
18
 
19
19
  self.inputFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32
20
20
  sampleRate:devicePrefferedSampleRate
@@ -91,12 +91,16 @@
91
91
 
92
92
  - (void)start
93
93
  {
94
- [[AudioEngine sharedInstance] attachInputNode:self.sinkNode];
94
+ AudioEngine *audioEngine = [AudioEngine sharedInstance];
95
+ assert(audioEngine != nil);
96
+ [audioEngine attachInputNode:self.sinkNode];
95
97
  }
96
98
 
97
99
  - (void)stop
98
100
  {
99
- [[AudioEngine sharedInstance] detachInputNode];
101
+ AudioEngine *audioEngine = [AudioEngine sharedInstance];
102
+ assert(audioEngine != nil);
103
+ [audioEngine detachInputNode];
100
104
  }
101
105
 
102
106
  - (void)cleanup
@@ -0,0 +1,7 @@
1
+ #pragma once
2
+
3
+ #import <Foundation/Foundation.h>
4
+
5
+ @interface IOSAudioEventHandlerRegistry : NSObject
6
+
7
+ -
@@ -0,0 +1,12 @@
1
+ // #import <audioapi/ios/events/IOSAudioEventHandlerRegistry.h>
2
+ //
3
+ // #include <memory>
4
+ // #include
5
+ //
6
+ //@implementation IOSAudioEventHandlerRegistry {
7
+ // std::shared_ptr<AudioEventHandlerRegistry> _eventHandler;
8
+ //
9
+ //
10
+ // }
11
+ //
12
+ //@end
@@ -3,12 +3,17 @@
3
3
  #import <AVFoundation/AVFoundation.h>
4
4
  #import <Foundation/Foundation.h>
5
5
 
6
+ @class AudioSessionManager;
7
+
6
8
  @interface AudioEngine : NSObject
7
9
 
8
10
  @property (nonatomic, strong) AVAudioEngine *audioEngine;
9
11
  @property (nonatomic, strong) NSMutableDictionary *sourceNodes;
10
12
  @property (nonatomic, strong) NSMutableDictionary *sourceFormats;
11
13
  @property (nonatomic, strong) AVAudioSinkNode *inputNode;
14
+ @property (nonatomic, weak) AudioSessionManager *sessionManager;
15
+
16
+ - (instancetype)initWithAudioSessionManager:(AudioSessionManager *)sessionManager;
12
17
 
13
18
  + (instancetype)sharedInstance;
14
19
  - (void)cleanup;
@@ -7,22 +7,10 @@ static AudioEngine *_sharedInstance = nil;
7
7
 
8
8
  + (instancetype)sharedInstance
9
9
  {
10
- static dispatch_once_t onceToken;
11
-
12
- dispatch_once(&onceToken, ^{
13
- _sharedInstance = [[self alloc] initPrivate];
14
- });
15
-
16
10
  return _sharedInstance;
17
11
  }
18
12
 
19
- - (instancetype)init
20
- {
21
- @throw [NSException exceptionWithName:@"Singleton" reason:@"Use +[AudioEngine sharedInstance]" userInfo:nil];
22
- return nil;
23
- }
24
-
25
- - (instancetype)initPrivate
13
+ - (instancetype)initWithAudioSessionManager:(AudioSessionManager *)sessionManager
26
14
  {
27
15
  if (self = [super init]) {
28
16
  self.audioEngine = [[AVAudioEngine alloc] init];
@@ -31,9 +19,12 @@ static AudioEngine *_sharedInstance = nil;
31
19
  self.sourceNodes = [[NSMutableDictionary alloc] init];
32
20
  self.sourceFormats = [[NSMutableDictionary alloc] init];
33
21
 
34
- [[AudioSessionManager sharedInstance] setActive:true];
22
+ self.sessionManager = sessionManager;
23
+ [self.sessionManager setActive:true];
35
24
  }
36
25
 
26
+ _sharedInstance = self;
27
+
37
28
  return self;
38
29
  }
39
30
 
@@ -49,7 +40,8 @@ static AudioEngine *_sharedInstance = nil;
49
40
  self.sourceFormats = nil;
50
41
  self.inputNode = nil;
51
42
 
52
- [[AudioSessionManager sharedInstance] setActive:false];
43
+ [self.sessionManager setActive:false];
44
+ self.sessionManager = nil;
53
45
  }
54
46
 
55
47
  - (bool)rebuildAudioEngine
@@ -13,7 +13,7 @@
13
13
  @property (nonatomic, assign) AVAudioSessionCategory sessionCategory;
14
14
  @property (nonatomic, assign) AVAudioSessionCategoryOptions sessionOptions;
15
15
 
16
- + (instancetype)sharedInstance;
16
+ - (instancetype)init;
17
17
  - (void)cleanup;
18
18
  - (bool)configureAudioSession;
19
19
 
@@ -2,24 +2,7 @@
2
2
 
3
3
  @implementation AudioSessionManager
4
4
 
5
- static AudioSessionManager *_sharedInstance = nil;
6
-
7
- + (instancetype)sharedInstance
8
- {
9
- static dispatch_once_t onceToken;
10
- dispatch_once(&onceToken, ^{
11
- _sharedInstance = [[self alloc] initPrivate];
12
- });
13
- return _sharedInstance;
14
- }
15
-
16
5
  - (instancetype)init
17
- {
18
- @throw [NSException exceptionWithName:@"Singleton" reason:@"Use +[AudioSessionManager sharedInstance]" userInfo:nil];
19
- return nil;
20
- }
21
-
22
- - (instancetype)initPrivate
23
6
  {
24
7
  if (self = [super init]) {
25
8
  self.audioSession = [AVAudioSession sharedInstance];
@@ -194,7 +177,8 @@ static AudioSessionManager *_sharedInstance = nil;
194
177
 
195
178
  - (NSString *)requestRecordingPermissions
196
179
  {
197
- [self.audioSession requestRecordPermission:^(BOOL granted) {}];
180
+ [self.audioSession requestRecordPermission:^(BOOL granted){
181
+ }];
198
182
  return [self checkRecordingPermissions];
199
183
  }
200
184
 
@@ -4,16 +4,16 @@
4
4
  #import <Foundation/Foundation.h>
5
5
  #import <MediaPlayer/MediaPlayer.h>
6
6
 
7
- @class AudioManagerModule;
7
+ @class AudioAPIModule;
8
8
 
9
9
  @interface LockScreenManager : NSObject
10
10
 
11
- @property (nonatomic, weak) AudioManagerModule *audioManagerModule;
11
+ @property (nonatomic, weak) AudioAPIModule *audioAPIModule;
12
12
 
13
13
  @property (nonatomic, weak) MPNowPlayingInfoCenter *playingInfoCenter;
14
14
  @property (nonatomic, copy) NSString *artworkUrl;
15
15
 
16
- + (instancetype)sharedInstanceWithAudioManagerModule:(AudioManagerModule *)audioManagerModule;
16
+ - (instancetype)initWithAudioAPIModule:(AudioAPIModule *)audioAPIModule;
17
17
  - (void)cleanup;
18
18
 
19
19
  - (void)setLockScreenInfo:(NSDictionary *)info;
@@ -1,5 +1,5 @@
1
1
  #import <MediaPlayer/MediaPlayer.h>
2
- #import <audioapi/ios/AudioManagerModule.h>
2
+ #import <audioapi/ios/AudioAPIModule.h>
3
3
  #import <audioapi/ios/system/LockScreenManager.h>
4
4
 
5
5
  #define LOCK_SCREEN_INFO \
@@ -14,30 +14,14 @@
14
14
 
15
15
  @implementation LockScreenManager
16
16
 
17
- static LockScreenManager *_sharedInstance = nil;
18
-
19
- + (instancetype)sharedInstanceWithAudioManagerModule:(AudioManagerModule *)audioManagerModule
20
- {
21
- static dispatch_once_t onceToken;
22
- dispatch_once(&onceToken, ^{
23
- _sharedInstance = [[self alloc] initPrivateWithAudioManagerModule:audioManagerModule];
24
- });
25
- return _sharedInstance;
26
- }
27
-
28
- - (instancetype)init
29
- {
30
- @throw [NSException exceptionWithName:@"Singleton" reason:@"Use +[LockScreenManager sharedInstance]" userInfo:nil];
31
- return nil;
32
- }
33
-
34
- - (instancetype)initPrivateWithAudioManagerModule:(AudioManagerModule *)audioManagerModule
17
+ - (instancetype)initWithAudioAPIModule:(AudioAPIModule *)audioAPIModule
35
18
  {
36
19
  if (self = [super init]) {
37
- self.audioManagerModule = audioManagerModule;
20
+ self.audioAPIModule = audioAPIModule;
38
21
  self.playingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
39
22
  [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
40
23
  }
24
+
41
25
  return self;
42
26
  }
43
27
 
@@ -176,31 +160,31 @@ static LockScreenManager *_sharedInstance = nil;
176
160
  {
177
161
  MPRemoteCommandCenter *remoteCenter = [MPRemoteCommandCenter sharedCommandCenter];
178
162
 
179
- if ([name isEqual:@"play"]) {
163
+ if ([name isEqual:@"remotePlay"]) {
180
164
  [self enableCommand:remoteCenter.playCommand withSelector:@selector(onPlay:) enabled:enabled];
181
- } else if ([name isEqual:@"pause"]) {
165
+ } else if ([name isEqual:@"remotePause"]) {
182
166
  [self enableCommand:remoteCenter.pauseCommand withSelector:@selector(onPause:) enabled:enabled];
183
- } else if ([name isEqual:@"stop"]) {
167
+ } else if ([name isEqual:@"remoteStop"]) {
184
168
  [self enableCommand:remoteCenter.stopCommand withSelector:@selector(onStop:) enabled:enabled];
185
- } else if ([name isEqual:@"togglePlayPause"]) {
169
+ } else if ([name isEqual:@"remoteTogglePlayPause"]) {
186
170
  [self enableCommand:remoteCenter.togglePlayPauseCommand withSelector:@selector(onTogglePlayPause:) enabled:enabled];
187
- } else if ([name isEqual:@"changePlaybackRate"]) {
171
+ } else if ([name isEqual:@"remoteChangePlaybackRate"]) {
188
172
  [self enableCommand:remoteCenter.changePlaybackRateCommand
189
173
  withSelector:@selector(onChangePlaybackRate:)
190
174
  enabled:enabled];
191
- } else if ([name isEqual:@"nextTrack"]) {
175
+ } else if ([name isEqual:@"remoteNextTrack"]) {
192
176
  [self enableCommand:remoteCenter.nextTrackCommand withSelector:@selector(onNextTrack:) enabled:enabled];
193
- } else if ([name isEqual:@"previousTrack"]) {
177
+ } else if ([name isEqual:@"remotePreviousTrack"]) {
194
178
  [self enableCommand:remoteCenter.previousTrackCommand withSelector:@selector(onPreviousTrack:) enabled:enabled];
195
- } else if ([name isEqual:@"skipForward"]) {
179
+ } else if ([name isEqual:@"remoteSkipForward"]) {
196
180
  [self enableCommand:remoteCenter.skipForwardCommand withSelector:@selector(onSkipForward:) enabled:enabled];
197
- } else if ([name isEqual:@"skipBackward"]) {
181
+ } else if ([name isEqual:@"remoteSkipBackward"]) {
198
182
  [self enableCommand:remoteCenter.skipBackwardCommand withSelector:@selector(onSkipBackward:) enabled:enabled];
199
- } else if ([name isEqual:@"seekForward"]) {
183
+ } else if ([name isEqual:@"remoteSeekForward"]) {
200
184
  [self enableCommand:remoteCenter.seekForwardCommand withSelector:@selector(onSeekForward:) enabled:enabled];
201
- } else if ([name isEqual:@"seekBackward"]) {
185
+ } else if ([name isEqual:@"remoteSeekBackward"]) {
202
186
  [self enableCommand:remoteCenter.seekBackwardCommand withSelector:@selector(onSeekBackward:) enabled:enabled];
203
- } else if ([name isEqual:@"changePlaybackPosition"]) {
187
+ } else if ([name isEqual:@"remoteChangePlaybackPosition"]) {
204
188
  [self enableCommand:remoteCenter.changePlaybackPositionCommand
205
189
  withSelector:@selector(onChangePlaybackPosition:)
206
190
  enabled:enabled];
@@ -218,77 +202,81 @@ static LockScreenManager *_sharedInstance = nil;
218
202
 
219
203
  - (MPRemoteCommandHandlerStatus)onPlay:(MPRemoteCommandEvent *)event
220
204
  {
221
- [self.audioManagerModule sendEventWithName:@"onRemotePlay" body:@{}];
205
+ [self.audioAPIModule invokeHandlerWithEventName:@"remotePlay" eventBody:nil];
222
206
  return MPRemoteCommandHandlerStatusSuccess;
223
207
  }
224
208
 
225
209
  - (MPRemoteCommandHandlerStatus)onPause:(MPRemoteCommandEvent *)event
226
210
  {
227
- [self.audioManagerModule sendEventWithName:@"onRemotePause" body:@{}];
211
+ [self.audioAPIModule invokeHandlerWithEventName:@"remotePause" eventBody:nil];
228
212
  return MPRemoteCommandHandlerStatusSuccess;
229
213
  }
230
214
 
231
215
  - (MPRemoteCommandHandlerStatus)onStop:(MPRemoteCommandEvent *)event
232
216
  {
233
- [self.audioManagerModule sendEventWithName:@"onRemoteStop" body:@{}];
217
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteStop" eventBody:nil];
234
218
  return MPRemoteCommandHandlerStatusSuccess;
235
219
  }
236
220
 
237
221
  - (MPRemoteCommandHandlerStatus)onTogglePlayPause:(MPRemoteCommandEvent *)event
238
222
  {
239
- [self.audioManagerModule sendEventWithName:@"onRemoteTogglePlayPause" body:@{}];
223
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteTogglePlayPause" eventBody:nil];
240
224
  return MPRemoteCommandHandlerStatusSuccess;
241
225
  }
242
226
 
243
227
  - (MPRemoteCommandHandlerStatus)onChangePlaybackRate:(MPChangePlaybackRateCommandEvent *)event
244
228
  {
245
- [self.audioManagerModule sendEventWithName:@"onRemoteChangePlaybackRate"
246
- body:@{@"value" : [NSNumber numberWithDouble:event.playbackRate]}];
229
+ NSDictionary *body = @{@"value" : [NSNumber numberWithDouble:event.playbackRate]};
230
+
231
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteChangePlaybackRate" eventBody:body];
247
232
  return MPRemoteCommandHandlerStatusSuccess;
248
233
  }
249
234
 
250
235
  - (MPRemoteCommandHandlerStatus)onNextTrack:(MPRemoteCommandEvent *)event
251
236
  {
252
- [self.audioManagerModule sendEventWithName:@"onRemoteNextTrack" body:@{}];
237
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteNextTrack" eventBody:nil];
253
238
  return MPRemoteCommandHandlerStatusSuccess;
254
239
  }
255
240
 
256
241
  - (MPRemoteCommandHandlerStatus)onPreviousTrack:(MPRemoteCommandEvent *)event
257
242
  {
258
- [self.audioManagerModule sendEventWithName:@"onRemotePreviousTrack" body:@{}];
243
+ [self.audioAPIModule invokeHandlerWithEventName:@"remotePreviousTrack" eventBody:nil];
259
244
  return MPRemoteCommandHandlerStatusSuccess;
260
245
  }
261
246
 
262
247
  - (MPRemoteCommandHandlerStatus)onSeekForward:(MPRemoteCommandEvent *)event
263
248
  {
264
- [self.audioManagerModule sendEventWithName:@"onRemoteSeekForward" body:nil];
249
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteSeekForward" eventBody:nil];
265
250
  return MPRemoteCommandHandlerStatusSuccess;
266
251
  }
267
252
 
268
253
  - (MPRemoteCommandHandlerStatus)onSeekBackward:(MPRemoteCommandEvent *)event
269
254
  {
270
- [self.audioManagerModule sendEventWithName:@"onRemoteSeekBackward" body:@{}];
255
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteSeekBackward" eventBody:nil];
271
256
  return MPRemoteCommandHandlerStatusSuccess;
272
257
  }
273
258
 
274
259
  - (MPRemoteCommandHandlerStatus)onSkipForward:(MPSkipIntervalCommandEvent *)event
275
260
  {
276
- [self.audioManagerModule sendEventWithName:@"onRemoteSkipForward"
277
- body:@{@"value" : [NSNumber numberWithDouble:event.interval]}];
261
+ NSDictionary *body = @{@"value" : [NSNumber numberWithDouble:event.interval]};
262
+
263
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteSkipForward" eventBody:body];
278
264
  return MPRemoteCommandHandlerStatusSuccess;
279
265
  }
280
266
 
281
267
  - (MPRemoteCommandHandlerStatus)onSkipBackward:(MPSkipIntervalCommandEvent *)event
282
268
  {
283
- [self.audioManagerModule sendEventWithName:@"onRemoteSkipBackward"
284
- body:@{@"value" : [NSNumber numberWithDouble:event.interval]}];
269
+ NSDictionary *body = @{@"value" : [NSNumber numberWithDouble:event.interval]};
270
+
271
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteSkipBackward" eventBody:body];
285
272
  return MPRemoteCommandHandlerStatusSuccess;
286
273
  }
287
274
 
288
275
  - (MPRemoteCommandHandlerStatus)onChangePlaybackPosition:(MPChangePlaybackPositionCommandEvent *)event
289
276
  {
290
- [self.audioManagerModule sendEventWithName:@"onRemoteChangePlaybackPosition"
291
- body:@{@"value" : [NSNumber numberWithDouble:event.positionTime]}];
277
+ NSDictionary *body = @{@"value" : [NSNumber numberWithDouble:event.positionTime]};
278
+
279
+ [self.audioAPIModule invokeHandlerWithEventName:@"remoteChangePlaybackPosition" eventBody:body];
292
280
  return MPRemoteCommandHandlerStatusSuccess;
293
281
  }
294
282
 
@@ -3,11 +3,11 @@
3
3
  #import <AVFoundation/AVFoundation.h>
4
4
  #import <Foundation/Foundation.h>
5
5
 
6
- @class AudioManagerModule;
6
+ @class AudioAPIModule;
7
7
 
8
8
  @interface NotificationManager : NSObject
9
9
 
10
- @property (nonatomic, weak) AudioManagerModule *audioManagerModule;
10
+ @property (nonatomic, weak) AudioAPIModule *audioAPIModule;
11
11
  @property (nonatomic, weak) NSNotificationCenter *notificationCenter;
12
12
 
13
13
  @property (nonatomic, assign) bool isInterrupted;
@@ -15,7 +15,7 @@
15
15
  @property (nonatomic, assign) bool audioInterruptionsObserved;
16
16
  @property (nonatomic, assign) bool volumeChangesObserved;
17
17
 
18
- + (instancetype)sharedInstanceWithAudioManagerModule:(AudioManagerModule *)audioManagerModule;
18
+ - (instancetype)initWithAudioAPIModule:(AudioAPIModule *)audioAPIModule;
19
19
  - (void)cleanup;
20
20
 
21
21
  - (void)observeAudioInterruptions:(BOOL)enabled;