@siteed/audio-studio 3.0.3 → 3.0.5
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/CHANGELOG.md +17 -1
- package/android/src/main/java/net/siteed/audiostudio/AudioRecorderManager.kt +59 -51
- package/android/src/main/java/net/siteed/audiostudio/AudioStudioModule.kt +500 -485
- package/build/cjs/AudioAnalysis/wasmConfig.js.map +1 -1
- package/build/cjs/AudioAnalysis/wasmLoader.web.js +2 -1
- package/build/cjs/AudioAnalysis/wasmLoader.web.js.map +1 -1
- package/build/cjs/trimAudio.js.map +1 -1
- package/build/esm/AudioAnalysis/wasmConfig.js.map +1 -1
- package/build/esm/AudioAnalysis/wasmLoader.web.js +2 -1
- package/build/esm/AudioAnalysis/wasmLoader.web.js.map +1 -1
- package/build/esm/trimAudio.js.map +1 -1
- package/build/types/AudioAnalysis/wasmLoader.web.d.ts.map +1 -1
- package/build/types/trimAudio.d.ts.map +1 -1
- package/ios/AudioStreamManager.swift +135 -89
- package/ios/AudioStudioModule.swift +239 -216
- package/package.json +1 -1
- package/src/AudioAnalysis/wasmConfig.ts +1 -1
- package/src/AudioAnalysis/wasmLoader.web.ts +8 -3
- package/src/trimAudio.ts +19 -5
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
## [3.0.5] - 2026-04-25
|
|
12
|
+
### Changed
|
|
13
|
+
- fix(audio-studio): don't start notification on prepareRecording (Android) (#364) ([5d40d7e](https://github.com/deeeed/audiolab/commit/5d40d7e730f2b74459d319979fd9c112891b10f2))
|
|
14
|
+
- docs: update api references for v3.0.4 ([12421ee](https://github.com/deeeed/audiolab/commit/12421ee6146187888492b957c0eee428fcab3e8b))
|
|
15
|
+
- chore(audio-studio): release @siteed/audio-studio@3.0.4 ([3a5b7da](https://github.com/deeeed/audiolab/commit/3a5b7da8f4289a599d928dce01f262ab97398143))
|
|
16
|
+
## [3.0.4] - 2026-04-25
|
|
17
|
+
### Changed
|
|
18
|
+
- fix(audio-studio): move module ops off main thread + fix iOS stop crash (#363) ([1a07d2d](https://github.com/deeeed/audiolab/commit/1a07d2d9222bfac1083b00d6de992fcb2a3be42d))
|
|
19
|
+
- chore(audio-studio): release @siteed/audio-studio@3.0.3 ([9d4d14e](https://github.com/deeeed/audiolab/commit/9d4d14e8dffd4378a71f2d3dfb5d7140b8248c0f))
|
|
20
|
+
- fix(audio-studio): convert trim ranges from Double to Long on Android (#347) (#360) ([6099e0e](https://github.com/deeeed/audiolab/commit/6099e0e81f3c8d7b1c109b415ad63e924f3f043b))
|
|
21
|
+
- feat(audio-studio): web trimAudio, WASM refactor, new utilities (#344) ([3d4862a](https://github.com/deeeed/audiolab/commit/3d4862a57a5eb2496169d27f758d7628d7d3659a))
|
|
22
|
+
- feat(sherpa-voice): comprehensive logging + fix Android prod model extraction (#342) ([5b20594](https://github.com/deeeed/audiolab/commit/5b20594c729a9deb703cbc2e23c07daa616149ab))
|
|
23
|
+
- fix(audio-studio): remove blocking CDN poll from publish.sh, sync wasmConfig to 3.0.2 ([290409a](https://github.com/deeeed/audiolab/commit/290409aae8d1160e1952a5ee1961ce3864fbb0c8))
|
|
24
|
+
- chore(audio-studio): release @siteed/audio-studio@3.0.2 ([ebd3300](https://github.com/deeeed/audiolab/commit/ebd330098d2756e6d5a555126e2dfc3fb038d155))
|
|
11
25
|
## [3.0.3] - 2026-04-12
|
|
12
26
|
### Changed
|
|
13
27
|
- fix(audio-studio): convert trim ranges from Double to Long on Android (#347) (#360) ([6099e0e](https://github.com/deeeed/audiolab/commit/6099e0e81f3c8d7b1c109b415ad63e924f3f043b))
|
|
@@ -335,7 +349,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
335
349
|
- Audio features extraction during recording
|
|
336
350
|
- Consistent WAV PCM recording format across all platforms
|
|
337
351
|
|
|
338
|
-
[unreleased]: https://github.com/deeeed/audiolab/compare/@siteed/audio-studio@3.0.
|
|
352
|
+
[unreleased]: https://github.com/deeeed/audiolab/compare/@siteed/audio-studio@3.0.5...HEAD
|
|
353
|
+
[3.0.5]: https://github.com/deeeed/audiolab/compare/@siteed/audio-studio@3.0.4...@siteed/audio-studio@3.0.5
|
|
354
|
+
[3.0.4]: https://github.com/deeeed/audiolab/compare/@siteed/audio-studio@3.0.3...@siteed/audio-studio@3.0.4
|
|
339
355
|
[3.0.3]: https://github.com/deeeed/audiolab/compare/@siteed/audio-studio@3.0.2...@siteed/audio-studio@3.0.3
|
|
340
356
|
[3.0.2]: https://github.com/deeeed/audiolab/compare/@siteed/audio-studio@3.0.2-beta.2...@siteed/audio-studio@3.0.2
|
|
341
357
|
[3.0.1]: https://github.com/deeeed/audiolab/compare/@siteed/audio-studio@3.0.0...@siteed/audio-studio@3.0.1
|
|
@@ -455,49 +455,55 @@ class AudioRecorderManager(
|
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
private fun initializePhoneStateListener() {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
458
|
+
// The legacy PhoneStateListener (API < 31) requires a Looper on the
|
|
459
|
+
// thread that constructs it; calling listen() also expects the same.
|
|
460
|
+
// prepareRecording now runs on Dispatchers.IO (no Looper), so we
|
|
461
|
+
// marshal the whole registration to the main thread's Looper. The
|
|
462
|
+
// API 31+ path uses context.mainExecutor and is thread-safe, but we
|
|
463
|
+
// route everything through main for consistency.
|
|
464
|
+
android.os.Handler(android.os.Looper.getMainLooper()).post {
|
|
465
|
+
try {
|
|
466
|
+
LogUtils.d(CLASS_NAME, "Initializing phone state listener...")
|
|
467
|
+
|
|
468
|
+
if (permissionUtils.checkPhoneStatePermission()) {
|
|
469
|
+
LogUtils.d(CLASS_NAME, "Phone state permission granted")
|
|
470
|
+
|
|
471
|
+
val localTelephonyManager = telephonyManager
|
|
472
|
+
if (localTelephonyManager != null) {
|
|
473
|
+
try {
|
|
474
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
475
|
+
val callback = object : TelephonyCallback(), TelephonyCallback.CallStateListener {
|
|
476
|
+
override fun onCallStateChanged(state: Int) {
|
|
477
|
+
handleCallStateChanged(state)
|
|
478
|
+
}
|
|
472
479
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
handleCallStateChanged(state)
|
|
480
|
+
telephonyCallback = callback
|
|
481
|
+
localTelephonyManager.registerTelephonyCallback(context.mainExecutor, callback)
|
|
482
|
+
LogUtils.d(CLASS_NAME, "Successfully registered TelephonyCallback (API 31+)")
|
|
483
|
+
} else {
|
|
484
|
+
phoneStateListener = object : PhoneStateListener() {
|
|
485
|
+
@Deprecated("Deprecated in API 31")
|
|
486
|
+
override fun onCallStateChanged(state: Int, phoneNumber: String?) {
|
|
487
|
+
handleCallStateChanged(state)
|
|
488
|
+
}
|
|
483
489
|
}
|
|
490
|
+
localTelephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
|
|
491
|
+
LogUtils.d(CLASS_NAME, "Successfully registered PhoneStateListener (legacy)")
|
|
484
492
|
}
|
|
485
|
-
|
|
486
|
-
LogUtils.
|
|
493
|
+
} catch (e: SecurityException) {
|
|
494
|
+
LogUtils.w(CLASS_NAME, "Missing permission for phone state listener: ${e.message}")
|
|
495
|
+
} catch (e: Exception) {
|
|
496
|
+
LogUtils.e(CLASS_NAME, "Failed to register phone state listener", e)
|
|
487
497
|
}
|
|
488
|
-
}
|
|
489
|
-
LogUtils.w(CLASS_NAME, "
|
|
490
|
-
} catch (e: Exception) {
|
|
491
|
-
LogUtils.e(CLASS_NAME, "Failed to register phone state listener", e)
|
|
498
|
+
} else {
|
|
499
|
+
LogUtils.w(CLASS_NAME, "TelephonyManager is null, phone call interruption handling disabled (device may not have telephony service)")
|
|
492
500
|
}
|
|
493
501
|
} else {
|
|
494
|
-
LogUtils.w(CLASS_NAME, "
|
|
502
|
+
LogUtils.w(CLASS_NAME, "READ_PHONE_STATE permission not granted, phone call interruption handling disabled")
|
|
495
503
|
}
|
|
496
|
-
}
|
|
497
|
-
LogUtils.
|
|
504
|
+
} catch (e: Exception) {
|
|
505
|
+
LogUtils.e(CLASS_NAME, "Failed to initialize phone state listener", e)
|
|
498
506
|
}
|
|
499
|
-
} catch (e: Exception) {
|
|
500
|
-
LogUtils.e(CLASS_NAME, "Failed to initialize phone state listener", e)
|
|
501
507
|
}
|
|
502
508
|
}
|
|
503
509
|
|
|
@@ -903,12 +909,6 @@ class AudioRecorderManager(
|
|
|
903
909
|
LogUtils.d(CLASS_NAME, "Skipping primary file creation - primary output is disabled")
|
|
904
910
|
}
|
|
905
911
|
|
|
906
|
-
if (recordingConfig.showNotification && enableBackgroundAudio) {
|
|
907
|
-
notificationManager.initialize(recordingConfig)
|
|
908
|
-
notificationManager.startUpdates(System.currentTimeMillis())
|
|
909
|
-
AudioRecordingService.startService(context)
|
|
910
|
-
}
|
|
911
|
-
|
|
912
912
|
acquireWakeLock()
|
|
913
913
|
audioProcessor.resetCumulativeAmplitudeRange()
|
|
914
914
|
return true
|
|
@@ -954,20 +954,28 @@ class AudioRecorderManager(
|
|
|
954
954
|
|
|
955
955
|
audioRecord?.startRecording()
|
|
956
956
|
isPaused.set(false)
|
|
957
|
-
_isRecording.set(true)
|
|
958
957
|
isFirstChunk = true
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
958
|
+
recordingStartTime = System.currentTimeMillis()
|
|
959
|
+
|
|
960
|
+
// Start notification + foreground service before flipping isRecording (#298, #288).
|
|
961
|
+
// Previously the notification block fired in initializeRecordingResources, which is
|
|
962
|
+
// also reached from prepareRecording, so the notification timer started on prepare.
|
|
963
|
+
// Mirrors iOS fix in AudioStreamManager.swift. Service start is shared by both
|
|
964
|
+
// showNotification and keepAwake gates and must precede _isRecording=true so
|
|
965
|
+
// getStatus() can't observe (isRecording=true && !isServiceRunning).
|
|
966
|
+
val needsService = (recordingConfig.showNotification || recordingConfig.keepAwake) &&
|
|
967
|
+
enableBackgroundAudio
|
|
968
|
+
if (recordingConfig.showNotification && enableBackgroundAudio) {
|
|
969
|
+
notificationManager.initialize(recordingConfig)
|
|
970
|
+
notificationManager.startUpdates(recordingStartTime)
|
|
962
971
|
}
|
|
963
|
-
|
|
964
|
-
recordingThread = Thread { recordingProcess() }.apply { start() }
|
|
965
|
-
|
|
966
|
-
// Start service if keepAwake is true, but only if background audio is enabled (#288)
|
|
967
|
-
if (recordingConfig.keepAwake && enableBackgroundAudio) {
|
|
972
|
+
if (needsService) {
|
|
968
973
|
AudioRecordingService.startService(context)
|
|
969
974
|
}
|
|
970
|
-
|
|
975
|
+
|
|
976
|
+
_isRecording.set(true)
|
|
977
|
+
recordingThread = Thread { recordingProcess() }.apply { start() }
|
|
978
|
+
|
|
971
979
|
return true
|
|
972
980
|
|
|
973
981
|
} catch (e: Exception) {
|