react-native-audio-api 0.10.0-nightly-e16d7ff-20251030 → 0.11.0-alpha.1
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/RNAudioAPI.podspec +11 -16
- package/android/build.gradle +3 -33
- package/android/src/main/cpp/audioapi/CMakeLists.txt +0 -6
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +0 -5
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +0 -1
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +142 -28
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +40 -13
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +2 -4
- package/android/src/main/cpp/audioapi/android/core/NativeAudioRecorder.hpp +9 -9
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidFileWriterBackend.h +37 -0
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.cpp +187 -0
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.h +57 -0
- package/android/src/main/cpp/audioapi/android/core/utils/AudioDecoder.cpp +0 -6
- package/android/src/main/cpp/audioapi/android/core/utils/FileUtils.h +34 -0
- package/android/src/main/cpp/audioapi/android/core/utils/FileUtilts.cpp +133 -0
- package/android/src/main/cpp/audioapi/android/core/utils/MiniaudioImplementation.cpp +3 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegAudioFileOptions.cpp +154 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegAudioFileOptions.h +41 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.cpp +429 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.h +113 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileOptions.cpp +47 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileOptions.h +28 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.cpp +269 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.h +47 -0
- package/android/src/main/cpp/audioapi/android/system/NativeFileInfo.hpp +31 -0
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +3 -29
- package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +9 -21
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +6 -27
- package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +0 -11
- package/android/src/main/java/com/swmansion/audioapi/system/NativeFileInfo.kt +18 -0
- package/android/src/main/jniLibs/arm64-v8a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavformat.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavutil.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libswresample.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavformat.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavutil.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86_64/libswresample.so +0 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +2 -30
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +0 -18
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +0 -1
- package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.cpp +1 -1
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +97 -18
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +18 -6
- package/common/cpp/audioapi/core/AudioNode.h +2 -3
- package/common/cpp/audioapi/core/AudioParam.cpp +2 -2
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +0 -10
- package/common/cpp/audioapi/core/BaseAudioContext.h +0 -2
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +32 -69
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.h +1 -37
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +36 -82
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +52 -31
- package/common/cpp/audioapi/core/sources/StreamerNode.cpp +58 -59
- package/common/cpp/audioapi/core/sources/StreamerNode.h +8 -37
- package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +0 -5
- package/common/cpp/audioapi/core/utils/Constants.h +1 -2
- package/common/cpp/audioapi/core/utils/worklets/SafeIncludes.h +10 -0
- package/common/cpp/audioapi/dsp/AudioUtils.cpp +1 -1
- package/common/cpp/audioapi/dsp/FFT.cpp +26 -0
- package/common/cpp/audioapi/dsp/FFT.h +2 -26
- package/common/cpp/audioapi/external/arm64-v8a/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libogg.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libopus.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libssl.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libogg.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libopus.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libssl.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/avcodec.h +2 -2
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec_desc.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec_id.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec_par.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavformat/avformat.h +2 -2
- package/common/cpp/audioapi/external/ffmpeg_include/libavutil/avutil.h +2 -2
- package/common/cpp/audioapi/external/iphoneos/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libogg.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libopus.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libssl.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libogg.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libopus.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libssl.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64/libavcodec.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64_x86_64-simulator/libavcodec.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64_x86_64-simulator/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64/libavformat.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64_x86_64-simulator/libavformat.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64_x86_64-simulator/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64_x86_64-simulator/libavutil.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64_x86_64-simulator/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64/libswresample.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64_x86_64-simulator/libswresample.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64_x86_64-simulator/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/external/x86/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/x86/libogg.a +0 -0
- package/common/cpp/audioapi/external/x86/libopus.a +0 -0
- package/common/cpp/audioapi/external/x86/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/x86/libssl.a +0 -0
- package/common/cpp/audioapi/external/x86/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/x86/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/x86/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libogg.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libopus.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libssl.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +3 -2
- package/common/cpp/audioapi/libs/ffmpeg/INSTRUCTIONS.md +32 -0
- package/common/cpp/audioapi/libs/ffmpeg/create_xcframework.sh +111 -0
- package/common/cpp/audioapi/libs/ffmpeg/ffmpeg_setup.sh +391 -0
- package/common/cpp/audioapi/utils/AudioBus.cpp +0 -28
- package/common/cpp/audioapi/utils/AudioBus.h +0 -3
- package/common/cpp/audioapi/utils/ThreadPool.hpp +1 -59
- package/common/cpp/test/CMakeLists.txt +14 -19
- package/ios/audioapi/ios/AudioAPIModule.h +1 -2
- package/ios/audioapi/ios/AudioAPIModule.mm +0 -2
- package/ios/audioapi/ios/core/IOSAudioFileOptions.h +36 -0
- package/ios/audioapi/ios/core/IOSAudioFileOptions.mm +140 -0
- package/ios/audioapi/ios/core/IOSAudioFileWriter.h +51 -0
- package/ios/audioapi/ios/core/IOSAudioFileWriter.mm +223 -0
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +28 -10
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +117 -30
- package/ios/audioapi/ios/core/IOSRecorderCallback.h +57 -0
- package/ios/audioapi/ios/core/IOSRecorderCallback.mm +189 -0
- package/ios/audioapi/ios/core/NativeAudioRecorder.h +4 -9
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +29 -71
- package/ios/audioapi/ios/core/utils/AudioDecoder.mm +1 -0
- package/ios/audioapi/ios/system/AudioEngine.mm +3 -3
- package/ios/audioapi/ios/system/AudioSessionManager.mm +0 -9
- package/ios/audioapi/ios/system/LockScreenManager.h +1 -0
- package/ios/audioapi/ios/system/LockScreenManager.mm +19 -6
- package/lib/commonjs/api.js +76 -141
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/api.web.js +0 -8
- package/lib/commonjs/api.web.js.map +1 -1
- package/lib/commonjs/core/AudioContext.js +1 -1
- package/lib/commonjs/core/AudioContext.js.map +1 -1
- package/lib/commonjs/core/AudioRecorder.js +171 -13
- package/lib/commonjs/core/AudioRecorder.js.map +1 -1
- package/lib/commonjs/core/BaseAudioContext.js +25 -28
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
- package/lib/commonjs/core/OfflineAudioContext.js +1 -1
- package/lib/commonjs/core/OfflineAudioContext.js.map +1 -1
- package/lib/commonjs/types.js +46 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/bitEnums.js +33 -0
- package/lib/commonjs/utils/bitEnums.js.map +1 -0
- package/lib/commonjs/utils/index.js +21 -19
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/commonjs/web-core/AudioContext.js +0 -12
- package/lib/commonjs/web-core/AudioContext.js.map +1 -1
- package/lib/commonjs/web-core/OfflineAudioContext.js +0 -12
- package/lib/commonjs/web-core/OfflineAudioContext.js.map +1 -1
- package/lib/module/api.js +15 -16
- package/lib/module/api.js.map +1 -1
- package/lib/module/api.web.js +0 -1
- package/lib/module/api.web.js.map +1 -1
- package/lib/module/core/AudioContext.js +2 -2
- package/lib/module/core/AudioContext.js.map +1 -1
- package/lib/module/core/AudioRecorder.js +171 -13
- package/lib/module/core/AudioRecorder.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +26 -29
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/OfflineAudioContext.js +2 -2
- package/lib/module/core/OfflineAudioContext.js.map +1 -1
- package/lib/module/types.js +45 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/bitEnums.js +27 -0
- package/lib/module/utils/bitEnums.js.map +1 -0
- package/lib/module/utils/index.js +2 -15
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/web-core/AudioContext.js +0 -12
- package/lib/module/web-core/AudioContext.js.map +1 -1
- package/lib/module/web-core/OfflineAudioContext.js +0 -12
- package/lib/module/web-core/OfflineAudioContext.js.map +1 -1
- package/lib/typescript/api.d.ts +17 -19
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/api.web.d.ts +0 -1
- package/lib/typescript/api.web.d.ts.map +1 -1
- package/lib/typescript/core/AudioContext.d.ts.map +1 -1
- package/lib/typescript/core/AudioRecorder.d.ts +62 -7
- package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +1 -3
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/events/types.d.ts +16 -0
- package/lib/typescript/events/types.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +42 -9
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +79 -8
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/utils/bitEnums.d.ts +4 -0
- package/lib/typescript/utils/bitEnums.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +2 -5
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioContext.d.ts +0 -3
- package/lib/typescript/web-core/AudioContext.d.ts.map +1 -1
- package/lib/typescript/web-core/BaseAudioContext.d.ts +0 -2
- package/lib/typescript/web-core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/web-core/OfflineAudioContext.d.ts +0 -3
- package/lib/typescript/web-core/OfflineAudioContext.d.ts.map +1 -1
- package/package.json +4 -7
- package/src/api.ts +18 -45
- package/src/api.web.ts +0 -1
- package/src/core/AudioContext.ts +2 -3
- package/src/core/AudioRecorder.ts +211 -24
- package/src/core/BaseAudioContext.ts +60 -67
- package/src/core/OfflineAudioContext.ts +2 -2
- package/src/events/types.ts +18 -0
- package/src/interfaces.ts +52 -16
- package/src/types.ts +90 -9
- package/src/utils/bitEnums.ts +51 -0
- package/src/utils/index.ts +2 -22
- package/src/web-core/AudioContext.tsx +0 -25
- package/src/web-core/BaseAudioContext.tsx +0 -2
- package/src/web-core/OfflineAudioContext.tsx +0 -25
- package/common/cpp/audioapi/HostObjects/effects/ConvolverNodeHostObject.cpp +0 -47
- package/common/cpp/audioapi/HostObjects/effects/ConvolverNodeHostObject.h +0 -20
- package/common/cpp/audioapi/core/effects/ConvolverNode.cpp +0 -210
- package/common/cpp/audioapi/core/effects/ConvolverNode.h +0 -55
- package/common/cpp/audioapi/dsp/Convolver.cpp +0 -213
- package/common/cpp/audioapi/dsp/Convolver.h +0 -45
- package/common/cpp/audioapi/libs/ffmpeg/relinking.md +0 -24
- package/common/cpp/audioapi/utils/AlignedAllocator.hpp +0 -50
- package/common/cpp/test/src/biquad/BiquadFilterChromium.cpp +0 -389
- package/common/cpp/test/src/biquad/BiquadFilterChromium.h +0 -64
- package/common/cpp/test/src/biquad/BiquadFilterTest.cpp +0 -284
- package/common/cpp/test/src/biquad/BiquadFilterTest.h +0 -40
- package/lib/commonjs/core/ConvolverNode.js +0 -37
- package/lib/commonjs/core/ConvolverNode.js.map +0 -1
- package/lib/commonjs/web-core/ConvolverNode.js +0 -40
- package/lib/commonjs/web-core/ConvolverNode.js.map +0 -1
- package/lib/commonjs/web-core/ConvolverNodeOptions.js +0 -6
- package/lib/commonjs/web-core/ConvolverNodeOptions.js.map +0 -1
- package/lib/module/core/ConvolverNode.js +0 -31
- package/lib/module/core/ConvolverNode.js.map +0 -1
- package/lib/module/web-core/ConvolverNode.js +0 -34
- package/lib/module/web-core/ConvolverNode.js.map +0 -1
- package/lib/module/web-core/ConvolverNodeOptions.js +0 -4
- package/lib/module/web-core/ConvolverNodeOptions.js.map +0 -1
- package/lib/typescript/core/ConvolverNode.d.ts +0 -12
- package/lib/typescript/core/ConvolverNode.d.ts.map +0 -1
- package/lib/typescript/web-core/ConvolverNode.d.ts +0 -11
- package/lib/typescript/web-core/ConvolverNode.d.ts.map +0 -1
- package/lib/typescript/web-core/ConvolverNodeOptions.d.ts +0 -6
- package/lib/typescript/web-core/ConvolverNodeOptions.d.ts.map +0 -1
- package/scripts/download-prebuilt-binaries.sh +0 -52
- package/scripts/rnaa_utils.rb +0 -8
- package/scripts/validate-worklets-version.js +0 -28
- package/src/core/ConvolverNode.ts +0 -35
- package/src/web-core/ConvolverNode.tsx +0 -43
- package/src/web-core/ConvolverNodeOptions.tsx +0 -6
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#import <AVFoundation/AVFoundation.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
|
|
4
|
+
#include <audioapi/ios/core/IOSAudioFileOptions.h>
|
|
5
|
+
|
|
6
|
+
namespace audioapi {
|
|
7
|
+
|
|
8
|
+
IOSAudioFileOptions::IOSAudioFileOptions(float sampleRate, size_t channelCount, size_t bitRate, size_t flags)
|
|
9
|
+
{
|
|
10
|
+
sampleRate_ = sampleRate;
|
|
11
|
+
channelCount_ = channelCount;
|
|
12
|
+
bitRate_ = bitRate;
|
|
13
|
+
|
|
14
|
+
format_ = static_cast<uint8_t>(((flags >> 0) & 0xF));
|
|
15
|
+
quality_ = static_cast<uint8_t>(((flags >> 4) & 0xF));
|
|
16
|
+
flacCompressionLevel_ = static_cast<uint8_t>(((flags >> 8) & 0xF));
|
|
17
|
+
directory_ = static_cast<uint8_t>(((flags >> 12) & 0xF));
|
|
18
|
+
bitDepth_ = static_cast<uint8_t>(((flags >> 16) & 0xF));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
AudioFormatID IOSAudioFileOptions::getFormat() const
|
|
22
|
+
{
|
|
23
|
+
switch (format_) {
|
|
24
|
+
case 1:
|
|
25
|
+
return kAudioFormatLinearPCM; // WAV <-> Linear PCM container
|
|
26
|
+
case 2:
|
|
27
|
+
return kAudioFormatLinearPCM; // CAF <-> Linear PCM container
|
|
28
|
+
case 3:
|
|
29
|
+
return kAudioFormatMPEG4AAC; // M4A <-> AAC
|
|
30
|
+
case 4:
|
|
31
|
+
return kAudioFormatFLAC; // FLAC <-> FLAC
|
|
32
|
+
default:
|
|
33
|
+
return kAudioFormatLinearPCM; // Default to Linear PCM
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
NSInteger IOSAudioFileOptions::getQuality() const
|
|
38
|
+
{
|
|
39
|
+
switch (quality_) {
|
|
40
|
+
case 1:
|
|
41
|
+
return AVAudioQualityMin;
|
|
42
|
+
case 2:
|
|
43
|
+
return AVAudioQualityLow;
|
|
44
|
+
case 3:
|
|
45
|
+
return AVAudioQualityMedium;
|
|
46
|
+
case 4:
|
|
47
|
+
return AVAudioQualityHigh;
|
|
48
|
+
case 5:
|
|
49
|
+
return AVAudioQualityMax;
|
|
50
|
+
default:
|
|
51
|
+
return AVAudioQualityMedium; // Default to Medium
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
NSInteger IOSAudioFileOptions::getFlacCompressionLevel() const
|
|
56
|
+
{
|
|
57
|
+
// Shift the quality from 1-9 to 0-8 for real values
|
|
58
|
+
// Default to 5 if out of range
|
|
59
|
+
return (flacCompressionLevel_ >= 1 && flacCompressionLevel_ <= 9) ? flacCompressionLevel_ - 1 : 5;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
NSSearchPathDirectory IOSAudioFileOptions::getDirectory() const
|
|
63
|
+
{
|
|
64
|
+
switch (directory_) {
|
|
65
|
+
case 1:
|
|
66
|
+
return NSDocumentDirectory;
|
|
67
|
+
case 2:
|
|
68
|
+
return NSCachesDirectory;
|
|
69
|
+
default:
|
|
70
|
+
return NSCachesDirectory; // Default to Caches
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
NSString *IOSAudioFileOptions::getFileExtension() const
|
|
75
|
+
{
|
|
76
|
+
switch (format_) {
|
|
77
|
+
case 1:
|
|
78
|
+
return @"wav"; // WAV <-> Linear PCM container
|
|
79
|
+
case 2:
|
|
80
|
+
return @"caf"; // CAF <-> Linear PCM container
|
|
81
|
+
case 3:
|
|
82
|
+
return @"m4a"; // M4A <-> AAC
|
|
83
|
+
case 4:
|
|
84
|
+
return @"flac"; // FLAC <-> FLAC
|
|
85
|
+
default:
|
|
86
|
+
return @"wav"; // Default to WAV
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
NSInteger IOSAudioFileOptions::getBitDepth() const
|
|
91
|
+
{
|
|
92
|
+
switch (bitDepth_) {
|
|
93
|
+
case 1:
|
|
94
|
+
return 16;
|
|
95
|
+
case 2:
|
|
96
|
+
return 24;
|
|
97
|
+
case 3:
|
|
98
|
+
return 32;
|
|
99
|
+
default:
|
|
100
|
+
return 24; // Default to 24-bit
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
NSDictionary *IOSAudioFileOptions::getFileSettings()
|
|
105
|
+
{
|
|
106
|
+
AudioFormatID format = getFormat();
|
|
107
|
+
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
|
|
108
|
+
|
|
109
|
+
settings[AVFormatIDKey] = @(format);
|
|
110
|
+
settings[AVSampleRateKey] = @(sampleRate_);
|
|
111
|
+
settings[AVNumberOfChannelsKey] = @(channelCount_);
|
|
112
|
+
|
|
113
|
+
settings[AVEncoderAudioQualityKey] = @(getQuality());
|
|
114
|
+
|
|
115
|
+
if (format == kAudioFormatMPEG4AAC) {
|
|
116
|
+
settings[AVEncoderBitRateKey] = @(bitRate_);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (format == kAudioFormatLinearPCM) {
|
|
120
|
+
NSInteger bitDepth = getBitDepth();
|
|
121
|
+
|
|
122
|
+
settings[AVLinearPCMBitDepthKey] = @(bitDepth);
|
|
123
|
+
settings[AVLinearPCMIsFloatKey] = @(bitDepth == 32);
|
|
124
|
+
settings[AVLinearPCMIsBigEndianKey] = @(NO);
|
|
125
|
+
settings[AVLinearPCMIsNonInterleaved] = @(NO);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (format == kAudioFormatFLAC) {
|
|
129
|
+
settings[@"FLACCompressionLevel"] = @(getFlacCompressionLevel());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return settings;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
float IOSAudioFileOptions::getSampleRate()
|
|
136
|
+
{
|
|
137
|
+
return sampleRate_;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <string>
|
|
5
|
+
#include <tuple>
|
|
6
|
+
|
|
7
|
+
#ifndef __OBJC__ // when compiled as C++
|
|
8
|
+
typedef struct objc_object NSURL;
|
|
9
|
+
typedef struct objc_object NSString;
|
|
10
|
+
typedef struct objc_object AVAudioFile;
|
|
11
|
+
typedef struct objc_object AVAudioFormat;
|
|
12
|
+
typedef struct objc_object AudioBufferList;
|
|
13
|
+
typedef struct objc_object AVAudioConverter;
|
|
14
|
+
#endif // __OBJC__
|
|
15
|
+
|
|
16
|
+
namespace audioapi {
|
|
17
|
+
|
|
18
|
+
class IOSAudioFileOptions;
|
|
19
|
+
|
|
20
|
+
class IOSAudioFileWriter {
|
|
21
|
+
public:
|
|
22
|
+
IOSAudioFileWriter(float sampleRate, size_t channelCount, size_t bitRate, size_t iosFlags);
|
|
23
|
+
~IOSAudioFileWriter();
|
|
24
|
+
|
|
25
|
+
std::string openFile(AVAudioFormat *bufferFormat, size_t maxInputBufferLength);
|
|
26
|
+
std::tuple<double, double> closeFile();
|
|
27
|
+
|
|
28
|
+
bool writeAudioData(const AudioBufferList *audioBufferList, int numFrames);
|
|
29
|
+
|
|
30
|
+
double getCurrentDuration() const;
|
|
31
|
+
|
|
32
|
+
private:
|
|
33
|
+
size_t converterInputBufferSize_;
|
|
34
|
+
size_t converterOutputBufferSize_;
|
|
35
|
+
std::atomic<size_t> framesWritten_{0};
|
|
36
|
+
|
|
37
|
+
NSString *getISODateStringForDirectory();
|
|
38
|
+
NSString *getTimestampForFilename();
|
|
39
|
+
NSURL *getFileURL();
|
|
40
|
+
|
|
41
|
+
std::shared_ptr<IOSAudioFileOptions> fileOptions_;
|
|
42
|
+
AVAudioFile *audioFile_;
|
|
43
|
+
AVAudioFormat *bufferFormat_;
|
|
44
|
+
AVAudioConverter *converter_;
|
|
45
|
+
NSURL *fileURL_;
|
|
46
|
+
|
|
47
|
+
AVAudioPCMBuffer *converterInputBuffer_;
|
|
48
|
+
AVAudioPCMBuffer *converterOutputBuffer_;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#import <AVFoundation/AVFoundation.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
|
|
4
|
+
#include <audioapi/ios/core/IOSAudioFileOptions.h>
|
|
5
|
+
#include <audioapi/ios/core/IOSAudioFileWriter.h>
|
|
6
|
+
|
|
7
|
+
constexpr double BYTES_TO_MB = 1024.0 * 1024.0;
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
IOSAudioFileWriter::IOSAudioFileWriter(float sampleRate, size_t channelCount, size_t bitRate, size_t iosFlags)
|
|
11
|
+
{
|
|
12
|
+
fileOptions_ = std::make_shared<IOSAudioFileOptions>(sampleRate, channelCount, bitRate, iosFlags);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
IOSAudioFileWriter::~IOSAudioFileWriter()
|
|
16
|
+
{
|
|
17
|
+
fileURL_ = nil;
|
|
18
|
+
audioFile_ = nil;
|
|
19
|
+
converter_ = nil;
|
|
20
|
+
bufferFormat_ = nil;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
std::string IOSAudioFileWriter::openFile(AVAudioFormat *bufferFormat, size_t maxInputBufferLength)
|
|
24
|
+
{
|
|
25
|
+
@autoreleasepool {
|
|
26
|
+
if (audioFile_ != nil) {
|
|
27
|
+
NSLog(@"⚠️ createFileForWriting: currentAudioFile_ already exists");
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
framesWritten_.store(0);
|
|
31
|
+
|
|
32
|
+
bufferFormat_ = bufferFormat;
|
|
33
|
+
|
|
34
|
+
NSError *error = nil;
|
|
35
|
+
NSDictionary *settings = fileOptions_->getFileSettings();
|
|
36
|
+
fileURL_ = getFileURL();
|
|
37
|
+
|
|
38
|
+
NSLog(@"ℹ️ Creating audio file at URL: %@", [fileURL_ absoluteString]);
|
|
39
|
+
|
|
40
|
+
audioFile_ = [[AVAudioFile alloc] initForWriting:fileURL_
|
|
41
|
+
settings:settings
|
|
42
|
+
commonFormat:AVAudioPCMFormatFloat32
|
|
43
|
+
interleaved:bufferFormat.interleaved
|
|
44
|
+
error:&error];
|
|
45
|
+
converter_ = [[AVAudioConverter alloc] initFromFormat:bufferFormat toFormat:[audioFile_ processingFormat]];
|
|
46
|
+
converter_.sampleRateConverterAlgorithm = AVSampleRateConverterAlgorithm_Normal;
|
|
47
|
+
converter_.sampleRateConverterQuality = AVAudioQualityMax;
|
|
48
|
+
converter_.primeMethod = AVAudioConverterPrimeMethod_None;
|
|
49
|
+
|
|
50
|
+
converterInputBufferSize_ = maxInputBufferLength;
|
|
51
|
+
converterOutputBufferSize_ = std::max(
|
|
52
|
+
(double)maxInputBufferLength, fileOptions_->getSampleRate() / bufferFormat.sampleRate * maxInputBufferLength);
|
|
53
|
+
|
|
54
|
+
converterInputBuffer_ = [[AVAudioPCMBuffer alloc] initWithPCMFormat:bufferFormat
|
|
55
|
+
frameCapacity:(AVAudioFrameCount)maxInputBufferLength];
|
|
56
|
+
converterOutputBuffer_ = [[AVAudioPCMBuffer alloc] initWithPCMFormat:[audioFile_ processingFormat]
|
|
57
|
+
frameCapacity:(AVAudioFrameCount)maxInputBufferLength];
|
|
58
|
+
|
|
59
|
+
if (error != nil || audioFile_ == nil) {
|
|
60
|
+
NSLog(@"Error creating audio file for writing: %@", [error debugDescription]);
|
|
61
|
+
audioFile_ = nil;
|
|
62
|
+
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return [[fileURL_ path] UTF8String];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
std::tuple<double, double> IOSAudioFileWriter::closeFile()
|
|
71
|
+
{
|
|
72
|
+
@autoreleasepool {
|
|
73
|
+
NSError *error;
|
|
74
|
+
std::string filePath = [[fileURL_ path] UTF8String];
|
|
75
|
+
|
|
76
|
+
if (audioFile_ == nil) {
|
|
77
|
+
return {0, 0};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// AVAudioFile automatically finalizes the file when deallocated
|
|
81
|
+
audioFile_ = nil;
|
|
82
|
+
|
|
83
|
+
double fileDuration = CMTimeGetSeconds([[AVURLAsset URLAssetWithURL:fileURL_ options:nil] duration]);
|
|
84
|
+
double fileSizeBytesMb =
|
|
85
|
+
static_cast<double>([[[NSFileManager defaultManager] attributesOfItemAtPath:fileURL_.path
|
|
86
|
+
error:&error] fileSize]) /
|
|
87
|
+
BYTES_TO_MB;
|
|
88
|
+
|
|
89
|
+
NSLog(
|
|
90
|
+
@"ℹ️ Closed audio file at path: %s, duration: %.2f sec, size: %.2f MB",
|
|
91
|
+
filePath.c_str(),
|
|
92
|
+
fileDuration,
|
|
93
|
+
fileSizeBytesMb);
|
|
94
|
+
|
|
95
|
+
if (error != nil) {
|
|
96
|
+
NSLog(@"⚠️ closeFile: error while retrieving file size");
|
|
97
|
+
fileSizeBytesMb = 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fileURL_ = nil;
|
|
101
|
+
|
|
102
|
+
return {fileSizeBytesMb, fileDuration};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
bool IOSAudioFileWriter::writeAudioData(const AudioBufferList *audioBufferList, int numFrames)
|
|
107
|
+
{
|
|
108
|
+
if (audioFile_ == nil) {
|
|
109
|
+
NSLog(@"⚠️ writeAudioData: audioFile is nil, cannot write data");
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@autoreleasepool {
|
|
114
|
+
NSError *error = nil;
|
|
115
|
+
AVAudioFormat *fileFormat = [audioFile_ processingFormat];
|
|
116
|
+
|
|
117
|
+
if (bufferFormat_.sampleRate == fileFormat.sampleRate && bufferFormat_.channelCount == fileFormat.channelCount &&
|
|
118
|
+
bufferFormat_.isInterleaved == fileFormat.isInterleaved) {
|
|
119
|
+
AVAudioPCMBuffer *processingBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:fileFormat
|
|
120
|
+
bufferListNoCopy:audioBufferList
|
|
121
|
+
deallocator:NULL];
|
|
122
|
+
processingBuffer.frameLength = (AVAudioFrameCount)numFrames;
|
|
123
|
+
|
|
124
|
+
[audioFile_ writeFromBuffer:processingBuffer error:&error];
|
|
125
|
+
|
|
126
|
+
if (error != nil) {
|
|
127
|
+
NSLog(@"Error writing audio data to file: %@", [error debugDescription]);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
framesWritten_.fetch_add(numFrames);
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
size_t outputFrameCount = ceil(numFrames * fileFormat.sampleRate / bufferFormat_.sampleRate);
|
|
136
|
+
|
|
137
|
+
for (size_t i = 0; i < bufferFormat_.channelCount; ++i) {
|
|
138
|
+
memcpy(
|
|
139
|
+
converterInputBuffer_.mutableAudioBufferList->mBuffers[i].mData,
|
|
140
|
+
audioBufferList->mBuffers[i].mData,
|
|
141
|
+
audioBufferList->mBuffers[i].mDataByteSize);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
converterInputBuffer_.frameLength = numFrames;
|
|
145
|
+
|
|
146
|
+
AVAudioConverterInputBlock inputBlock =
|
|
147
|
+
^AVAudioBuffer *_Nullable(AVAudioPacketCount inNumberOfPackets, AVAudioConverterInputStatus *outStatus)
|
|
148
|
+
{
|
|
149
|
+
// this line is probably an delusion, but for my sanity lets keep it
|
|
150
|
+
inNumberOfPackets = numFrames;
|
|
151
|
+
*outStatus = AVAudioConverterInputStatus_HaveData;
|
|
152
|
+
return converterInputBuffer_;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
[converter_ convertToBuffer:converterOutputBuffer_ error:&error withInputFromBlock:inputBlock];
|
|
156
|
+
|
|
157
|
+
if (error != nil) {
|
|
158
|
+
NSLog(@"Error during audio conversion: %@", [error debugDescription]);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
[audioFile_ writeFromBuffer:converterOutputBuffer_ error:&error];
|
|
163
|
+
|
|
164
|
+
if (error != nil) {
|
|
165
|
+
NSLog(@"Error writing audio data to file: %@", [error debugDescription]);
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
framesWritten_.fetch_add(numFrames);
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
NSString *IOSAudioFileWriter::getISODateStringForDirectory()
|
|
175
|
+
{
|
|
176
|
+
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
|
|
177
|
+
fmt.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
|
|
178
|
+
fmt.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; // or local if you prefer
|
|
179
|
+
fmt.dateFormat = @"yyyy-MM-dd";
|
|
180
|
+
return [fmt stringFromDate:[NSDate date]];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
NSString *IOSAudioFileWriter::getTimestampForFilename()
|
|
184
|
+
{
|
|
185
|
+
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
|
|
186
|
+
fmt.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
|
|
187
|
+
fmt.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; // or local if you prefer
|
|
188
|
+
fmt.dateFormat = @"yyyyMMdd_HHmmss_SSS";
|
|
189
|
+
return [fmt stringFromDate:[NSDate date]];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
NSURL *IOSAudioFileWriter::getFileURL()
|
|
193
|
+
{
|
|
194
|
+
NSError *error = nil;
|
|
195
|
+
|
|
196
|
+
NSSearchPathDirectory searchDirectory = fileOptions_->getDirectory();
|
|
197
|
+
NSString *directory = [NSString stringWithFormat:@"AudioAPI/%@", getISODateStringForDirectory()];
|
|
198
|
+
|
|
199
|
+
NSURL *baseURL = [[[NSFileManager defaultManager] URLsForDirectory:searchDirectory
|
|
200
|
+
inDomains:NSUserDomainMask] firstObject];
|
|
201
|
+
NSURL *dirURL = [baseURL URLByAppendingPathComponent:directory isDirectory:YES];
|
|
202
|
+
|
|
203
|
+
[[NSFileManager defaultManager] createDirectoryAtURL:dirURL
|
|
204
|
+
withIntermediateDirectories:YES
|
|
205
|
+
attributes:nil
|
|
206
|
+
error:&error];
|
|
207
|
+
|
|
208
|
+
if (error != nil) {
|
|
209
|
+
NSLog(@"Error creating directory for audio recordings: %@", [error debugDescription]);
|
|
210
|
+
dirURL = baseURL;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
NSString *fileName =
|
|
214
|
+
[NSString stringWithFormat:@"audio_%@.%@", getTimestampForFilename(), fileOptions_->getFileExtension()];
|
|
215
|
+
return [dirURL URLByAppendingPathComponent:fileName];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
double IOSAudioFileWriter::getCurrentDuration() const
|
|
219
|
+
{
|
|
220
|
+
return static_cast<double>(framesWritten_.load()) / bufferFormat_.sampleRate;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
} // namespace audioapi
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#ifdef __OBJC__ // when compiled as
|
|
3
|
+
#ifdef __OBJC__ // when compiled as C++
|
|
4
4
|
#import <NativeAudioRecorder.h>
|
|
5
|
-
#else
|
|
5
|
+
#else
|
|
6
|
+
typedef struct objc_object AVAudioFile;
|
|
7
|
+
typedef struct objc_object NSURL;
|
|
8
|
+
typedef struct objc_object AudioBufferList;
|
|
6
9
|
typedef struct objc_object NativeAudioRecorder;
|
|
7
10
|
#endif // __OBJC__
|
|
8
11
|
|
|
@@ -12,21 +15,36 @@ namespace audioapi {
|
|
|
12
15
|
|
|
13
16
|
class AudioBus;
|
|
14
17
|
class CircularAudioArray;
|
|
18
|
+
class IOSAudioFileWriter;
|
|
19
|
+
class IOSRecorderCallback;
|
|
20
|
+
class AudioEventHandlerRegistry;
|
|
15
21
|
|
|
16
22
|
class IOSAudioRecorder : public AudioRecorder {
|
|
17
23
|
public:
|
|
18
|
-
IOSAudioRecorder(
|
|
19
|
-
float sampleRate,
|
|
20
|
-
int bufferLength,
|
|
21
|
-
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
22
|
-
|
|
24
|
+
IOSAudioRecorder(const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
23
25
|
~IOSAudioRecorder() override;
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
std::string start() override;
|
|
28
|
+
std::tuple<std::string, double, double> stop() override;
|
|
29
|
+
|
|
30
|
+
void enableFileOutput(float sampleRate, size_t channelCount, size_t bitRate, size_t iosFlags, size_t androidFlags)
|
|
31
|
+
override;
|
|
32
|
+
void disableFileOutput() override;
|
|
33
|
+
|
|
34
|
+
void pause() override;
|
|
35
|
+
void resume() override;
|
|
36
|
+
|
|
37
|
+
void setOnAudioReadyCallback(float sampleRate, size_t bufferLength, size_t channelCount, uint64_t callbackId)
|
|
38
|
+
override;
|
|
39
|
+
void clearOnAudioReadyCallback() override;
|
|
40
|
+
|
|
41
|
+
double getCurrentDuration() const override;
|
|
27
42
|
|
|
28
43
|
private:
|
|
29
|
-
|
|
44
|
+
std::shared_ptr<IOSAudioFileWriter> fileWriter_;
|
|
45
|
+
std::shared_ptr<IOSRecorderCallback> callback_;
|
|
46
|
+
std::string filePath_{""};
|
|
47
|
+
NativeAudioRecorder *nativeRecorder_;
|
|
30
48
|
};
|
|
31
49
|
|
|
32
50
|
} // namespace audioapi
|
|
@@ -1,70 +1,157 @@
|
|
|
1
1
|
#import <AVFoundation/AVFoundation.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
#include <unordered_map>
|
|
2
4
|
|
|
3
5
|
#include <audioapi/core/utils/Constants.h>
|
|
4
6
|
#include <audioapi/dsp/VectorMath.h>
|
|
5
7
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
8
|
+
#include <audioapi/ios/core/IOSAudioFileWriter.h>
|
|
6
9
|
#include <audioapi/ios/core/IOSAudioRecorder.h>
|
|
10
|
+
#include <audioapi/ios/core/IOSRecorderCallback.h>
|
|
7
11
|
#include <audioapi/utils/AudioArray.h>
|
|
8
12
|
#include <audioapi/utils/AudioBus.h>
|
|
9
13
|
#include <audioapi/utils/CircularAudioArray.h>
|
|
10
14
|
#include <audioapi/utils/CircularOverflowableAudioArray.h>
|
|
11
|
-
#include <unordered_map>
|
|
12
15
|
|
|
13
16
|
namespace audioapi {
|
|
14
17
|
|
|
15
|
-
IOSAudioRecorder::IOSAudioRecorder(
|
|
16
|
-
|
|
17
|
-
int bufferLength,
|
|
18
|
-
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
|
|
19
|
-
: AudioRecorder(sampleRate, bufferLength, audioEventHandlerRegistry)
|
|
18
|
+
IOSAudioRecorder::IOSAudioRecorder(const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
|
|
19
|
+
: AudioRecorder(audioEventHandlerRegistry), fileWriter_(nullptr)
|
|
20
20
|
{
|
|
21
|
-
AudioReceiverBlock
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
writeToBuffers(inputChannel, numFrames);
|
|
21
|
+
AudioReceiverBlock receiverBlock = ^(const AudioBufferList *inputBuffer, int numFrames) {
|
|
22
|
+
if (usesFileOutput()) {
|
|
23
|
+
fileWriter_->writeAudioData(inputBuffer, numFrames);
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
auto *outputChannel = bus->getChannel(0)->getData();
|
|
30
|
-
|
|
31
|
-
circularBuffer_->pop_front(outputChannel, bufferLength_);
|
|
32
|
-
|
|
33
|
-
invokeOnAudioReadyCallback(bus, bufferLength_);
|
|
26
|
+
if (usesCallback()) {
|
|
27
|
+
callback_->receiveAudioData(inputBuffer, numFrames);
|
|
34
28
|
}
|
|
35
29
|
};
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
bufferLength:bufferLength
|
|
39
|
-
sampleRate:sampleRate];
|
|
31
|
+
nativeRecorder_ = [[NativeAudioRecorder alloc] initWithReceiverBlock:receiverBlock];
|
|
40
32
|
}
|
|
41
33
|
|
|
42
34
|
IOSAudioRecorder::~IOSAudioRecorder()
|
|
43
35
|
{
|
|
44
36
|
stop();
|
|
45
|
-
[
|
|
37
|
+
[nativeRecorder_ cleanup];
|
|
38
|
+
}
|
|
39
|
+
std::string IOSAudioRecorder::start()
|
|
40
|
+
{
|
|
41
|
+
size_t maxInputBufferLength = [nativeRecorder_ getBufferSize];
|
|
42
|
+
|
|
43
|
+
if (isRecording()) {
|
|
44
|
+
return filePath_;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (usesFileOutput()) {
|
|
48
|
+
filePath_ = fileWriter_->openFile([nativeRecorder_ getInputFormat], maxInputBufferLength);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (usesCallback()) {
|
|
52
|
+
callback_->prepare([nativeRecorder_ getInputFormat], maxInputBufferLength);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (isConnected()) {
|
|
56
|
+
// TODO: set adapter node properties?
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
[nativeRecorder_ start];
|
|
60
|
+
state_.store(RecorderState::Recording);
|
|
61
|
+
|
|
62
|
+
return filePath_;
|
|
46
63
|
}
|
|
47
64
|
|
|
48
|
-
|
|
65
|
+
std::tuple<std::string, double, double> IOSAudioRecorder::stop()
|
|
49
66
|
{
|
|
50
|
-
|
|
67
|
+
std::string filePath = filePath_;
|
|
68
|
+
double outputFileSize = 0;
|
|
69
|
+
double outputDuration = 0;
|
|
70
|
+
|
|
71
|
+
if (!isRecording()) {
|
|
72
|
+
return {filePath, 0, 0};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
[nativeRecorder_ stop];
|
|
76
|
+
state_.store(RecorderState::Idle);
|
|
77
|
+
|
|
78
|
+
if (usesFileOutput()) {
|
|
79
|
+
auto [size, duration] = fileWriter_->closeFile();
|
|
80
|
+
outputFileSize = size;
|
|
81
|
+
outputDuration = duration;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (usesCallback()) {
|
|
85
|
+
callback_->cleanup();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
filePath_ = "";
|
|
89
|
+
return {filePath, outputFileSize, outputDuration};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
void IOSAudioRecorder::enableFileOutput(
|
|
93
|
+
float sampleRate,
|
|
94
|
+
size_t channelCount,
|
|
95
|
+
size_t bitRate,
|
|
96
|
+
size_t iosFlags,
|
|
97
|
+
size_t androidFlags)
|
|
98
|
+
{
|
|
99
|
+
fileOutputEnabled_.store(true);
|
|
100
|
+
fileWriter_ = std::make_shared<IOSAudioFileWriter>(sampleRate, channelCount, bitRate, iosFlags);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
void IOSAudioRecorder::disableFileOutput()
|
|
104
|
+
{
|
|
105
|
+
fileOutputEnabled_.store(false);
|
|
106
|
+
fileWriter_ = nullptr;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
void IOSAudioRecorder::pause()
|
|
110
|
+
{
|
|
111
|
+
if (!isRecording()) {
|
|
51
112
|
return;
|
|
52
113
|
}
|
|
53
114
|
|
|
54
|
-
[
|
|
55
|
-
|
|
115
|
+
[nativeRecorder_ stop];
|
|
116
|
+
state_.store(RecorderState::Paused);
|
|
56
117
|
}
|
|
57
118
|
|
|
58
|
-
void IOSAudioRecorder::
|
|
119
|
+
void IOSAudioRecorder::resume()
|
|
59
120
|
{
|
|
60
|
-
if (!
|
|
121
|
+
if (!isPaused()) {
|
|
61
122
|
return;
|
|
62
123
|
}
|
|
63
124
|
|
|
64
|
-
|
|
65
|
-
|
|
125
|
+
[nativeRecorder_ start];
|
|
126
|
+
state_.store(RecorderState::Recording);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
void IOSAudioRecorder::setOnAudioReadyCallback(
|
|
130
|
+
float sampleRate,
|
|
131
|
+
size_t bufferLength,
|
|
132
|
+
size_t channelCount,
|
|
133
|
+
uint64_t callbackId)
|
|
134
|
+
{
|
|
135
|
+
callback_ = std::make_shared<IOSRecorderCallback>(
|
|
136
|
+
audioEventHandlerRegistry_, sampleRate, bufferLength, channelCount, callbackId);
|
|
137
|
+
callbackOutputEnabled_.store(true);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void IOSAudioRecorder::clearOnAudioReadyCallback()
|
|
141
|
+
{
|
|
142
|
+
callbackOutputEnabled_.store(false);
|
|
143
|
+
callback_ = nullptr;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
double IOSAudioRecorder::getCurrentDuration() const
|
|
147
|
+
{
|
|
148
|
+
double duration = 0.0;
|
|
149
|
+
|
|
150
|
+
if (usesFileOutput() && fileWriter_) {
|
|
151
|
+
duration = fileWriter_->getCurrentDuration();
|
|
152
|
+
}
|
|
66
153
|
|
|
67
|
-
|
|
154
|
+
return duration;
|
|
68
155
|
}
|
|
69
156
|
|
|
70
157
|
} // namespace audioapi
|