@absolutejs/voice 0.0.22-beta.581 → 0.0.22-beta.582
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.
|
@@ -22,9 +22,16 @@ type MinimalGainNode = {
|
|
|
22
22
|
value: number;
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
+
type MinimalAnalyserNode = {
|
|
26
|
+
connect?: (destination: unknown) => void;
|
|
27
|
+
disconnect?: () => void;
|
|
28
|
+
fftSize: number;
|
|
29
|
+
getByteTimeDomainData: (array: Uint8Array) => void;
|
|
30
|
+
};
|
|
25
31
|
type MinimalAudioContext = {
|
|
26
32
|
baseLatency?: number;
|
|
27
33
|
close: () => Promise<void>;
|
|
34
|
+
createAnalyser?: () => MinimalAnalyserNode;
|
|
28
35
|
createBuffer: (numberOfChannels: number, length: number, sampleRate: number) => MinimalAudioBuffer;
|
|
29
36
|
createBufferSource: () => MinimalAudioBufferSourceNode;
|
|
30
37
|
createGain?: () => MinimalGainNode;
|
|
@@ -1693,6 +1693,8 @@ var DEFAULT_PLAYBACK_RATE = 1;
|
|
|
1693
1693
|
var MIN_PLAYBACK_RATE = 0.5;
|
|
1694
1694
|
var MAX_PLAYBACK_RATE = 2;
|
|
1695
1695
|
var STRETCH_BYPASS_EPSILON = 0.01;
|
|
1696
|
+
var ANALYSER_FFT_SIZE = 256;
|
|
1697
|
+
var PCM_BYTE_MIDPOINT = 128;
|
|
1696
1698
|
var createInitialState3 = () => ({
|
|
1697
1699
|
activeSourceCount: 0,
|
|
1698
1700
|
error: null,
|
|
@@ -1753,6 +1755,8 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
1753
1755
|
let state = createInitialState3();
|
|
1754
1756
|
let audioContext = null;
|
|
1755
1757
|
let outputNode = null;
|
|
1758
|
+
let analyserNode = null;
|
|
1759
|
+
let analyserBuffer = null;
|
|
1756
1760
|
let volume = clampVolume(options.volume);
|
|
1757
1761
|
let playbackRate = clampPlaybackRate(options.playbackRate);
|
|
1758
1762
|
let stretcher = null;
|
|
@@ -1849,6 +1853,12 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
1849
1853
|
if (audioContext.createGain) {
|
|
1850
1854
|
outputNode = audioContext.createGain();
|
|
1851
1855
|
outputNode.connect?.(audioContext.destination);
|
|
1856
|
+
if (audioContext.createAnalyser) {
|
|
1857
|
+
analyserNode = audioContext.createAnalyser();
|
|
1858
|
+
analyserNode.fftSize = ANALYSER_FFT_SIZE;
|
|
1859
|
+
analyserBuffer = new Uint8Array(analyserNode.fftSize);
|
|
1860
|
+
outputNode.connect?.(analyserNode);
|
|
1861
|
+
}
|
|
1852
1862
|
}
|
|
1853
1863
|
queueEndTime = audioContext.currentTime;
|
|
1854
1864
|
return audioContext;
|
|
@@ -1973,6 +1983,9 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
1973
1983
|
audioContext = null;
|
|
1974
1984
|
outputNode?.disconnect?.();
|
|
1975
1985
|
outputNode = null;
|
|
1986
|
+
analyserNode?.disconnect?.();
|
|
1987
|
+
analyserNode = null;
|
|
1988
|
+
analyserBuffer = null;
|
|
1976
1989
|
queueEndTime = 0;
|
|
1977
1990
|
setState({
|
|
1978
1991
|
activeSourceCount: 0,
|
|
@@ -1983,6 +1996,18 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
1983
1996
|
get error() {
|
|
1984
1997
|
return state.error;
|
|
1985
1998
|
},
|
|
1999
|
+
getOutputLevel: () => {
|
|
2000
|
+
if (!analyserNode || !analyserBuffer) {
|
|
2001
|
+
return 0;
|
|
2002
|
+
}
|
|
2003
|
+
analyserNode.getByteTimeDomainData(analyserBuffer);
|
|
2004
|
+
let sumSquares = 0;
|
|
2005
|
+
for (const sample of analyserBuffer) {
|
|
2006
|
+
const centered = (sample - PCM_BYTE_MIDPOINT) / PCM_BYTE_MIDPOINT;
|
|
2007
|
+
sumSquares += centered * centered;
|
|
2008
|
+
}
|
|
2009
|
+
return Math.sqrt(sumSquares / analyserBuffer.length);
|
|
2010
|
+
},
|
|
1986
2011
|
getSnapshot: () => state,
|
|
1987
2012
|
interrupt: async () => {
|
|
1988
2013
|
const startedAt = Date.now();
|
package/dist/client/index.js
CHANGED
|
@@ -529,6 +529,8 @@ var DEFAULT_PLAYBACK_RATE = 1;
|
|
|
529
529
|
var MIN_PLAYBACK_RATE = 0.5;
|
|
530
530
|
var MAX_PLAYBACK_RATE = 2;
|
|
531
531
|
var STRETCH_BYPASS_EPSILON = 0.01;
|
|
532
|
+
var ANALYSER_FFT_SIZE = 256;
|
|
533
|
+
var PCM_BYTE_MIDPOINT = 128;
|
|
532
534
|
var createInitialState = () => ({
|
|
533
535
|
activeSourceCount: 0,
|
|
534
536
|
error: null,
|
|
@@ -589,6 +591,8 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
589
591
|
let state = createInitialState();
|
|
590
592
|
let audioContext = null;
|
|
591
593
|
let outputNode = null;
|
|
594
|
+
let analyserNode = null;
|
|
595
|
+
let analyserBuffer = null;
|
|
592
596
|
let volume = clampVolume(options.volume);
|
|
593
597
|
let playbackRate = clampPlaybackRate(options.playbackRate);
|
|
594
598
|
let stretcher = null;
|
|
@@ -685,6 +689,12 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
685
689
|
if (audioContext.createGain) {
|
|
686
690
|
outputNode = audioContext.createGain();
|
|
687
691
|
outputNode.connect?.(audioContext.destination);
|
|
692
|
+
if (audioContext.createAnalyser) {
|
|
693
|
+
analyserNode = audioContext.createAnalyser();
|
|
694
|
+
analyserNode.fftSize = ANALYSER_FFT_SIZE;
|
|
695
|
+
analyserBuffer = new Uint8Array(analyserNode.fftSize);
|
|
696
|
+
outputNode.connect?.(analyserNode);
|
|
697
|
+
}
|
|
688
698
|
}
|
|
689
699
|
queueEndTime = audioContext.currentTime;
|
|
690
700
|
return audioContext;
|
|
@@ -809,6 +819,9 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
809
819
|
audioContext = null;
|
|
810
820
|
outputNode?.disconnect?.();
|
|
811
821
|
outputNode = null;
|
|
822
|
+
analyserNode?.disconnect?.();
|
|
823
|
+
analyserNode = null;
|
|
824
|
+
analyserBuffer = null;
|
|
812
825
|
queueEndTime = 0;
|
|
813
826
|
setState({
|
|
814
827
|
activeSourceCount: 0,
|
|
@@ -819,6 +832,18 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
819
832
|
get error() {
|
|
820
833
|
return state.error;
|
|
821
834
|
},
|
|
835
|
+
getOutputLevel: () => {
|
|
836
|
+
if (!analyserNode || !analyserBuffer) {
|
|
837
|
+
return 0;
|
|
838
|
+
}
|
|
839
|
+
analyserNode.getByteTimeDomainData(analyserBuffer);
|
|
840
|
+
let sumSquares = 0;
|
|
841
|
+
for (const sample of analyserBuffer) {
|
|
842
|
+
const centered = (sample - PCM_BYTE_MIDPOINT) / PCM_BYTE_MIDPOINT;
|
|
843
|
+
sumSquares += centered * centered;
|
|
844
|
+
}
|
|
845
|
+
return Math.sqrt(sumSquares / analyserBuffer.length);
|
|
846
|
+
},
|
|
822
847
|
getSnapshot: () => state,
|
|
823
848
|
interrupt: async () => {
|
|
824
849
|
const startedAt = Date.now();
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1331,6 +1331,9 @@ export type VoiceAudioPlayerSource = {
|
|
|
1331
1331
|
export type VoiceAudioPlayer = {
|
|
1332
1332
|
close: () => Promise<void>;
|
|
1333
1333
|
error: string | null;
|
|
1334
|
+
/** Instantaneous RMS amplitude (0..1) of the assistant's audio output — for
|
|
1335
|
+
* driving a visualizer from the actual voice. 0 when idle / no analyser. */
|
|
1336
|
+
getOutputLevel: () => number;
|
|
1334
1337
|
getSnapshot: () => VoiceAudioPlayerState;
|
|
1335
1338
|
activeSourceCount: number;
|
|
1336
1339
|
isActive: boolean;
|
package/dist/testing/index.js
CHANGED
|
@@ -1736,6 +1736,8 @@ var DEFAULT_PLAYBACK_RATE = 1;
|
|
|
1736
1736
|
var MIN_PLAYBACK_RATE = 0.5;
|
|
1737
1737
|
var MAX_PLAYBACK_RATE = 2;
|
|
1738
1738
|
var STRETCH_BYPASS_EPSILON = 0.01;
|
|
1739
|
+
var ANALYSER_FFT_SIZE = 256;
|
|
1740
|
+
var PCM_BYTE_MIDPOINT = 128;
|
|
1739
1741
|
var createInitialState = () => ({
|
|
1740
1742
|
activeSourceCount: 0,
|
|
1741
1743
|
error: null,
|
|
@@ -1796,6 +1798,8 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
1796
1798
|
let state = createInitialState();
|
|
1797
1799
|
let audioContext = null;
|
|
1798
1800
|
let outputNode = null;
|
|
1801
|
+
let analyserNode = null;
|
|
1802
|
+
let analyserBuffer = null;
|
|
1799
1803
|
let volume = clampVolume(options.volume);
|
|
1800
1804
|
let playbackRate = clampPlaybackRate(options.playbackRate);
|
|
1801
1805
|
let stretcher = null;
|
|
@@ -1892,6 +1896,12 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
1892
1896
|
if (audioContext.createGain) {
|
|
1893
1897
|
outputNode = audioContext.createGain();
|
|
1894
1898
|
outputNode.connect?.(audioContext.destination);
|
|
1899
|
+
if (audioContext.createAnalyser) {
|
|
1900
|
+
analyserNode = audioContext.createAnalyser();
|
|
1901
|
+
analyserNode.fftSize = ANALYSER_FFT_SIZE;
|
|
1902
|
+
analyserBuffer = new Uint8Array(analyserNode.fftSize);
|
|
1903
|
+
outputNode.connect?.(analyserNode);
|
|
1904
|
+
}
|
|
1895
1905
|
}
|
|
1896
1906
|
queueEndTime = audioContext.currentTime;
|
|
1897
1907
|
return audioContext;
|
|
@@ -2016,6 +2026,9 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
2016
2026
|
audioContext = null;
|
|
2017
2027
|
outputNode?.disconnect?.();
|
|
2018
2028
|
outputNode = null;
|
|
2029
|
+
analyserNode?.disconnect?.();
|
|
2030
|
+
analyserNode = null;
|
|
2031
|
+
analyserBuffer = null;
|
|
2019
2032
|
queueEndTime = 0;
|
|
2020
2033
|
setState({
|
|
2021
2034
|
activeSourceCount: 0,
|
|
@@ -2026,6 +2039,18 @@ var createVoiceAudioPlayer = (source, options = {}) => {
|
|
|
2026
2039
|
get error() {
|
|
2027
2040
|
return state.error;
|
|
2028
2041
|
},
|
|
2042
|
+
getOutputLevel: () => {
|
|
2043
|
+
if (!analyserNode || !analyserBuffer) {
|
|
2044
|
+
return 0;
|
|
2045
|
+
}
|
|
2046
|
+
analyserNode.getByteTimeDomainData(analyserBuffer);
|
|
2047
|
+
let sumSquares = 0;
|
|
2048
|
+
for (const sample of analyserBuffer) {
|
|
2049
|
+
const centered = (sample - PCM_BYTE_MIDPOINT) / PCM_BYTE_MIDPOINT;
|
|
2050
|
+
sumSquares += centered * centered;
|
|
2051
|
+
}
|
|
2052
|
+
return Math.sqrt(sumSquares / analyserBuffer.length);
|
|
2053
|
+
},
|
|
2029
2054
|
getSnapshot: () => state,
|
|
2030
2055
|
interrupt: async () => {
|
|
2031
2056
|
const startedAt = Date.now();
|