@siteed/audio-studio 3.0.2 → 3.0.4
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 +19 -1
- package/android/src/main/java/net/siteed/audiostudio/AudioRecorderManager.kt +41 -35
- package/android/src/main/java/net/siteed/audiostudio/AudioStudioModule.kt +500 -479
- package/build/cjs/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.js +10 -7
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.js.map +1 -1
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js +78 -97
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -1
- package/build/cjs/AudioAnalysis/extractAudioAnalysis.js +15 -12
- package/build/cjs/AudioAnalysis/extractAudioAnalysis.js.map +1 -1
- package/build/cjs/AudioAnalysis/extractAudioData.js +144 -2
- package/build/cjs/AudioAnalysis/extractAudioData.js.map +1 -1
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js +9 -56
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -1
- package/build/cjs/AudioAnalysis/wasmConfig.js +4 -4
- package/build/cjs/AudioAnalysis/wasmConfig.js.map +1 -1
- package/build/cjs/AudioAnalysis/wasmLoader.web.js +79 -0
- package/build/cjs/AudioAnalysis/wasmLoader.web.js.map +1 -0
- package/build/cjs/AudioStudioModule.js +4 -599
- package/build/cjs/AudioStudioModule.js.map +1 -1
- package/build/cjs/trimAudio.js +227 -0
- package/build/cjs/trimAudio.js.map +1 -1
- package/build/cjs/utils/encodeCompressedAudio.web.js +65 -0
- package/build/cjs/utils/encodeCompressedAudio.web.js.map +1 -0
- package/build/cjs/utils/resampleAudioBuffer.web.js +25 -0
- package/build/cjs/utils/resampleAudioBuffer.web.js.map +1 -0
- package/build/esm/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
- package/build/esm/AudioAnalysis/audioFeaturesWasm.js +8 -5
- package/build/esm/AudioAnalysis/audioFeaturesWasm.js.map +1 -1
- package/build/esm/AudioAnalysis/audioFeaturesWasm.web.js +76 -62
- package/build/esm/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -1
- package/build/esm/AudioAnalysis/extractAudioAnalysis.js +15 -12
- package/build/esm/AudioAnalysis/extractAudioAnalysis.js.map +1 -1
- package/build/esm/AudioAnalysis/extractAudioData.js +144 -2
- package/build/esm/AudioAnalysis/extractAudioData.js.map +1 -1
- package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js +9 -23
- package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -1
- package/build/esm/AudioAnalysis/wasmConfig.js +4 -4
- package/build/esm/AudioAnalysis/wasmConfig.js.map +1 -1
- package/build/esm/AudioAnalysis/wasmLoader.web.js +43 -0
- package/build/esm/AudioAnalysis/wasmLoader.web.js.map +1 -0
- package/build/esm/AudioStudioModule.js +4 -596
- package/build/esm/AudioStudioModule.js.map +1 -1
- package/build/esm/trimAudio.js +227 -0
- package/build/esm/trimAudio.js.map +1 -1
- package/build/esm/utils/encodeCompressedAudio.web.js +62 -0
- package/build/esm/utils/encodeCompressedAudio.web.js.map +1 -0
- package/build/esm/utils/resampleAudioBuffer.web.js +22 -0
- package/build/esm/utils/resampleAudioBuffer.web.js.map +1 -0
- package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts +11 -0
- package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -1
- package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts +5 -9
- package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts.map +1 -1
- package/build/types/AudioAnalysis/audioFeaturesWasm.web.d.ts +35 -16
- package/build/types/AudioAnalysis/audioFeaturesWasm.web.d.ts.map +1 -1
- package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -1
- package/build/types/AudioAnalysis/extractAudioData.d.ts +2 -2
- package/build/types/AudioAnalysis/extractAudioData.d.ts.map +1 -1
- package/build/types/AudioAnalysis/melSpectrogramWasm.web.d.ts.map +1 -1
- package/build/types/AudioAnalysis/wasmLoader.web.d.ts +3 -0
- package/build/types/AudioAnalysis/wasmLoader.web.d.ts.map +1 -0
- package/build/types/AudioStudioModule.d.ts.map +1 -1
- package/build/types/trimAudio.d.ts.map +1 -1
- package/build/types/utils/encodeCompressedAudio.web.d.ts +10 -0
- package/build/types/utils/encodeCompressedAudio.web.d.ts.map +1 -0
- package/build/types/utils/resampleAudioBuffer.web.d.ts +2 -0
- package/build/types/utils/resampleAudioBuffer.web.d.ts.map +1 -0
- package/ios/AudioStreamManager.swift +135 -89
- package/ios/AudioStudioModule.swift +239 -216
- package/package.json +1 -1
- package/src/AudioAnalysis/AudioAnalysis.types.ts +12 -0
- package/src/AudioAnalysis/audioFeaturesWasm.ts +17 -22
- package/src/AudioAnalysis/audioFeaturesWasm.web.ts +102 -94
- package/src/AudioAnalysis/extractAudioAnalysis.ts +23 -20
- package/src/AudioAnalysis/extractAudioData.ts +186 -4
- package/src/AudioAnalysis/melSpectrogramWasm.web.ts +10 -27
- package/src/AudioAnalysis/wasmConfig.ts +4 -4
- package/src/AudioAnalysis/wasmLoader.web.ts +53 -0
- package/src/AudioStudioModule.ts +6 -854
- package/src/trimAudio.ts +351 -0
- package/src/utils/encodeCompressedAudio.web.ts +78 -0
- package/src/utils/resampleAudioBuffer.web.ts +39 -0
- package/build/cjs/AudioAnalysis/extractWaveform.js +0 -18
- package/build/cjs/AudioAnalysis/extractWaveform.js.map +0 -1
- package/build/esm/AudioAnalysis/extractWaveform.js +0 -11
- package/build/esm/AudioAnalysis/extractWaveform.js.map +0 -1
- package/build/types/AudioAnalysis/extractWaveform.d.ts +0 -8
- package/build/types/AudioAnalysis/extractWaveform.d.ts.map +0 -1
- package/src/AudioAnalysis/extractWaveform.ts +0 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioAnalysis.types.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/AudioAnalysis.types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AudioAnalysis.types.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/AudioAnalysis.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
mfcc: number[];
|
|
7
|
-
chromagram: number[];
|
|
1
|
+
import type { AudioFeaturesWasmResult } from './AudioAnalysis.types';
|
|
2
|
+
export declare class AudioFeaturesStreamingSession {
|
|
3
|
+
static create(_sampleRate: number, _fftLength?: number, _nMfcc?: number, _nMelFilters?: number, _computeMfcc?: boolean, _computeChroma?: boolean): Promise<AudioFeaturesStreamingSession>;
|
|
4
|
+
computeFrame(_samples: Float32Array): AudioFeaturesWasmResult | null;
|
|
5
|
+
dispose(): void;
|
|
8
6
|
}
|
|
9
|
-
export declare function initAudioFeaturesWasm(_sampleRate: number, _fftLength?: number, _nMfcc?: number, _nMelFilters?: number, _computeMfcc?: boolean, _computeChroma?: boolean): Promise<void>;
|
|
10
|
-
export declare function computeAudioFeaturesFrameWasm(_samples: Float32Array): AudioFeaturesWasmResult | null;
|
|
11
7
|
export declare function computeAudioFeaturesWasm(_audioData: Float32Array, _sampleRate: number, _fftLength?: number, _nMfcc?: number, _nMelFilters?: number, _computeMfcc?: boolean, _computeChroma?: boolean): Promise<AudioFeaturesWasmResult>;
|
|
12
8
|
//# sourceMappingURL=audioFeaturesWasm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audioFeaturesWasm.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"audioFeaturesWasm.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAEpE,qBAAa,6BAA6B;WACzB,MAAM,CACf,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,OAAO,EACtB,cAAc,CAAC,EAAE,OAAO,GACzB,OAAO,CAAC,6BAA6B,CAAC;IAIzC,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,uBAAuB,GAAG,IAAI;IAIpE,OAAO,IAAI,IAAI;CAClB;AAED,wBAAsB,wBAAwB,CAC1C,UAAU,EAAE,YAAY,EACxB,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,OAAO,EACtB,cAAc,CAAC,EAAE,OAAO,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAElC"}
|
|
@@ -1,21 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
spectralCentroid: number;
|
|
3
|
-
spectralFlatness: number;
|
|
4
|
-
spectralRolloff: number;
|
|
5
|
-
spectralBandwidth: number;
|
|
6
|
-
mfcc: number[];
|
|
7
|
-
chromagram: number[];
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Initialise the WASM streaming audio features processor.
|
|
11
|
-
* Call once before computeAudioFeaturesFrameWasm().
|
|
12
|
-
*/
|
|
13
|
-
export declare function initAudioFeaturesWasm(sampleRate: number, fftLength?: number, nMfcc?: number, nMelFilters?: number, computeMfcc?: boolean, computeChroma?: boolean): Promise<void>;
|
|
1
|
+
import type { AudioFeaturesWasmResult } from './AudioAnalysis.types';
|
|
14
2
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
3
|
+
* Encapsulates a single WASM streaming audio features session.
|
|
4
|
+
* Each instance owns its own WASM heap allocations; multiple sessions
|
|
5
|
+
* can exist concurrently without interfering with each other.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const session = await AudioFeaturesStreamingSession.create(sampleRate)
|
|
9
|
+
* try {
|
|
10
|
+
* for (const frame of frames) {
|
|
11
|
+
* const result = session.computeFrame(frame)
|
|
12
|
+
* }
|
|
13
|
+
* } finally {
|
|
14
|
+
* session.dispose()
|
|
15
|
+
* }
|
|
17
16
|
*/
|
|
18
|
-
export declare
|
|
17
|
+
export declare class AudioFeaturesStreamingSession {
|
|
18
|
+
private module;
|
|
19
|
+
private framePtr;
|
|
20
|
+
private frameCapacity;
|
|
21
|
+
private resultPtr;
|
|
22
|
+
private constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Initialise a new streaming session. Loads the WASM module if needed.
|
|
25
|
+
*/
|
|
26
|
+
static create(sampleRate: number, fftLength?: number, nMfcc?: number, nMelFilters?: number, computeMfcc?: boolean, computeChroma?: boolean): Promise<AudioFeaturesStreamingSession>;
|
|
27
|
+
/**
|
|
28
|
+
* Compute audio features for a single frame.
|
|
29
|
+
* Returns null on error or if the session has been disposed.
|
|
30
|
+
*/
|
|
31
|
+
computeFrame(samples: Float32Array): AudioFeaturesWasmResult | null;
|
|
32
|
+
/**
|
|
33
|
+
* Free all WASM heap allocations owned by this session.
|
|
34
|
+
* The session must not be used after calling dispose().
|
|
35
|
+
*/
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}
|
|
19
38
|
/**
|
|
20
39
|
* Compute audio features for a buffer of samples via WASM C++.
|
|
21
40
|
* Lazy-loads the WASM module on first call.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audioFeaturesWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audioFeaturesWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAyDpE;;;;;;;;;;;;;;GAcG;AACH,qBAAa,6BAA6B;IACtC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,SAAS,CAAI;IAErB,OAAO;IAIP;;OAEG;WACU,MAAM,CACf,UAAU,EAAE,MAAM,EAClB,SAAS,SAAO,EAChB,KAAK,SAAK,EACV,WAAW,SAAK,EAChB,WAAW,UAAO,EAClB,aAAa,UAAO,GACrB,OAAO,CAAC,6BAA6B,CAAC;IAyBzC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,uBAAuB,GAAG,IAAI;IA6BnE;;;OAGG;IACH,OAAO,IAAI,IAAI;CAYlB;AAID;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,SAAS,EAAE,YAAY,EACvB,UAAU,EAAE,MAAM,EAClB,SAAS,SAAO,EAChB,KAAK,SAAK,EACV,WAAW,SAAK,EAChB,WAAW,UAAO,EAClB,aAAa,UAAO,GACrB,OAAO,CAAC,uBAAuB,CAAC,CA4BlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractAudioAnalysis.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioAnalysis.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAGlD,OAAO,EACH,aAAa,EACb,oBAAoB,EAEpB,cAAc,EACjB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,EAAkB,WAAW,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"extractAudioAnalysis.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioAnalysis.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAGlD,OAAO,EACH,aAAa,EACb,oBAAoB,EAEpB,cAAc,EACjB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,EAAkB,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAwBrE,MAAM,WAAW,4BAA4B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,eAAe,CAAC,EAAE,cAAc,CAAA;CACnC;AAGD,UAAU,kBAAkB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB;AAGD,UAAU,gBAAiB,SAAQ,kBAAkB;IACjD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAA;CACjB;AAGD,UAAU,gBAAiB,SAAQ,kBAAkB;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,KAAK,CAAA;IACnB,SAAS,CAAC,EAAE,KAAK,CAAA;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,gBAAgB,GAAG,gBAAgB,CAAA;AAE3E;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACtC,KAAK,EAAE,yBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,CA2HxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAU,sIAYzC,4BAA4B,KAAG,OAAO,CAAC,aAAa,CAoGtD,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { ExtractAudioDataOptions } from '../AudioStudio.types';
|
|
2
|
-
export declare const extractAudioData: (props: ExtractAudioDataOptions) => Promise<
|
|
1
|
+
import { ExtractAudioDataOptions, ExtractedAudioData } from '../AudioStudio.types';
|
|
2
|
+
export declare const extractAudioData: (props: ExtractAudioDataOptions) => Promise<ExtractedAudioData>;
|
|
3
3
|
//# sourceMappingURL=extractAudioData.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractAudioData.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioData.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"extractAudioData.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioData.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,uBAAuB,EACvB,kBAAkB,EACrB,MAAM,sBAAsB,CAAA;AAQ7B,eAAO,MAAM,gBAAgB,GACzB,OAAO,uBAAuB,KAC/B,OAAO,CAAC,kBAAkB,CAwL5B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"melSpectrogramWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"melSpectrogramWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,wBAAsB,oBAAoB,CACtC,UAAU,EAAE,MAAM,EAClB,KAAK,SAAM,EACX,SAAS,SAAO,EAChB,iBAAiB,SAAM,EACvB,gBAAgB,SAAM,EACtB,IAAI,SAAI,EACR,IAAI,SAAI,GACT,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,GAAG,IAAI,CA4B1E;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC3C,SAAS,EAAE,YAAY,EACvB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAgErB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasmLoader.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/wasmLoader.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAuBpE,wBAAgB,aAAa,IAAI,OAAO,CAAC,uBAAuB,CAAC,CA6BhE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioStudioModule.d.ts","sourceRoot":"","sources":["../../src/AudioStudioModule.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AudioStudioModule.d.ts","sourceRoot":"","sources":["../../src/AudioStudioModule.ts"],"names":[],"mappings":"AAMA,QAAA,IAAI,iBAAiB,EAAE,GAAG,CAAA;AAiI1B,eAAe,iBAAiB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trimAudio.d.ts","sourceRoot":"","sources":["../../src/trimAudio.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"trimAudio.d.ts","sourceRoot":"","sources":["../../src/trimAudio.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACpB,MAAM,qBAAqB,CAAA;AAuD5B;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAC3B,OAAO,EAAE,gBAAgB,EACzB,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GACtD,OAAO,CAAC,eAAe,CAAC,CA+V1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACjC,OAAO,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOTE: Encodes audio in real-time via AudioContext + MediaRecorder playback.
|
|
3
|
+
* A 60-second clip takes ~60 seconds to encode — this is a known Web Audio API
|
|
4
|
+
* limitation; there is no offline API for Opus/AAC encoding in browsers.
|
|
5
|
+
*/
|
|
6
|
+
export declare function encodeCompressedAudio(buffer: AudioBuffer, format: 'opus' | 'aac', bitrate?: number): Promise<{
|
|
7
|
+
data: ArrayBuffer;
|
|
8
|
+
bitrate: number;
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=encodeCompressedAudio.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encodeCompressedAudio.web.d.ts","sourceRoot":"","sources":["../../../src/utils/encodeCompressedAudio.web.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,GAAG,KAAK,EACtB,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAoEjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resampleAudioBuffer.web.d.ts","sourceRoot":"","sources":["../../../src/utils/resampleAudioBuffer.web.ts"],"names":[],"mappings":"AAAA,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,WAAW,CAAC,CAkCtB"}
|
|
@@ -65,6 +65,7 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
65
65
|
internal var lastEmittedCompressedSize: Int64 = 0
|
|
66
66
|
private var totalDataSize: Int64 = 0
|
|
67
67
|
private var lastBufferTime: AVAudioTime?
|
|
68
|
+
/// Guarded by `accumulatedDataLock`.
|
|
68
69
|
private var accumulatedData = Data()
|
|
69
70
|
|
|
70
71
|
// Data emission for onAudioAnalysis
|
|
@@ -73,8 +74,57 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
73
74
|
internal var lastEmittedCompressedSizeAnalysis: Int64 = 0
|
|
74
75
|
private var totalDataSizeAnalysis: Int64 = 0
|
|
75
76
|
private var lastBufferTimeAnalysis: AVAudioTime?
|
|
77
|
+
/// Guarded by `accumulatedDataLock`.
|
|
76
78
|
private var accumulatedAnalysisData = Data()
|
|
77
79
|
|
|
80
|
+
// Guards accumulatedData and accumulatedAnalysisData. The audio tap
|
|
81
|
+
// appends from the render thread while emit/pause/stop snapshot-and-clear
|
|
82
|
+
// from other threads. Without this lock, base64EncodedString crashed
|
|
83
|
+
// mid-flush (issue #314) and short emissions were occasionally dropped.
|
|
84
|
+
private let accumulatedDataLock = NSLock()
|
|
85
|
+
|
|
86
|
+
/// Append the same chunk to both buffers under the lock.
|
|
87
|
+
/// Called from the audio tap thread.
|
|
88
|
+
private func appendAccumulated(_ data: Data) {
|
|
89
|
+
accumulatedDataLock.lock()
|
|
90
|
+
accumulatedData.append(data)
|
|
91
|
+
accumulatedAnalysisData.append(data)
|
|
92
|
+
accumulatedDataLock.unlock()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/// Atomically snapshot accumulatedData and clear it. Empty Data if buffer was empty.
|
|
96
|
+
private func takeAccumulatedSnapshot() -> Data {
|
|
97
|
+
accumulatedDataLock.lock()
|
|
98
|
+
defer { accumulatedDataLock.unlock() }
|
|
99
|
+
let snapshot = accumulatedData
|
|
100
|
+
accumulatedData.removeAll()
|
|
101
|
+
return snapshot
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/// Atomically snapshot accumulatedAnalysisData and clear it.
|
|
105
|
+
private func takeAccumulatedAnalysisSnapshot() -> Data {
|
|
106
|
+
accumulatedDataLock.lock()
|
|
107
|
+
defer { accumulatedDataLock.unlock() }
|
|
108
|
+
let snapshot = accumulatedAnalysisData
|
|
109
|
+
accumulatedAnalysisData.removeAll()
|
|
110
|
+
return snapshot
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/// Clear both buffers atomically (lifecycle resets).
|
|
114
|
+
private func resetAccumulated() {
|
|
115
|
+
accumulatedDataLock.lock()
|
|
116
|
+
accumulatedData.removeAll()
|
|
117
|
+
accumulatedAnalysisData.removeAll()
|
|
118
|
+
accumulatedDataLock.unlock()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// Current size of accumulatedData for logs/probes.
|
|
122
|
+
private func accumulatedDataSize() -> Int {
|
|
123
|
+
accumulatedDataLock.lock()
|
|
124
|
+
defer { accumulatedDataLock.unlock() }
|
|
125
|
+
return accumulatedData.count
|
|
126
|
+
}
|
|
127
|
+
|
|
78
128
|
|
|
79
129
|
|
|
80
130
|
private var fileManager = FileManager.default
|
|
@@ -830,16 +880,14 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
830
880
|
return false
|
|
831
881
|
}
|
|
832
882
|
|
|
833
|
-
//
|
|
883
|
+
// Deactivate the session for a clean slate before reconfiguring.
|
|
884
|
+
// configureAudioSession() below will activate it once — no need for
|
|
885
|
+
// the previous deactivate→sleep→activate→reconfigure→activate cycle.
|
|
834
886
|
do {
|
|
835
887
|
let session = AVAudioSession.sharedInstance()
|
|
836
888
|
try session.setActive(false, options: .notifyOthersOnDeactivation)
|
|
837
|
-
Thread.sleep(forTimeInterval: 0.1) // Brief pause to ensure clean state
|
|
838
|
-
try session.setActive(true, options: .notifyOthersOnDeactivation)
|
|
839
889
|
} catch {
|
|
840
|
-
Logger.debug("AudioStreamManager", "Failed to
|
|
841
|
-
delegate?.audioStreamManager(self, didFailWithError: "Failed to reset audio session: \(error.localizedDescription)")
|
|
842
|
-
return false
|
|
890
|
+
Logger.debug("AudioStreamManager", "Failed to deactivate audio session (non-fatal): \(error)")
|
|
843
891
|
}
|
|
844
892
|
|
|
845
893
|
// Update auto-resume preference from settings
|
|
@@ -850,8 +898,7 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
850
898
|
emissionIntervalAnalysis = max(10.0, Double(settings.intervalAnalysis ?? 500)) / 1000.0
|
|
851
899
|
lastEmissionTime = nil // Will be set when recording starts
|
|
852
900
|
lastEmissionTimeAnalysis = nil // Will be set when recording starts
|
|
853
|
-
|
|
854
|
-
accumulatedAnalysisData.removeAll()
|
|
901
|
+
resetAccumulated()
|
|
855
902
|
totalDataSize = 0
|
|
856
903
|
totalDataSizeAnalysis = 0
|
|
857
904
|
totalPausedDuration = 0
|
|
@@ -943,8 +990,9 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
943
990
|
|
|
944
991
|
recordingSettings = newSettings // Keep original settings with desired sample rate
|
|
945
992
|
|
|
946
|
-
audioEngine.prepare()
|
|
947
|
-
|
|
993
|
+
// audioEngine.prepare() is already called inside installTapWithHardwareFormat()
|
|
994
|
+
// (default prepareEngine: true). Don't call it twice.
|
|
995
|
+
|
|
948
996
|
// Setup compressed recording if enabled
|
|
949
997
|
if settings.output.compressed.enabled {
|
|
950
998
|
// Create compressed settings
|
|
@@ -1010,9 +1058,18 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1010
1058
|
Logger.debug("AudioStreamManager", "AudioProcessor activated successfully.")
|
|
1011
1059
|
}
|
|
1012
1060
|
|
|
1013
|
-
//
|
|
1061
|
+
// initializeNotifications schedules a Timer that needs main's RunLoop,
|
|
1062
|
+
// and notificationManager must exist before prepareRecording returns
|
|
1063
|
+
// (the recursive startRecording → prepareRecording path uses it
|
|
1064
|
+
// immediately). .sync is safe: nothing on main blocks on audioLifecycleQueue.
|
|
1014
1065
|
if settings.showNotification {
|
|
1015
|
-
|
|
1066
|
+
if Thread.isMainThread {
|
|
1067
|
+
initializeNotifications()
|
|
1068
|
+
} else {
|
|
1069
|
+
DispatchQueue.main.sync {
|
|
1070
|
+
self.initializeNotifications()
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1016
1073
|
}
|
|
1017
1074
|
|
|
1018
1075
|
// Mark preparation as complete
|
|
@@ -1177,16 +1234,12 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1177
1234
|
Logger.debug("Pausing recording...")
|
|
1178
1235
|
|
|
1179
1236
|
// Emit any remaining audio data before pausing
|
|
1180
|
-
|
|
1181
|
-
|
|
1237
|
+
let finalData = takeAccumulatedSnapshot()
|
|
1238
|
+
if !finalData.isEmpty {
|
|
1239
|
+
Logger.debug("Emitting final audio chunk of \(finalData.count) bytes before pausing")
|
|
1182
1240
|
let recordingTime = currentRecordingDuration()
|
|
1183
1241
|
let finalTotalSize = self.totalDataSize
|
|
1184
|
-
|
|
1185
|
-
// Create a copy of accumulated data to avoid race conditions
|
|
1186
|
-
let finalData = accumulatedData
|
|
1187
|
-
accumulatedData.removeAll()
|
|
1188
|
-
|
|
1189
|
-
// Notify delegate with final audio data
|
|
1242
|
+
|
|
1190
1243
|
delegate?.audioStreamManager(
|
|
1191
1244
|
self,
|
|
1192
1245
|
didReceiveAudioData: finalData,
|
|
@@ -1542,9 +1595,9 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1542
1595
|
}
|
|
1543
1596
|
|
|
1544
1597
|
// --- Event Emission & Analysis (Always Happens) ---
|
|
1545
|
-
// Audio streaming is independent of file output settings
|
|
1546
|
-
|
|
1547
|
-
|
|
1598
|
+
// Audio streaming is independent of file output settings.
|
|
1599
|
+
// Lock-protected append: see accumulatedDataLock for rationale.
|
|
1600
|
+
appendAccumulated(dataToWrite)
|
|
1548
1601
|
|
|
1549
1602
|
if recordingSettings?.showNotification == true {
|
|
1550
1603
|
updateNotificationDuration()
|
|
@@ -1555,34 +1608,36 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1555
1608
|
|
|
1556
1609
|
// Emit AudioData event
|
|
1557
1610
|
if let lastEmission = self.lastEmissionTime {
|
|
1558
|
-
// Log emission evaluation every 10th buffer
|
|
1559
1611
|
if debugBufferCounter % 10 == 0 {
|
|
1560
1612
|
let timeGap = currentTime.timeIntervalSince(lastEmission)
|
|
1561
1613
|
let isTimeReady = timeGap >= emissionInterval
|
|
1562
|
-
Logger.debug("EMISSION DEBUG: Time since last: \(timeGap)s, Threshold: \(emissionInterval)s, Ready: \(isTimeReady), DataSize: \(
|
|
1614
|
+
Logger.debug("EMISSION DEBUG: Time since last: \(timeGap)s, Threshold: \(emissionInterval)s, Ready: \(isTimeReady), DataSize: \(accumulatedDataSize()) bytes")
|
|
1563
1615
|
}
|
|
1564
|
-
|
|
1565
|
-
if currentTime.timeIntervalSince(lastEmission) >= emissionInterval
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1616
|
+
|
|
1617
|
+
if currentTime.timeIntervalSince(lastEmission) >= emissionInterval {
|
|
1618
|
+
// Atomic snapshot+clear avoids the race that crashed
|
|
1619
|
+
// base64EncodedString in the delegate (issue #314) and
|
|
1620
|
+
// stops short writes from being dropped between read
|
|
1621
|
+
// and clear.
|
|
1622
|
+
let dataToEmit = takeAccumulatedSnapshot()
|
|
1623
|
+
if !dataToEmit.isEmpty {
|
|
1624
|
+
let recordingTime = currentRecordingDuration()
|
|
1625
|
+
self.lastEmissionTime = currentTime
|
|
1626
|
+
self.lastEmittedSize = currentTotalSize
|
|
1627
|
+
let compressionInfo = buildCompressionInfo()
|
|
1628
|
+
|
|
1629
|
+
Logger.debug("EMISSION SUCCESS: Emitting \(dataToEmit.count) bytes at recording time \(recordingTime)s")
|
|
1630
|
+
|
|
1631
|
+
delegate?.audioStreamManager(
|
|
1632
|
+
self,
|
|
1633
|
+
didReceiveAudioData: dataToEmit,
|
|
1634
|
+
recordingTime: recordingTime,
|
|
1635
|
+
totalDataSize: currentTotalSize,
|
|
1636
|
+
compressionInfo: compressionInfo
|
|
1637
|
+
)
|
|
1638
|
+
}
|
|
1583
1639
|
}
|
|
1584
1640
|
} else {
|
|
1585
|
-
// This case occurs when lastEmissionTime is nil (either first run or after reset)
|
|
1586
1641
|
Logger.debug("EMISSION DEBUG: lastEmissionTime is nil, setting to current time")
|
|
1587
1642
|
lastEmissionTime = currentTime
|
|
1588
1643
|
}
|
|
@@ -1591,12 +1646,11 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1591
1646
|
if let lastEmissionAnalysis = self.lastEmissionTimeAnalysis,
|
|
1592
1647
|
currentTime.timeIntervalSince(lastEmissionAnalysis) >= emissionIntervalAnalysis,
|
|
1593
1648
|
settings.enableProcessing,
|
|
1594
|
-
let _ = self.audioProcessor
|
|
1595
|
-
|
|
1596
|
-
let dataToAnalyze = accumulatedAnalysisData
|
|
1649
|
+
let _ = self.audioProcessor {
|
|
1650
|
+
let dataToAnalyze = takeAccumulatedAnalysisSnapshot()
|
|
1597
1651
|
self.lastEmissionTimeAnalysis = currentTime
|
|
1598
|
-
accumulatedAnalysisData.removeAll()
|
|
1599
1652
|
|
|
1653
|
+
if !dataToAnalyze.isEmpty {
|
|
1600
1654
|
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
|
1601
1655
|
guard let self = self, let processor = self.audioProcessor, let settings = self.recordingSettings else {
|
|
1602
1656
|
// Logger.debug("Analysis Dispatch SKIP: self, processor, or settings nil")
|
|
@@ -1627,6 +1681,7 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1627
1681
|
}
|
|
1628
1682
|
}
|
|
1629
1683
|
}
|
|
1684
|
+
}
|
|
1630
1685
|
// Logger.debug("Dispatched analysis task.") // Optional: Re-enable if needed
|
|
1631
1686
|
}
|
|
1632
1687
|
}
|
|
@@ -1744,24 +1799,23 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1744
1799
|
|
|
1745
1800
|
Logger.debug("Stopping recording...")
|
|
1746
1801
|
|
|
1747
|
-
// IMPORTANT: Emit any remaining audio data before stopping the engine
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
let
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
)
|
|
1802
|
+
// IMPORTANT: Emit any remaining audio data before stopping the engine.
|
|
1803
|
+
// Atomic snapshot avoids the race documented in #314.
|
|
1804
|
+
if isRecording {
|
|
1805
|
+
let finalData = takeAccumulatedSnapshot()
|
|
1806
|
+
if !finalData.isEmpty {
|
|
1807
|
+
Logger.debug("Emitting final audio chunk of \(finalData.count) bytes before stopping")
|
|
1808
|
+
let recordingTime = currentRecordingDuration()
|
|
1809
|
+
let finalTotalSize = self.totalDataSize
|
|
1810
|
+
|
|
1811
|
+
delegate?.audioStreamManager(
|
|
1812
|
+
self,
|
|
1813
|
+
didReceiveAudioData: finalData,
|
|
1814
|
+
recordingTime: recordingTime,
|
|
1815
|
+
totalDataSize: finalTotalSize,
|
|
1816
|
+
compressionInfo: buildCompressionInfo()
|
|
1817
|
+
)
|
|
1818
|
+
}
|
|
1765
1819
|
}
|
|
1766
1820
|
|
|
1767
1821
|
disableWakeLock()
|
|
@@ -1904,8 +1958,7 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1904
1958
|
lastEmittedSize = 0
|
|
1905
1959
|
lastEmittedSizeAnalysis = 0
|
|
1906
1960
|
lastEmittedCompressedSize = 0
|
|
1907
|
-
|
|
1908
|
-
accumulatedAnalysisData.removeAll()
|
|
1961
|
+
resetAccumulated()
|
|
1909
1962
|
recordingUUID = nil
|
|
1910
1963
|
totalDataSize = 0
|
|
1911
1964
|
|
|
@@ -1970,8 +2023,7 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
1970
2023
|
self.lastEmittedSize = 0
|
|
1971
2024
|
self.lastEmittedSizeAnalysis = 0
|
|
1972
2025
|
self.lastEmittedCompressedSize = 0
|
|
1973
|
-
self.
|
|
1974
|
-
self.accumulatedAnalysisData.removeAll()
|
|
2026
|
+
self.resetAccumulated()
|
|
1975
2027
|
self.recordingUUID = nil
|
|
1976
2028
|
self.totalDataSize = 0
|
|
1977
2029
|
self.cachedWavFileSize = 0
|
|
@@ -2173,16 +2225,16 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
2173
2225
|
Logger.debug("Recording was manually paused, leaving engine paused after fallback.")
|
|
2174
2226
|
}
|
|
2175
2227
|
|
|
2176
|
-
// Emit any remaining audio data from the previous device
|
|
2177
|
-
|
|
2178
|
-
|
|
2228
|
+
// Emit any remaining audio data from the previous device, then
|
|
2229
|
+
// wipe both buffers atomically (analysis buffer is discarded since
|
|
2230
|
+
// we want to start fresh on the fallback device).
|
|
2231
|
+
let finalData = takeAccumulatedSnapshot()
|
|
2232
|
+
_ = takeAccumulatedAnalysisSnapshot()
|
|
2233
|
+
if !finalData.isEmpty {
|
|
2234
|
+
Logger.debug("Emitting final audio chunk of \(finalData.count) bytes from previous device")
|
|
2179
2235
|
let recordingTime = currentRecordingDuration()
|
|
2180
2236
|
let finalTotalSize = self.totalDataSize
|
|
2181
|
-
|
|
2182
|
-
// Create a copy of accumulated data to avoid race conditions
|
|
2183
|
-
let finalData = accumulatedData
|
|
2184
|
-
|
|
2185
|
-
// Notify delegate with final audio data from previous device
|
|
2237
|
+
|
|
2186
2238
|
delegate?.audioStreamManager(
|
|
2187
2239
|
self,
|
|
2188
2240
|
didReceiveAudioData: finalData,
|
|
@@ -2191,15 +2243,10 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
2191
2243
|
compressionInfo: buildCompressionInfo()
|
|
2192
2244
|
)
|
|
2193
2245
|
}
|
|
2194
|
-
|
|
2246
|
+
|
|
2195
2247
|
// Reset emission timers to force new data emission with the fallback device
|
|
2196
2248
|
lastEmissionTime = Date() // Reset to force immediate emission
|
|
2197
2249
|
lastEmissionTimeAnalysis = Date() // Reset analysis timer too
|
|
2198
|
-
|
|
2199
|
-
// Important: Do not reset totalDataSize here - it needs to be maintained
|
|
2200
|
-
// We only clear the buffers to start accumulating new data from the fallback device
|
|
2201
|
-
accumulatedData.removeAll() // Clear any partial data from previous device
|
|
2202
|
-
accumulatedAnalysisData.removeAll() // Clear analysis data buffer
|
|
2203
2250
|
Logger.debug("Emission timers reset. Current totalDataSize: \(totalDataSize)")
|
|
2204
2251
|
|
|
2205
2252
|
// CRITICAL: Multiple scheduled recovery attempts
|
|
@@ -2209,14 +2256,13 @@ class AudioStreamManager: NSObject, AudioDeviceManagerDelegate {
|
|
|
2209
2256
|
Logger.debug("FALLBACK RECOVERY: Checking for data at \(delaySeconds)s")
|
|
2210
2257
|
|
|
2211
2258
|
// Force an immediate emission if data is being received but not emitted
|
|
2212
|
-
|
|
2259
|
+
let dataToEmit = self.takeAccumulatedSnapshot()
|
|
2260
|
+
if !dataToEmit.isEmpty {
|
|
2213
2261
|
Logger.debug("FALLBACK RECOVERY: Forcing emission from accumulated data after \(delaySeconds)s (total size: \(self.totalDataSize))")
|
|
2214
|
-
let dataToEmit = self.accumulatedData
|
|
2215
2262
|
let recordingTime = self.currentRecordingDuration()
|
|
2216
2263
|
let totalSize = self.totalDataSize
|
|
2217
|
-
|
|
2264
|
+
|
|
2218
2265
|
self.lastEmissionTime = Date() // Reset the emission timer
|
|
2219
|
-
self.accumulatedData.removeAll() // Clear the buffer
|
|
2220
2266
|
|
|
2221
2267
|
// Direct delegate call with accumulated data
|
|
2222
2268
|
self.delegate?.audioStreamManager(
|