@mentra/bluetooth-sdk 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.
- package/README.md +278 -0
- package/android/build.gradle +167 -0
- package/android/lc3Lib/CMakeLists.txt +6 -0
- package/android/lc3Lib/build.gradle +109 -0
- package/android/lc3Lib/proguard-rules.pro +33 -0
- package/android/lc3Lib/src/main/AndroidManifest.xml +2 -0
- package/android/lc3Lib/src/main/cpp/CMakeLists.txt +8 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/CMakeLists.txt +30 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/CMakeLists.txt +7 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.cc +96 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.h +53 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/Makefile.am +6 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h +26 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h.in +26 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/ogg.h +209 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/os_types.h +158 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus.h +981 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_custom.h +342 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_defines.h +799 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_multistream.h +660 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_projection.h +568 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_types.h +166 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.cc +268 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.h +115 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/opus_tools/opus_header.h +59 -0
- package/android/lc3Lib/src/main/cpp/liblc3/CMakeLists.txt +38 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/lc3.h +309 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/lc3_private.h +162 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/rnnoise.h +114 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/CMakeLists.txt +19 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.c +92 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.h +44 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.c +375 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.h +315 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.c +129 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.h +69 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/common.h +148 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.c +70 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.h +43 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/fastmath.h +158 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/lc3.c +702 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.c +893 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.h +111 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_arm.h +506 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_neon.h +281 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/makefile.mk +35 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.c +452 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.h +57 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct_neon.h +296 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/meson.build +46 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.c +61 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.h +57 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.c +880 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.h +103 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.c +904 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.h +119 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.c +3457 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.h +94 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.c +457 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.h +99 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3.cpp +159 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/_kiss_fft_guts.h +182 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/arch.h +261 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.c +279 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.h +59 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/common.h +48 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/compile.sh +3 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/denoise.c +646 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.c +601 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.h +203 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/opus_types.h +159 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.c +526 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.h +149 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.c +178 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.h +69 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.c +11051 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.h +34 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_reader.c +168 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_train.py +66 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/tansig_table.h +45 -0
- package/android/lc3Lib/src/main/java/com/mentra/lc3Lib/Lc3Cpp.java +38 -0
- package/android/lc3Lib/third_party/CMakeLists.txt +23 -0
- package/android/lc3Lib/third_party/CMakeLists_libogg.txt +18 -0
- package/android/lc3Lib/third_party/CMakeLists_libopus.txt +18 -0
- package/android/lc3Lib/third_party/CMakeLists_opus-tools.txt +23 -0
- package/android/lc3Lib/third_party/opus_tools/src/AUTHORS +5 -0
- package/android/lc3Lib/third_party/opus_tools/src/CMakeLists.txt +4 -0
- package/android/lc3Lib/third_party/opus_tools/src/COPYING +371 -0
- package/android/lc3Lib/third_party/opus_tools/src/ChangeLog +3 -0
- package/android/lc3Lib/third_party/opus_tools/src/Makefile.am +42 -0
- package/android/lc3Lib/third_party/opus_tools/src/Makefile.unix +23 -0
- package/android/lc3Lib/third_party/opus_tools/src/NEWS +0 -0
- package/android/lc3Lib/third_party/opus_tools/src/README +0 -0
- package/android/lc3Lib/third_party/opus_tools/src/autogen.sh +115 -0
- package/android/lc3Lib/third_party/opus_tools/src/configure.ac +293 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/arch.h +239 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/audio-in.c +1046 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.c +245 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.h +28 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.c +320 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.h +51 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/lpc.c +157 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/lpc.h +27 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.c +286 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.h +59 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusdec.c +884 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.c +1021 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.h +101 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.c +639 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.h +51 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/os_support.h +167 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/resample.c +1137 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/speex_resampler.h +344 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/stack_alloc.h +115 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.c +125 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.h +62 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.c +223 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.h +60 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +528 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +610 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +1616 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +314 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +1710 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +554 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/ObservableStore.kt +68 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +158 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +934 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +175 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +1109 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +3974 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3551 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1327 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +6959 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1655 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +53675 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +202 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +224 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +340 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +465 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +221 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AES.java +106 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AudioSessionMonitor.kt +189 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BitmapJavaUtils.java +169 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +179 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +44 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/G1Text.kt +436 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleRelayNaming.java +29 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleUploadService.java +76 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/K900ProtocolUtils.java +791 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +186 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +589 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/PhoneAudioMonitor.kt +303 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/SmartGlassesConnectionState.java +9 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/ByteUtilAudioPlayer.java +655 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/Lc3Player.java +441 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/PCMAudioPlayer.java +431 -0
- package/android/src/main/res/values/strings.xml +4 -0
- package/app.plugin.js +1 -0
- package/build/BluetoothSdk.types.d.ts +498 -0
- package/build/BluetoothSdk.types.d.ts.map +1 -0
- package/build/BluetoothSdk.types.js +23 -0
- package/build/BluetoothSdk.types.js.map +1 -0
- package/build/BluetoothSdkModule.d.ts +71 -0
- package/build/BluetoothSdkModule.d.ts.map +1 -0
- package/build/BluetoothSdkModule.js +106 -0
- package/build/BluetoothSdkModule.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/BluetoothSdkModule.swift +665 -0
- package/ios/MentraBluetoothSDK.podspec +77 -0
- package/ios/Packages/CoreObjC/CoreObjC.xcodeproj/project.pbxproj +213 -0
- package/ios/Packages/CoreObjC/PcmConverter.h +22 -0
- package/ios/Packages/CoreObjC/PcmConverter.m +266 -0
- package/ios/Packages/CoreObjC/attdet.c +92 -0
- package/ios/Packages/CoreObjC/attdet.h +44 -0
- package/ios/Packages/CoreObjC/bits.c +375 -0
- package/ios/Packages/CoreObjC/bits.h +315 -0
- package/ios/Packages/CoreObjC/bwdet.c +129 -0
- package/ios/Packages/CoreObjC/bwdet.h +69 -0
- package/ios/Packages/CoreObjC/common.h +151 -0
- package/ios/Packages/CoreObjC/energy.c +70 -0
- package/ios/Packages/CoreObjC/energy.h +43 -0
- package/ios/Packages/CoreObjC/fastmath.h +158 -0
- package/ios/Packages/CoreObjC/lc3.c +704 -0
- package/ios/Packages/CoreObjC/lc3.h +313 -0
- package/ios/Packages/CoreObjC/lc3_cpp.h +283 -0
- package/ios/Packages/CoreObjC/lc3_private.h +163 -0
- package/ios/Packages/CoreObjC/ltpf.c +905 -0
- package/ios/Packages/CoreObjC/ltpf.h +111 -0
- package/ios/Packages/CoreObjC/ltpf_arm.h +506 -0
- package/ios/Packages/CoreObjC/ltpf_neon.h +281 -0
- package/ios/Packages/CoreObjC/makefile.mk +35 -0
- package/ios/Packages/CoreObjC/mdct.c +469 -0
- package/ios/Packages/CoreObjC/mdct.h +57 -0
- package/ios/Packages/CoreObjC/mdct_neon.h +296 -0
- package/ios/Packages/CoreObjC/meson.build +61 -0
- package/ios/Packages/CoreObjC/plc.c +61 -0
- package/ios/Packages/CoreObjC/plc.h +57 -0
- package/ios/Packages/CoreObjC/rnnoise.h +114 -0
- package/ios/Packages/CoreObjC/sns.c +880 -0
- package/ios/Packages/CoreObjC/sns.h +103 -0
- package/ios/Packages/CoreObjC/spec.c +907 -0
- package/ios/Packages/CoreObjC/spec.h +119 -0
- package/ios/Packages/CoreObjC/tables.c +3457 -0
- package/ios/Packages/CoreObjC/tables.h +94 -0
- package/ios/Packages/CoreObjC/tns.c +457 -0
- package/ios/Packages/CoreObjC/tns.h +99 -0
- package/ios/Packages/SherpaOnnx/Model/joiner.onnx +0 -0
- package/ios/Packages/SherpaOnnx/Model/tokens.txt +502 -0
- package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +1659 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +162 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +1852 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +674 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +44 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
- package/ios/Packages/VAD/Common/VAD/VADQuality.swift +41 -0
- package/ios/Packages/VAD/Common/VAD/VADState.swift +26 -0
- package/ios/Packages/VAD/Common/VAD/VADStrategy.swift +29 -0
- package/ios/Packages/VAD/Common/VAD/VADType.swift +14 -0
- package/ios/Packages/VAD/Data/Configuration.swift +68 -0
- package/ios/Packages/VAD/Data/FrameSize.swift +39 -0
- package/ios/Packages/VAD/Data/Record.swift +13 -0
- package/ios/Packages/VAD/Data/Result.swift +22 -0
- package/ios/Packages/VAD/Data/SampleRate.swift +48 -0
- package/ios/Packages/VAD/Silero/Model/silero_vad.onnx +0 -0
- package/ios/Packages/VAD/Silero/SileroVAD.swift +284 -0
- package/ios/Packages/VAD/Silero/SileroVADStrategy.swift +64 -0
- package/ios/Packages/libbz2/module.modulemap +5 -0
- package/ios/Packages/libbz2/shim.h +1 -0
- package/ios/Source/Bridge.swift +353 -0
- package/ios/Source/Bridging-Header.h +16 -0
- package/ios/Source/DeviceManager.swift +1478 -0
- package/ios/Source/DeviceStore.swift +295 -0
- package/ios/Source/MentraBluetoothSDK.swift +2439 -0
- package/ios/Source/ObservableStore.swift +88 -0
- package/ios/Source/PrivacyInfo.xcprivacy +23 -0
- package/ios/Source/controllers/ControllerManager.swift +187 -0
- package/ios/Source/controllers/R1.swift +827 -0
- package/ios/Source/services/PhoneMic.swift +662 -0
- package/ios/Source/sgcs/Frame.swift +651 -0
- package/ios/Source/sgcs/G1.swift +2505 -0
- package/ios/Source/sgcs/G2.swift +3730 -0
- package/ios/Source/sgcs/Mach1.swift +543 -0
- package/ios/Source/sgcs/MentraLive.swift +4708 -0
- package/ios/Source/sgcs/MentraNex.swift +2479 -0
- package/ios/Source/sgcs/SGCManager.swift +243 -0
- package/ios/Source/sgcs/Simulated.swift +270 -0
- package/ios/Source/sgcs/mentraos_ble.pb.swift +3811 -0
- package/ios/Source/stt/STTTools.swift +154 -0
- package/ios/Source/stt/SherpaOnnxTranscriber.swift +401 -0
- package/ios/Source/utils/AudioSessionMonitor.swift +283 -0
- package/ios/Source/utils/Constants.swift +74 -0
- package/ios/Source/utils/Enums.swift +95 -0
- package/ios/Source/utils/G1Text.swift +2067 -0
- package/ios/Source/utils/JSCExperiment.swift +241 -0
- package/ios/Source/utils/MemoryMonitor.swift +44 -0
- package/ios/Source/utils/MessageChunker.swift +164 -0
- package/ios/Source/utils/Models.swift +135 -0
- package/ios/Source/utils/PhoneAudioMonitor.swift +226 -0
- package/ios/Source/utils/TarBz2Extractor.swift +206 -0
- package/package.json +78 -0
- package/plugin/build/index.d.ts +6 -0
- package/plugin/build/index.js +12 -0
- package/plugin/build/withAndroid.d.ts +4 -0
- package/plugin/build/withAndroid.js +80 -0
- package/plugin/build/withIos.d.ts +4 -0
- package/plugin/build/withIos.js +64 -0
- package/src/BluetoothSdk.types.ts +581 -0
- package/src/BluetoothSdkModule.ts +259 -0
- package/src/index.ts +4 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */
|
|
2
|
+
/* Modified by Jean-Marc Valin */
|
|
3
|
+
/*
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions
|
|
6
|
+
are met:
|
|
7
|
+
|
|
8
|
+
- Redistributions of source code must retain the above copyright
|
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
- Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
|
13
|
+
documentation and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
16
|
+
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
17
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
18
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
19
|
+
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
20
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
21
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
22
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
23
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
24
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
*/
|
|
27
|
+
/* opus_types.h based on ogg_types.h from libogg */
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
@file opus_types.h
|
|
31
|
+
@brief Opus reference implementation types
|
|
32
|
+
*/
|
|
33
|
+
#ifndef OPUS_TYPES_H
|
|
34
|
+
#define OPUS_TYPES_H
|
|
35
|
+
|
|
36
|
+
#define opus_int int /* used for counters etc; at least 16 bits */
|
|
37
|
+
#define opus_int64 long long
|
|
38
|
+
#define opus_int8 signed char
|
|
39
|
+
|
|
40
|
+
#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
|
|
41
|
+
#define opus_uint64 unsigned long long
|
|
42
|
+
#define opus_uint8 unsigned char
|
|
43
|
+
|
|
44
|
+
/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
|
|
45
|
+
#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
|
|
46
|
+
#include <stdint.h>
|
|
47
|
+
# undef opus_int64
|
|
48
|
+
# undef opus_int8
|
|
49
|
+
# undef opus_uint64
|
|
50
|
+
# undef opus_uint8
|
|
51
|
+
typedef int8_t opus_int8;
|
|
52
|
+
typedef uint8_t opus_uint8;
|
|
53
|
+
typedef int16_t opus_int16;
|
|
54
|
+
typedef uint16_t opus_uint16;
|
|
55
|
+
typedef int32_t opus_int32;
|
|
56
|
+
typedef uint32_t opus_uint32;
|
|
57
|
+
typedef int64_t opus_int64;
|
|
58
|
+
typedef uint64_t opus_uint64;
|
|
59
|
+
#elif defined(_WIN32)
|
|
60
|
+
|
|
61
|
+
# if defined(__CYGWIN__)
|
|
62
|
+
# include <_G_config.h>
|
|
63
|
+
typedef _G_int32_t opus_int32;
|
|
64
|
+
typedef _G_uint32_t opus_uint32;
|
|
65
|
+
typedef _G_int16 opus_int16;
|
|
66
|
+
typedef _G_uint16 opus_uint16;
|
|
67
|
+
# elif defined(__MINGW32__)
|
|
68
|
+
typedef short opus_int16;
|
|
69
|
+
typedef unsigned short opus_uint16;
|
|
70
|
+
typedef int opus_int32;
|
|
71
|
+
typedef unsigned int opus_uint32;
|
|
72
|
+
# elif defined(__MWERKS__)
|
|
73
|
+
typedef int opus_int32;
|
|
74
|
+
typedef unsigned int opus_uint32;
|
|
75
|
+
typedef short opus_int16;
|
|
76
|
+
typedef unsigned short opus_uint16;
|
|
77
|
+
# else
|
|
78
|
+
/* MSVC/Borland */
|
|
79
|
+
typedef __int32 opus_int32;
|
|
80
|
+
typedef unsigned __int32 opus_uint32;
|
|
81
|
+
typedef __int16 opus_int16;
|
|
82
|
+
typedef unsigned __int16 opus_uint16;
|
|
83
|
+
# endif
|
|
84
|
+
|
|
85
|
+
#elif defined(__MACOS__)
|
|
86
|
+
|
|
87
|
+
# include <sys/types.h>
|
|
88
|
+
typedef SInt16 opus_int16;
|
|
89
|
+
typedef UInt16 opus_uint16;
|
|
90
|
+
typedef SInt32 opus_int32;
|
|
91
|
+
typedef UInt32 opus_uint32;
|
|
92
|
+
|
|
93
|
+
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
|
|
94
|
+
|
|
95
|
+
# include <sys/types.h>
|
|
96
|
+
typedef int16_t opus_int16;
|
|
97
|
+
typedef u_int16_t opus_uint16;
|
|
98
|
+
typedef int32_t opus_int32;
|
|
99
|
+
typedef u_int32_t opus_uint32;
|
|
100
|
+
|
|
101
|
+
#elif defined(__BEOS__)
|
|
102
|
+
|
|
103
|
+
/* Be */
|
|
104
|
+
# include <inttypes.h>
|
|
105
|
+
typedef int16 opus_int16;
|
|
106
|
+
typedef u_int16 opus_uint16;
|
|
107
|
+
typedef int32_t opus_int32;
|
|
108
|
+
typedef u_int32_t opus_uint32;
|
|
109
|
+
|
|
110
|
+
#elif defined (__EMX__)
|
|
111
|
+
|
|
112
|
+
/* OS/2 GCC */
|
|
113
|
+
typedef short opus_int16;
|
|
114
|
+
typedef unsigned short opus_uint16;
|
|
115
|
+
typedef int opus_int32;
|
|
116
|
+
typedef unsigned int opus_uint32;
|
|
117
|
+
|
|
118
|
+
#elif defined (DJGPP)
|
|
119
|
+
|
|
120
|
+
/* DJGPP */
|
|
121
|
+
typedef short opus_int16;
|
|
122
|
+
typedef unsigned short opus_uint16;
|
|
123
|
+
typedef int opus_int32;
|
|
124
|
+
typedef unsigned int opus_uint32;
|
|
125
|
+
|
|
126
|
+
#elif defined(R5900)
|
|
127
|
+
|
|
128
|
+
/* PS2 EE */
|
|
129
|
+
typedef int opus_int32;
|
|
130
|
+
typedef unsigned opus_uint32;
|
|
131
|
+
typedef short opus_int16;
|
|
132
|
+
typedef unsigned short opus_uint16;
|
|
133
|
+
|
|
134
|
+
#elif defined(__SYMBIAN32__)
|
|
135
|
+
|
|
136
|
+
/* Symbian GCC */
|
|
137
|
+
typedef signed short opus_int16;
|
|
138
|
+
typedef unsigned short opus_uint16;
|
|
139
|
+
typedef signed int opus_int32;
|
|
140
|
+
typedef unsigned int opus_uint32;
|
|
141
|
+
|
|
142
|
+
#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
|
|
143
|
+
|
|
144
|
+
typedef short opus_int16;
|
|
145
|
+
typedef unsigned short opus_uint16;
|
|
146
|
+
typedef long opus_int32;
|
|
147
|
+
typedef unsigned long opus_uint32;
|
|
148
|
+
|
|
149
|
+
#elif defined(CONFIG_TI_C6X)
|
|
150
|
+
|
|
151
|
+
typedef short opus_int16;
|
|
152
|
+
typedef unsigned short opus_uint16;
|
|
153
|
+
typedef int opus_int32;
|
|
154
|
+
typedef unsigned int opus_uint32;
|
|
155
|
+
|
|
156
|
+
#else
|
|
157
|
+
|
|
158
|
+
/* Give up, take a reasonable guess */
|
|
159
|
+
typedef short opus_int16;
|
|
160
|
+
typedef unsigned short opus_uint16;
|
|
161
|
+
typedef int opus_int32;
|
|
162
|
+
typedef unsigned int opus_uint32;
|
|
163
|
+
|
|
164
|
+
#endif
|
|
165
|
+
|
|
166
|
+
#endif /* OPUS_TYPES_H */
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2019 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#include "ogg_opus_encoder.h"
|
|
18
|
+
|
|
19
|
+
#include <cassert>
|
|
20
|
+
#include <endian.h>
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <string>
|
|
23
|
+
#include <cstdint>
|
|
24
|
+
#include "opus_tools/opus_header.h"
|
|
25
|
+
|
|
26
|
+
// Ogg Opus information comes from the standard here:
|
|
27
|
+
// https://tools.ietf.org/html/draft-ietf-codec-oggopus-14
|
|
28
|
+
// This was also a useful reference:
|
|
29
|
+
// https://github.com/krad-radio/butt-krad-opus/blob/302a4b6a6a596be6632f30cfb567a6a6d8fcb3f9/src/opus_encode.cpp
|
|
30
|
+
|
|
31
|
+
namespace audio_util {
|
|
32
|
+
namespace {
|
|
33
|
+
|
|
34
|
+
static constexpr float kEncodingBufferSizeSeconds = 0.02f;
|
|
35
|
+
|
|
36
|
+
std::string SerializeUint32(uint32_t value) {
|
|
37
|
+
std::string result(4, '\0');
|
|
38
|
+
#if __BYTE_ORDER == __BIG_ENDIAN
|
|
39
|
+
#error The following line assumes that the byte order is little endian.
|
|
40
|
+
#endif
|
|
41
|
+
memcpy(&result[0], &value, sizeof(value));
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
} // namespace
|
|
46
|
+
|
|
47
|
+
OggOpusEncoder::OggOpusEncoder(int num_channels, int sample_rate_hz,
|
|
48
|
+
int bitrate_bps, bool use_vbr,
|
|
49
|
+
bool low_latency_mode)
|
|
50
|
+
: num_channels_(num_channels),
|
|
51
|
+
sample_rate_hz_(sample_rate_hz),
|
|
52
|
+
frame_size_(kEncodingBufferSizeSeconds * sample_rate_hz_),
|
|
53
|
+
encoder_(OpusUniquePtr(
|
|
54
|
+
opus_encoder_create(sample_rate_hz_, num_channels_,
|
|
55
|
+
OPUS_APPLICATION_AUDIO, &error_code_),
|
|
56
|
+
opus_encoder_destroy)),
|
|
57
|
+
flushed_(false),
|
|
58
|
+
low_latency_mode_(low_latency_mode),
|
|
59
|
+
elements_in_pcm_frame_(0),
|
|
60
|
+
pcm_frame_(num_channels_ * frame_size_) {
|
|
61
|
+
assert(num_channels <= 2); // Only mono and stereo are supported).
|
|
62
|
+
std::vector<int> valid_sample_rates = {8000, 12000, 16000, 24000, 48000};
|
|
63
|
+
assert(std::find(valid_sample_rates.begin(), valid_sample_rates.end(),
|
|
64
|
+
sample_rate_hz) != valid_sample_rates.end());
|
|
65
|
+
assert(bitrate_bps >= 500);
|
|
66
|
+
assert(bitrate_bps <= 512000);
|
|
67
|
+
|
|
68
|
+
opus_encoder_ctl(encoder_.get(), OPUS_SET_BITRATE(bitrate_bps));
|
|
69
|
+
if (!use_vbr) {
|
|
70
|
+
opus_encoder_ctl(encoder_.get(), OPUS_SET_VBR(0));
|
|
71
|
+
}
|
|
72
|
+
constexpr int kComplexity = 4;
|
|
73
|
+
opus_encoder_ctl(encoder_.get(), OPUS_SET_COMPLEXITY(kComplexity));
|
|
74
|
+
|
|
75
|
+
// We will always pass exactly one frame at a time to the encoder.
|
|
76
|
+
opus_frame_.resize(kBytesPerSample * pcm_frame_.size());
|
|
77
|
+
|
|
78
|
+
// Start generating Ogg packets (though they don't get sent out until the
|
|
79
|
+
// first call to Encode()).
|
|
80
|
+
packet_count_ = 0;
|
|
81
|
+
granule_position_ = 0;
|
|
82
|
+
ogg_stream_init(&stream_, 0 /* serial number */);
|
|
83
|
+
GenerateOggPacketsForHeader();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
OggOpusEncoder::~OggOpusEncoder() {
|
|
87
|
+
ogg_stream_clear(&stream_);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Encodes 16-bit PCM data in OggOpus format.
|
|
91
|
+
const std::vector<unsigned char>& OggOpusEncoder::Process(
|
|
92
|
+
const std::vector<int16_t>& pcm) {
|
|
93
|
+
assert(!flushed_);
|
|
94
|
+
assert((pcm.size() % num_channels_) == 0);
|
|
95
|
+
if (!header_) {
|
|
96
|
+
ogg_bytes_.resize(0);
|
|
97
|
+
} else {
|
|
98
|
+
header_ = false;
|
|
99
|
+
}
|
|
100
|
+
int num_samples_processed = 0;
|
|
101
|
+
|
|
102
|
+
// Process the first block, handling any leftovers from a previous round.
|
|
103
|
+
if (elements_in_pcm_frame_ > 0) {
|
|
104
|
+
int entries_to_write =
|
|
105
|
+
std::min(pcm_frame_.size() - elements_in_pcm_frame_, pcm.size());
|
|
106
|
+
std::copy(pcm.begin(), pcm.begin() + entries_to_write,
|
|
107
|
+
pcm_frame_.begin() + elements_in_pcm_frame_);
|
|
108
|
+
elements_in_pcm_frame_ += entries_to_write;
|
|
109
|
+
if (elements_in_pcm_frame_ == pcm_frame_.size()) {
|
|
110
|
+
// pcm_frame_ is full, encode it.
|
|
111
|
+
int num_opus_frame_bytes =
|
|
112
|
+
opus_encode(encoder_.get(), pcm_frame_.data(), frame_size_,
|
|
113
|
+
opus_frame_.data(), opus_frame_.size());
|
|
114
|
+
|
|
115
|
+
assert(num_opus_frame_bytes >= 0);
|
|
116
|
+
GenerateOggPacketsForOpusFrame(opus_frame_.data(), num_opus_frame_bytes,
|
|
117
|
+
&ogg_bytes_, false);
|
|
118
|
+
num_samples_processed += entries_to_write;
|
|
119
|
+
pcm_frame_.assign(pcm_frame_.size(), 0);
|
|
120
|
+
elements_in_pcm_frame_ = 0;
|
|
121
|
+
} else {
|
|
122
|
+
// There's nothing to encode. We've put all of pcm data into pcm_frame_
|
|
123
|
+
// for later processing.
|
|
124
|
+
ogg_bytes_.resize(0);
|
|
125
|
+
return ogg_bytes_;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Process whole frames directly from pcm.
|
|
130
|
+
while (num_samples_processed + frame_size_ * num_channels_ <= pcm.size()) {
|
|
131
|
+
int num_opus_frame_bytes =
|
|
132
|
+
opus_encode(encoder_.get(), pcm.data() + num_samples_processed,
|
|
133
|
+
frame_size_, opus_frame_.data(), opus_frame_.size());
|
|
134
|
+
|
|
135
|
+
assert(num_opus_frame_bytes >= 0);
|
|
136
|
+
GenerateOggPacketsForOpusFrame(opus_frame_.data(), num_opus_frame_bytes,
|
|
137
|
+
&ogg_bytes_, false);
|
|
138
|
+
num_samples_processed += frame_size_ * num_channels_;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (low_latency_mode_) {
|
|
142
|
+
// Force the codec to produce samples for every input buffer.
|
|
143
|
+
AppendOggStateToBuffer(&ogg_bytes_, true);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Place any remaining samples in pcm_frame_.
|
|
147
|
+
elements_in_pcm_frame_ = pcm.size() - num_samples_processed;
|
|
148
|
+
std::copy(pcm.begin() + num_samples_processed, pcm.end(), pcm_frame_.begin());
|
|
149
|
+
return ogg_bytes_;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Returns any remaining samples from the codec.
|
|
153
|
+
const std::vector<unsigned char>& OggOpusEncoder::Flush() {
|
|
154
|
+
assert(!flushed_);
|
|
155
|
+
ogg_bytes_.resize(0);
|
|
156
|
+
int num_opus_frame_bytes =
|
|
157
|
+
opus_encode(encoder_.get(), pcm_frame_.data(), frame_size_,
|
|
158
|
+
opus_frame_.data(), opus_frame_.size());
|
|
159
|
+
assert(num_opus_frame_bytes >= 0);
|
|
160
|
+
GenerateOggPacketsForOpusFrame(opus_frame_.data(), num_opus_frame_bytes,
|
|
161
|
+
&ogg_bytes_, true);
|
|
162
|
+
flushed_ = true;
|
|
163
|
+
return ogg_bytes_;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
void OggOpusEncoder::GenerateOggPacketsForHeader() {
|
|
167
|
+
// Both header packets must have granule position of zero.
|
|
168
|
+
assert(granule_position_ == 0);
|
|
169
|
+
OpusHeader header;
|
|
170
|
+
header.version = 1;
|
|
171
|
+
header.channels = num_channels_;
|
|
172
|
+
opus_encoder_ctl(encoder_.get(), OPUS_GET_LOOKAHEAD(&header.preskip));
|
|
173
|
+
header.input_sample_rate = sample_rate_hz_;
|
|
174
|
+
header.gain = 0;
|
|
175
|
+
header.channel_mapping = 0;
|
|
176
|
+
|
|
177
|
+
// Write the ID header.
|
|
178
|
+
ogg_packet id_packet;
|
|
179
|
+
id_packet.b_o_s = 1; // The first packet.
|
|
180
|
+
id_packet.e_o_s = 0;
|
|
181
|
+
id_packet.granulepos = granule_position_;
|
|
182
|
+
id_packet.packetno = packet_count_;
|
|
183
|
+
constexpr int kHeaderSizeUpperBound = 64;
|
|
184
|
+
id_packet.packet = new unsigned char[kHeaderSizeUpperBound];
|
|
185
|
+
// opus_header_to_packet fills id_packet.packet with header data and returns
|
|
186
|
+
// the number of bytes.
|
|
187
|
+
id_packet.bytes =
|
|
188
|
+
opus_header_to_packet(&header, id_packet.packet, kHeaderSizeUpperBound);
|
|
189
|
+
// Add the ID packet into the stream.
|
|
190
|
+
packet_count_++;
|
|
191
|
+
ogg_stream_packetin(&stream_, &id_packet);
|
|
192
|
+
|
|
193
|
+
// Write the comment header.
|
|
194
|
+
ogg_packet comment_packet;
|
|
195
|
+
comment_packet.b_o_s = 0;
|
|
196
|
+
comment_packet.e_o_s = 0;
|
|
197
|
+
comment_packet.granulepos = granule_position_;
|
|
198
|
+
comment_packet.packetno = packet_count_;
|
|
199
|
+
const std::string kVendor = "Google using libopus";
|
|
200
|
+
std::string packet = "";
|
|
201
|
+
packet.append("OpusTags");
|
|
202
|
+
packet.append(SerializeUint32(kVendor.size()));
|
|
203
|
+
packet.append(kVendor);
|
|
204
|
+
packet.append(SerializeUint32(0));
|
|
205
|
+
comment_packet.packet = const_cast<unsigned char*>(
|
|
206
|
+
reinterpret_cast<const unsigned char*>(packet.c_str()));
|
|
207
|
+
comment_packet.bytes = packet.length();
|
|
208
|
+
|
|
209
|
+
// Add the comment header into the stream.
|
|
210
|
+
packet_count_++;
|
|
211
|
+
ogg_stream_packetin(&stream_, &comment_packet);
|
|
212
|
+
// Force a page break after the comment header.
|
|
213
|
+
// According to
|
|
214
|
+
// https://tools.ietf.org/html/draft-ietf-codec-oggopus-14#section-3 there is
|
|
215
|
+
// a mandatory page break after the comment header.
|
|
216
|
+
AppendOggStateToBuffer(&ogg_bytes_, true);
|
|
217
|
+
header_ = true;
|
|
218
|
+
|
|
219
|
+
delete[] id_packet.packet;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
void OggOpusEncoder::GenerateOggPacketsForOpusFrame(
|
|
223
|
+
unsigned char* opus_frame_bytes, int opus_bytes_length,
|
|
224
|
+
std::vector<unsigned char>* ogg_bytes, bool flush) {
|
|
225
|
+
// Flush data from the ogg object into the outgoing stream.
|
|
226
|
+
AppendOggStateToBuffer(ogg_bytes, flush);
|
|
227
|
+
|
|
228
|
+
// Write the most recent buffer of Opus data into an Ogg packet.
|
|
229
|
+
ogg_packet frame_packet;
|
|
230
|
+
frame_packet.b_o_s = 0;
|
|
231
|
+
frame_packet.e_o_s = flush ? 1 : 0;
|
|
232
|
+
// According to
|
|
233
|
+
// https://tools.ietf.org/html/draft-ietf-codec-oggopus-14#section-4 the
|
|
234
|
+
// granule position should include all samples up to the last packet completed
|
|
235
|
+
// on the page, so we need to update granule_position_ before assigning it to
|
|
236
|
+
// the packet. If we're closing the stream, we don't assume that the last
|
|
237
|
+
// packet includes a full frame.
|
|
238
|
+
if (flush) {
|
|
239
|
+
granule_position_ += (elements_in_pcm_frame_ / num_channels_);
|
|
240
|
+
} else {
|
|
241
|
+
granule_position_ += frame_size_;
|
|
242
|
+
}
|
|
243
|
+
frame_packet.granulepos = granule_position_;
|
|
244
|
+
frame_packet.packetno = packet_count_;
|
|
245
|
+
frame_packet.packet = opus_frame_bytes;
|
|
246
|
+
frame_packet.bytes = opus_bytes_length;
|
|
247
|
+
// Add the data packet into the stream.
|
|
248
|
+
packet_count_++;
|
|
249
|
+
ogg_stream_packetin(&stream_, &frame_packet);
|
|
250
|
+
|
|
251
|
+
// Try flushing again after data packet.
|
|
252
|
+
AppendOggStateToBuffer(ogg_bytes, flush);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
void OggOpusEncoder::AppendOggStateToBuffer(std::vector<unsigned char>* buffer,
|
|
256
|
+
bool flush_ogg_stream) {
|
|
257
|
+
int (*write_fun)(ogg_stream_state*, ogg_page*) =
|
|
258
|
+
flush_ogg_stream ? &ogg_stream_flush : &ogg_stream_pageout;
|
|
259
|
+
while (write_fun(&stream_, &page_) != 0) {
|
|
260
|
+
const int initial_size = buffer->size();
|
|
261
|
+
buffer->resize(buffer->size() + page_.header_len + page_.body_len);
|
|
262
|
+
memcpy(buffer->data() + initial_size, page_.header, page_.header_len);
|
|
263
|
+
memcpy(buffer->data() + initial_size + page_.header_len, page_.body,
|
|
264
|
+
page_.body_len);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
} // namespace audio_util
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2019 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef AUDIO_UTIL_OGG_OPUS_ENCODER_H_
|
|
18
|
+
#define AUDIO_UTIL_OGG_OPUS_ENCODER_H_
|
|
19
|
+
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <string>
|
|
23
|
+
#include <vector>
|
|
24
|
+
#include "libogg/ogg.h"
|
|
25
|
+
#include "libopus/opus.h"
|
|
26
|
+
|
|
27
|
+
namespace audio_util {
|
|
28
|
+
|
|
29
|
+
// This class is meant to be a dependency-light streaming encoder.
|
|
30
|
+
//
|
|
31
|
+
// Encoding is done internally on a block size of 20ms, which seems to be the
|
|
32
|
+
// recommended size for Opus encoding.
|
|
33
|
+
class OggOpusEncoder {
|
|
34
|
+
public:
|
|
35
|
+
// Input is int16 data.
|
|
36
|
+
constexpr static int kBytesPerSample = 2;
|
|
37
|
+
constexpr static int kBitsPerSample = 16;
|
|
38
|
+
|
|
39
|
+
// num_channels must be 1 or 2.
|
|
40
|
+
// sample rate must be one of {8000, 12000, 16000, 24000, 48000}
|
|
41
|
+
// Note that low_latency_mode will increase the total number of Ogg packets,
|
|
42
|
+
// but will reduce overall latency of the codec. This does not impact the
|
|
43
|
+
// quality of audio compression, only how the data is packaged in the Ogg
|
|
44
|
+
// container. Low latency mode is only recommended for realtime streaming
|
|
45
|
+
// applications. See test for actual bitrate increases.
|
|
46
|
+
OggOpusEncoder(int num_channels, int sample_rate_hz, int bitrate_bps,
|
|
47
|
+
bool use_vbr, bool low_latency_mode);
|
|
48
|
+
|
|
49
|
+
~OggOpusEncoder();
|
|
50
|
+
|
|
51
|
+
// Encodes 16-bit PCM data in OggOpus format. There is no restriction on the
|
|
52
|
+
// size of the input vector.
|
|
53
|
+
// Note that it is very common for the returned vector to be empty. Keep
|
|
54
|
+
// calling this function with new samples until they become available.
|
|
55
|
+
const std::vector<unsigned char>& Process(const std::vector<int16_t>& pcm);
|
|
56
|
+
|
|
57
|
+
// Returns any remaining samples from the codec. This should be called last,
|
|
58
|
+
// and never more than once.
|
|
59
|
+
const std::vector<unsigned char>& Flush();
|
|
60
|
+
|
|
61
|
+
private:
|
|
62
|
+
using OpusUniquePtr =
|
|
63
|
+
std::unique_ptr<OpusEncoder, decltype(&opus_encoder_destroy)>;
|
|
64
|
+
|
|
65
|
+
std::string GetOpusErrorMessage() const;
|
|
66
|
+
|
|
67
|
+
// Push the Opus header details into the ogg stream.
|
|
68
|
+
void GenerateOggPacketsForHeader();
|
|
69
|
+
|
|
70
|
+
// Push data from a single Opus frame into an Ogg stream.
|
|
71
|
+
void GenerateOggPacketsForOpusFrame(unsigned char* opus_frame_bytes,
|
|
72
|
+
int opus_bytes_length,
|
|
73
|
+
std::vector<unsigned char>* ogg_bytes,
|
|
74
|
+
bool flush);
|
|
75
|
+
|
|
76
|
+
// Moves data from the stream_ object into buffer.
|
|
77
|
+
void AppendOggStateToBuffer(std::vector<unsigned char>* buffer, bool flush);
|
|
78
|
+
|
|
79
|
+
int num_channels_;
|
|
80
|
+
int sample_rate_hz_;
|
|
81
|
+
int bitrate_bps_;
|
|
82
|
+
|
|
83
|
+
// Number of samples in an Opus 20ms frame for a single channel.
|
|
84
|
+
int frame_size_;
|
|
85
|
+
OpusUniquePtr encoder_;
|
|
86
|
+
|
|
87
|
+
// Stores the status of Opus codec initialization.
|
|
88
|
+
int error_code_;
|
|
89
|
+
|
|
90
|
+
// Checks that Flush() isn't called multiple times.
|
|
91
|
+
bool flushed_;
|
|
92
|
+
bool header_;
|
|
93
|
+
|
|
94
|
+
// When true, flushing of the Ogg stream after every call to Process().
|
|
95
|
+
bool low_latency_mode_;
|
|
96
|
+
|
|
97
|
+
// A preallocated buffer to store the temporary OGG result.
|
|
98
|
+
std::vector<unsigned char> opus_frame_;
|
|
99
|
+
|
|
100
|
+
std::vector<unsigned char> ogg_bytes_;
|
|
101
|
+
|
|
102
|
+
// A stored buffer for a single frame of PCM data to be processed.
|
|
103
|
+
int elements_in_pcm_frame_;
|
|
104
|
+
std::vector<opus_int16> pcm_frame_;
|
|
105
|
+
|
|
106
|
+
// Ogg objects.
|
|
107
|
+
ogg_stream_state stream_;
|
|
108
|
+
ogg_page page_;
|
|
109
|
+
int packet_count_; // Count of packets pushed to the stream.
|
|
110
|
+
int granule_position_; // Position in the ogg stream.
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
} // namespace audio_util
|
|
114
|
+
|
|
115
|
+
#endif // AUDIO_UTIL_OGG_OPUS_ENCODER_H_
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* Copyright (C)2012 Xiph.Org Foundation
|
|
2
|
+
File: opus_header.h
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions
|
|
6
|
+
are met:
|
|
7
|
+
|
|
8
|
+
- Redistributions of source code must retain the above copyright
|
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
- Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
|
13
|
+
documentation and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
16
|
+
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
17
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
18
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
|
19
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
20
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
21
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
22
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
23
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
24
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#ifndef OPUS_HEADER_H
|
|
29
|
+
#define OPUS_HEADER_H
|
|
30
|
+
|
|
31
|
+
#include "../libogg/ogg.h"
|
|
32
|
+
|
|
33
|
+
#ifdef __cplusplus
|
|
34
|
+
extern "C" {
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
typedef struct {
|
|
38
|
+
int version;
|
|
39
|
+
int channels; /* Number of channels: 1..255 */
|
|
40
|
+
int preskip;
|
|
41
|
+
ogg_uint32_t input_sample_rate;
|
|
42
|
+
int gain; /* in dB S7.8 should be zero whenever possible */
|
|
43
|
+
int channel_mapping;
|
|
44
|
+
/* The rest is only used if channel_mapping != 0 */
|
|
45
|
+
int nb_streams;
|
|
46
|
+
int nb_coupled;
|
|
47
|
+
unsigned char stream_map[255];
|
|
48
|
+
} OpusHeader;
|
|
49
|
+
|
|
50
|
+
int opus_header_parse(const unsigned char *header, int len, OpusHeader *h);
|
|
51
|
+
int opus_header_to_packet(const OpusHeader *h, unsigned char *packet, int len);
|
|
52
|
+
|
|
53
|
+
extern const int wav_permute_matrix[8][8];
|
|
54
|
+
|
|
55
|
+
#ifdef __cplusplus
|
|
56
|
+
}
|
|
57
|
+
#endif
|
|
58
|
+
|
|
59
|
+
#endif
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
cmake_minimum_required(VERSION 3.18.1)
|
|
3
|
+
|
|
4
|
+
project("lc3")
|
|
5
|
+
|
|
6
|
+
include_directories(include)
|
|
7
|
+
#add_subdirectory(liblc3)
|
|
8
|
+
add_library(${CMAKE_PROJECT_NAME} SHARED
|
|
9
|
+
# List C/C++ source files with relative paths to this CMakeLists.txt.
|
|
10
|
+
liblc3.cpp
|
|
11
|
+
|
|
12
|
+
liblc3/attdet.c
|
|
13
|
+
liblc3/bits.c
|
|
14
|
+
liblc3/bwdet.c
|
|
15
|
+
liblc3/energy.c
|
|
16
|
+
liblc3/lc3.c
|
|
17
|
+
liblc3/ltpf.c
|
|
18
|
+
liblc3/mdct.c
|
|
19
|
+
liblc3/plc.c
|
|
20
|
+
liblc3/sns.c
|
|
21
|
+
liblc3/spec.c
|
|
22
|
+
liblc3/tables.c
|
|
23
|
+
liblc3/tns.c
|
|
24
|
+
|
|
25
|
+
rnnoise/celt_lpc.c
|
|
26
|
+
rnnoise/denoise.c
|
|
27
|
+
rnnoise/kiss_fft.c
|
|
28
|
+
rnnoise/pitch.c
|
|
29
|
+
rnnoise/rnn.c
|
|
30
|
+
rnnoise/rnn_data.c
|
|
31
|
+
rnnoise/rnn_reader.c
|
|
32
|
+
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
target_link_libraries(${CMAKE_PROJECT_NAME}
|
|
36
|
+
# List libraries link to the target library
|
|
37
|
+
android
|
|
38
|
+
log)
|