@elevenlabs/client 1.1.2 → 1.2.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/dist/BaseConversation.d.ts +8 -0
- package/dist/BaseConversation.d.ts.map +1 -1
- package/dist/BaseConversation.js.map +1 -1
- package/dist/InputController.d.ts +13 -0
- package/dist/InputController.d.ts.map +1 -1
- package/dist/OutputController.d.ts +13 -0
- package/dist/OutputController.d.ts.map +1 -1
- package/dist/VoiceConversation.d.ts +3 -3
- package/dist/VoiceConversation.d.ts.map +1 -1
- package/dist/VoiceConversation.js +7 -38
- package/dist/VoiceConversation.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/lib.iife.js +158 -37
- package/dist/lib.iife.js.map +1 -1
- package/dist/utils/WebRTCConnection.d.ts +14 -2
- package/dist/utils/WebRTCConnection.d.ts.map +1 -1
- package/dist/utils/WebRTCConnection.js +83 -10
- package/dist/utils/WebRTCConnection.js.map +1 -1
- package/dist/utils/calculateVolume.d.ts +7 -0
- package/dist/utils/calculateVolume.d.ts.map +1 -0
- package/dist/utils/calculateVolume.js +17 -0
- package/dist/utils/calculateVolume.js.map +1 -0
- package/dist/utils/input.d.ts +3 -0
- package/dist/utils/input.d.ts.map +1 -1
- package/dist/utils/input.js +15 -0
- package/dist/utils/input.js.map +1 -1
- package/dist/utils/output.d.ts +3 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +9 -0
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/volumeProvider.d.ts +21 -0
- package/dist/utils/volumeProvider.d.ts.map +1 -0
- package/dist/utils/volumeProvider.js +51 -0
- package/dist/utils/volumeProvider.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/lib.iife.js
CHANGED
|
@@ -383,7 +383,7 @@ var ElevenLabsClient = (function(exports) {
|
|
|
383
383
|
//#region src/sourceInfo.ts
|
|
384
384
|
let sourceInfo = Object.freeze({
|
|
385
385
|
name: "js_sdk",
|
|
386
|
-
version: "1.
|
|
386
|
+
version: "1.2.0"
|
|
387
387
|
});
|
|
388
388
|
//#endregion
|
|
389
389
|
//#region src/utils/events.ts
|
|
@@ -21929,6 +21929,66 @@ class RawAudioProcessor extends AudioWorkletProcessor {
|
|
|
21929
21929
|
}
|
|
21930
21930
|
registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
21931
21931
|
`);
|
|
21932
|
+
//#endregion
|
|
21933
|
+
//#region src/utils/calculateVolume.ts
|
|
21934
|
+
/**
|
|
21935
|
+
* Calculate a scalar volume level (0–1) from byte frequency data.
|
|
21936
|
+
*
|
|
21937
|
+
* The value is the mean of all frequency bins normalised to [0, 1].
|
|
21938
|
+
*/
|
|
21939
|
+
function calculateVolume(frequencyData) {
|
|
21940
|
+
if (frequencyData.length === 0) return 0;
|
|
21941
|
+
let volume = 0;
|
|
21942
|
+
for (let i = 0; i < frequencyData.length; i++) volume += frequencyData[i] / 255;
|
|
21943
|
+
volume /= frequencyData.length;
|
|
21944
|
+
return volume < 0 ? 0 : volume > 1 ? 1 : volume;
|
|
21945
|
+
}
|
|
21946
|
+
//#endregion
|
|
21947
|
+
//#region src/utils/volumeProvider.ts
|
|
21948
|
+
const NO_VOLUME = {
|
|
21949
|
+
getVolume: () => 0,
|
|
21950
|
+
getByteFrequencyData: () => {}
|
|
21951
|
+
};
|
|
21952
|
+
const MAX_VOICE_FREQUENCY = 8e3;
|
|
21953
|
+
/**
|
|
21954
|
+
* Resamples the voice-relevant portion of raw frequency data into an output
|
|
21955
|
+
* buffer using linear interpolation. This ensures both web and React Native
|
|
21956
|
+
* return comparable frequency data focused on the human voice range.
|
|
21957
|
+
*/
|
|
21958
|
+
function resampleVoiceRange(raw, buffer, sampleRate) {
|
|
21959
|
+
const binCount = raw.length;
|
|
21960
|
+
const hzPerBin = sampleRate / 2 / binCount;
|
|
21961
|
+
const minBin = Math.floor(100 / hzPerBin);
|
|
21962
|
+
const maxBin = Math.min(Math.ceil(MAX_VOICE_FREQUENCY / hzPerBin), binCount);
|
|
21963
|
+
const voiceBinCount = maxBin - minBin;
|
|
21964
|
+
const outLen = buffer.length;
|
|
21965
|
+
for (let i = 0; i < outLen; i++) {
|
|
21966
|
+
const pos = i / outLen * voiceBinCount;
|
|
21967
|
+
const lo = minBin + Math.floor(pos);
|
|
21968
|
+
const hi = Math.min(lo + 1, maxBin - 1);
|
|
21969
|
+
const t = pos - Math.floor(pos);
|
|
21970
|
+
buffer[i] = Math.round(raw[lo] * (1 - t) + raw[hi] * t);
|
|
21971
|
+
}
|
|
21972
|
+
}
|
|
21973
|
+
function createAnalyserVolumeProvider(analyser, sampleRate) {
|
|
21974
|
+
const binCount = analyser.frequencyBinCount;
|
|
21975
|
+
let rawData;
|
|
21976
|
+
let voiceData;
|
|
21977
|
+
return {
|
|
21978
|
+
getVolume() {
|
|
21979
|
+
rawData ??= new Uint8Array(binCount);
|
|
21980
|
+
voiceData ??= new Uint8Array(binCount);
|
|
21981
|
+
analyser.getByteFrequencyData(rawData);
|
|
21982
|
+
resampleVoiceRange(rawData, voiceData, sampleRate);
|
|
21983
|
+
return calculateVolume(voiceData);
|
|
21984
|
+
},
|
|
21985
|
+
getByteFrequencyData(buffer) {
|
|
21986
|
+
rawData ??= new Uint8Array(binCount);
|
|
21987
|
+
analyser.getByteFrequencyData(rawData);
|
|
21988
|
+
resampleVoiceRange(rawData, buffer, sampleRate);
|
|
21989
|
+
}
|
|
21990
|
+
};
|
|
21991
|
+
}
|
|
21932
21992
|
//#endregion
|
|
21933
21993
|
//#region src/utils/WebRTCConnection.ts
|
|
21934
21994
|
const DEFAULT_LIVEKIT_WS_URL = "wss://livekit.rtc.elevenlabs.io";
|
|
@@ -21946,8 +22006,11 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
21946
22006
|
audioCaptureContext = null;
|
|
21947
22007
|
audioElements = [];
|
|
21948
22008
|
outputDeviceId = null;
|
|
22009
|
+
inputAnalyser = null;
|
|
22010
|
+
inputAudioContext = null;
|
|
22011
|
+
inputVolumeProvider = NO_VOLUME;
|
|
21949
22012
|
outputAnalyser = null;
|
|
21950
|
-
|
|
22013
|
+
outputVolumeProvider = NO_VOLUME;
|
|
21951
22014
|
_isMuted = false;
|
|
21952
22015
|
input = {
|
|
21953
22016
|
close: async () => {
|
|
@@ -21970,6 +22033,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
21970
22033
|
console.warn("Cannot set microphone muted: room not connected or no local participant");
|
|
21971
22034
|
return;
|
|
21972
22035
|
}
|
|
22036
|
+
this._isMuted = isMuted;
|
|
21973
22037
|
const micTrackPublication = this.room.localParticipant.getTrackPublication(Track.Source.Microphone);
|
|
21974
22038
|
if (micTrackPublication?.track) try {
|
|
21975
22039
|
if (isMuted) await micTrackPublication.track.mute();
|
|
@@ -21978,10 +22042,24 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
21978
22042
|
await this.room.localParticipant.setMicrophoneEnabled(!isMuted);
|
|
21979
22043
|
}
|
|
21980
22044
|
else await this.room.localParticipant.setMicrophoneEnabled(!isMuted);
|
|
21981
|
-
|
|
22045
|
+
if (!isMuted) {
|
|
22046
|
+
const track = this.room.localParticipant.getTrackPublication(Track.Source.Microphone)?.track;
|
|
22047
|
+
if (track) this.setupInputAnalyser(track.mediaStreamTrack);
|
|
22048
|
+
}
|
|
21982
22049
|
},
|
|
21983
22050
|
isMuted: () => this._isMuted,
|
|
21984
|
-
getAnalyser: () => void 0
|
|
22051
|
+
getAnalyser: () => this.inputAnalyser ?? void 0,
|
|
22052
|
+
getVolume: () => {
|
|
22053
|
+
if (this._isMuted) return 0;
|
|
22054
|
+
return this.inputVolumeProvider.getVolume();
|
|
22055
|
+
},
|
|
22056
|
+
getByteFrequencyData: (buffer) => {
|
|
22057
|
+
if (this._isMuted) {
|
|
22058
|
+
buffer.fill(0);
|
|
22059
|
+
return;
|
|
22060
|
+
}
|
|
22061
|
+
this.inputVolumeProvider.getByteFrequencyData(buffer);
|
|
22062
|
+
}
|
|
21985
22063
|
};
|
|
21986
22064
|
output = {
|
|
21987
22065
|
close: async () => {},
|
|
@@ -21995,7 +22073,11 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
21995
22073
|
this.setAudioVolume(volume);
|
|
21996
22074
|
},
|
|
21997
22075
|
interrupt: (_resetDuration) => {},
|
|
21998
|
-
getAnalyser: () => this.outputAnalyser ?? void 0
|
|
22076
|
+
getAnalyser: () => this.outputAnalyser ?? void 0,
|
|
22077
|
+
getVolume: () => this.outputVolumeProvider.getVolume(),
|
|
22078
|
+
getByteFrequencyData: (buffer) => {
|
|
22079
|
+
this.outputVolumeProvider.getByteFrequencyData(buffer);
|
|
22080
|
+
}
|
|
21999
22081
|
};
|
|
22000
22082
|
constructor(room, conversationId, inputFormat, outputFormat, config = {}) {
|
|
22001
22083
|
super(config);
|
|
@@ -22043,6 +22125,8 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22043
22125
|
}
|
|
22044
22126
|
});
|
|
22045
22127
|
await micEnabled;
|
|
22128
|
+
const micTrack = room.localParticipant.getTrackPublication(Track.Source.Microphone)?.track;
|
|
22129
|
+
if (micTrack) connection.setupInputAnalyser(micTrack.mediaStreamTrack);
|
|
22046
22130
|
if (room.name) connection.conversationId = room.name.match(/(conv_[a-zA-Z0-9]+)/)?.[0] || room.name;
|
|
22047
22131
|
const overridesEvent = constructOverrides(config);
|
|
22048
22132
|
connection.debug({
|
|
@@ -22126,6 +22210,13 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22126
22210
|
} catch (error) {
|
|
22127
22211
|
console.warn("Error stopping local tracks:", error);
|
|
22128
22212
|
}
|
|
22213
|
+
if (this.inputAudioContext) {
|
|
22214
|
+
this.inputAudioContext.close().catch((error) => {
|
|
22215
|
+
console.warn("Error closing input audio context:", error);
|
|
22216
|
+
});
|
|
22217
|
+
this.inputAudioContext = null;
|
|
22218
|
+
this.inputAnalyser = null;
|
|
22219
|
+
}
|
|
22129
22220
|
if (this.audioCaptureContext) {
|
|
22130
22221
|
this.audioCaptureContext.close().catch((error) => {
|
|
22131
22222
|
console.warn("Error closing audio capture context:", error);
|
|
@@ -22162,6 +22253,35 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22162
22253
|
getRoom() {
|
|
22163
22254
|
return this.room;
|
|
22164
22255
|
}
|
|
22256
|
+
/**
|
|
22257
|
+
* (Re-)creates an AudioContext + AnalyserNode from the given track and
|
|
22258
|
+
* installs the corresponding VolumeProvider. Called once during create()
|
|
22259
|
+
* and again after an input device switch so the analyser follows the
|
|
22260
|
+
* active mic track.
|
|
22261
|
+
*/
|
|
22262
|
+
setupInputAnalyser(mediaStreamTrack) {
|
|
22263
|
+
if (this.inputAudioContext) {
|
|
22264
|
+
this.inputAudioContext.close().catch(() => {});
|
|
22265
|
+
this.inputAudioContext = null;
|
|
22266
|
+
this.inputAnalyser = null;
|
|
22267
|
+
}
|
|
22268
|
+
try {
|
|
22269
|
+
const ctx = new AudioContext();
|
|
22270
|
+
const analyser = ctx.createAnalyser();
|
|
22271
|
+
ctx.createMediaStreamSource(new MediaStream([mediaStreamTrack])).connect(analyser);
|
|
22272
|
+
this.inputAnalyser = analyser;
|
|
22273
|
+
this.inputAudioContext = ctx;
|
|
22274
|
+
this.inputVolumeProvider = createAnalyserVolumeProvider(analyser, ctx.sampleRate);
|
|
22275
|
+
} catch (error) {
|
|
22276
|
+
console.warn("[ConversationalAI] Failed to set up input volume analyser:", error);
|
|
22277
|
+
}
|
|
22278
|
+
}
|
|
22279
|
+
setInputVolumeProvider(provider) {
|
|
22280
|
+
this.inputVolumeProvider = provider;
|
|
22281
|
+
}
|
|
22282
|
+
setOutputVolumeProvider(provider) {
|
|
22283
|
+
this.outputVolumeProvider = provider;
|
|
22284
|
+
}
|
|
22165
22285
|
async setupAudioCapture(track) {
|
|
22166
22286
|
try {
|
|
22167
22287
|
const audioContext = new AudioContext();
|
|
@@ -22172,6 +22292,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22172
22292
|
const mediaStream = new MediaStream([track.mediaStreamTrack]);
|
|
22173
22293
|
const source = audioContext.createMediaStreamSource(mediaStream);
|
|
22174
22294
|
source.connect(this.outputAnalyser);
|
|
22295
|
+
this.setOutputVolumeProvider(createAnalyserVolumeProvider(this.outputAnalyser, audioContext.sampleRate));
|
|
22175
22296
|
await loadRawAudioProcessor(audioContext.audioWorklet);
|
|
22176
22297
|
const worklet = new AudioWorkletNode(audioContext, "rawAudioProcessor");
|
|
22177
22298
|
this.outputAnalyser.connect(worklet);
|
|
@@ -22236,6 +22357,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22236
22357
|
name: "microphone",
|
|
22237
22358
|
source: Track.Source.Microphone
|
|
22238
22359
|
});
|
|
22360
|
+
this.setupInputAnalyser(audioTrack.mediaStreamTrack);
|
|
22239
22361
|
} catch (error) {
|
|
22240
22362
|
console.error("Failed to change input device:", error);
|
|
22241
22363
|
try {
|
|
@@ -22246,12 +22368,6 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22246
22368
|
throw error;
|
|
22247
22369
|
}
|
|
22248
22370
|
}
|
|
22249
|
-
getOutputByteFrequencyData() {
|
|
22250
|
-
if (!this.outputAnalyser) return null;
|
|
22251
|
-
this.outputFrequencyData ??= new Uint8Array(this.outputAnalyser.frequencyBinCount);
|
|
22252
|
-
this.outputAnalyser.getByteFrequencyData(this.outputFrequencyData);
|
|
22253
|
-
return this.outputFrequencyData;
|
|
22254
|
-
}
|
|
22255
22371
|
};
|
|
22256
22372
|
//#endregion
|
|
22257
22373
|
//#region src/utils/ConnectionFactory.ts
|
|
@@ -22299,7 +22415,7 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22299
22415
|
}
|
|
22300
22416
|
//#endregion
|
|
22301
22417
|
//#region src/TextConversation.ts
|
|
22302
|
-
const EMPTY_FREQUENCY_DATA
|
|
22418
|
+
const EMPTY_FREQUENCY_DATA = new Uint8Array(0);
|
|
22303
22419
|
var TextConversation = class TextConversation extends BaseConversation {
|
|
22304
22420
|
type = "text";
|
|
22305
22421
|
setVolume() {
|
|
@@ -22309,10 +22425,10 @@ registerProcessor("rawAudioProcessor", RawAudioProcessor);
|
|
|
22309
22425
|
throw new Error("setMicMuted is not supported in text conversations");
|
|
22310
22426
|
}
|
|
22311
22427
|
getInputByteFrequencyData() {
|
|
22312
|
-
return EMPTY_FREQUENCY_DATA
|
|
22428
|
+
return EMPTY_FREQUENCY_DATA;
|
|
22313
22429
|
}
|
|
22314
22430
|
getOutputByteFrequencyData() {
|
|
22315
|
-
return EMPTY_FREQUENCY_DATA
|
|
22431
|
+
return EMPTY_FREQUENCY_DATA;
|
|
22316
22432
|
}
|
|
22317
22433
|
getInputVolume() {
|
|
22318
22434
|
return 0;
|
|
@@ -22498,6 +22614,7 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
|
|
|
22498
22614
|
volume = 1;
|
|
22499
22615
|
interrupted = false;
|
|
22500
22616
|
interruptTimeout = null;
|
|
22617
|
+
volumeProvider;
|
|
22501
22618
|
constructor(context, analyser, gain, worklet, audioElement) {
|
|
22502
22619
|
this.context = context;
|
|
22503
22620
|
this.analyser = analyser;
|
|
@@ -22505,10 +22622,17 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
|
|
|
22505
22622
|
this.worklet = worklet;
|
|
22506
22623
|
this.audioElement = audioElement;
|
|
22507
22624
|
this.worklet.port.start();
|
|
22625
|
+
this.volumeProvider = createAnalyserVolumeProvider(analyser, context.sampleRate);
|
|
22508
22626
|
}
|
|
22509
22627
|
getAnalyser() {
|
|
22510
22628
|
return this.analyser;
|
|
22511
22629
|
}
|
|
22630
|
+
getVolume() {
|
|
22631
|
+
return this.volumeProvider.getVolume();
|
|
22632
|
+
}
|
|
22633
|
+
getByteFrequencyData(buffer) {
|
|
22634
|
+
this.volumeProvider.getByteFrequencyData(buffer);
|
|
22635
|
+
}
|
|
22512
22636
|
addListener(listener) {
|
|
22513
22637
|
this.worklet.port.addEventListener("message", listener);
|
|
22514
22638
|
}
|
|
@@ -22617,6 +22741,7 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
|
|
|
22617
22741
|
return isIosDevice() ? { ideal: deviceId } : { exact: deviceId };
|
|
22618
22742
|
}
|
|
22619
22743
|
muted = false;
|
|
22744
|
+
volumeProvider;
|
|
22620
22745
|
constructor(context, analyser, worklet, inputStream, mediaStreamSource, permissions, onError = console.error) {
|
|
22621
22746
|
this.context = context;
|
|
22622
22747
|
this.analyser = analyser;
|
|
@@ -22627,10 +22752,22 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
|
|
|
22627
22752
|
this.onError = onError;
|
|
22628
22753
|
this.permissions.addEventListener("change", this.handlePermissionsChange);
|
|
22629
22754
|
this.worklet.port.start();
|
|
22755
|
+
this.volumeProvider = createAnalyserVolumeProvider(analyser, context.sampleRate);
|
|
22630
22756
|
}
|
|
22631
22757
|
getAnalyser() {
|
|
22632
22758
|
return this.analyser;
|
|
22633
22759
|
}
|
|
22760
|
+
getVolume() {
|
|
22761
|
+
if (this.muted) return 0;
|
|
22762
|
+
return this.volumeProvider.getVolume();
|
|
22763
|
+
}
|
|
22764
|
+
getByteFrequencyData(buffer) {
|
|
22765
|
+
if (this.muted) {
|
|
22766
|
+
buffer.fill(0);
|
|
22767
|
+
return;
|
|
22768
|
+
}
|
|
22769
|
+
this.volumeProvider.getByteFrequencyData(buffer);
|
|
22770
|
+
}
|
|
22634
22771
|
isMuted() {
|
|
22635
22772
|
return this.muted;
|
|
22636
22773
|
}
|
|
@@ -22771,7 +22908,6 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
|
|
|
22771
22908
|
let setupStrategy = webSessionSetup;
|
|
22772
22909
|
//#endregion
|
|
22773
22910
|
//#region src/VoiceConversation.ts
|
|
22774
|
-
const EMPTY_FREQUENCY_DATA = new Uint8Array(0);
|
|
22775
22911
|
var VoiceConversation = class VoiceConversation extends BaseConversation {
|
|
22776
22912
|
type = "voice";
|
|
22777
22913
|
static async requestWakeLock() {
|
|
@@ -22860,42 +22996,27 @@ registerProcessor("audioConcatProcessor", AudioConcatProcessor);
|
|
|
22860
22996
|
this.updateMode("speaking");
|
|
22861
22997
|
}
|
|
22862
22998
|
}
|
|
22863
|
-
|
|
22864
|
-
if (frequencyData.length === 0) return 0;
|
|
22865
|
-
let volume = 0;
|
|
22866
|
-
for (let i = 0; i < frequencyData.length; i++) volume += frequencyData[i] / 255;
|
|
22867
|
-
volume /= frequencyData.length;
|
|
22868
|
-
return volume < 0 ? 0 : volume > 1 ? 1 : volume;
|
|
22869
|
-
};
|
|
22999
|
+
static FREQUENCY_BIN_COUNT = 1024;
|
|
22870
23000
|
setMicMuted(isMuted) {
|
|
22871
23001
|
this.input.setMuted(isMuted).catch((error) => {
|
|
22872
23002
|
this.options.onError?.("Failed to set input muted state", error);
|
|
22873
23003
|
});
|
|
22874
23004
|
}
|
|
22875
23005
|
getInputByteFrequencyData() {
|
|
22876
|
-
|
|
22877
|
-
|
|
22878
|
-
this.inputFrequencyData ??= new Uint8Array(analyser.frequencyBinCount);
|
|
22879
|
-
analyser.getByteFrequencyData(this.inputFrequencyData);
|
|
23006
|
+
this.inputFrequencyData ??= new Uint8Array(VoiceConversation.FREQUENCY_BIN_COUNT);
|
|
23007
|
+
this.input.getByteFrequencyData(this.inputFrequencyData);
|
|
22880
23008
|
return this.inputFrequencyData;
|
|
22881
23009
|
}
|
|
22882
23010
|
getOutputByteFrequencyData() {
|
|
22883
|
-
|
|
22884
|
-
|
|
22885
|
-
if (webrtcData) return webrtcData;
|
|
22886
|
-
return new Uint8Array(1024);
|
|
22887
|
-
}
|
|
22888
|
-
const analyser = this.output.getAnalyser();
|
|
22889
|
-
if (!analyser) return EMPTY_FREQUENCY_DATA;
|
|
22890
|
-
this.outputFrequencyData ??= new Uint8Array(analyser.frequencyBinCount);
|
|
22891
|
-
analyser.getByteFrequencyData(this.outputFrequencyData);
|
|
23011
|
+
this.outputFrequencyData ??= new Uint8Array(VoiceConversation.FREQUENCY_BIN_COUNT);
|
|
23012
|
+
this.output.getByteFrequencyData(this.outputFrequencyData);
|
|
22892
23013
|
return this.outputFrequencyData;
|
|
22893
23014
|
}
|
|
22894
23015
|
getInputVolume() {
|
|
22895
|
-
return this.
|
|
23016
|
+
return this.input.getVolume();
|
|
22896
23017
|
}
|
|
22897
23018
|
getOutputVolume() {
|
|
22898
|
-
return this.
|
|
23019
|
+
return this.output.getVolume();
|
|
22899
23020
|
}
|
|
22900
23021
|
async changeInputDevice({ sampleRate, format, preferHeadphonesForIosDevices, inputDeviceId }) {
|
|
22901
23022
|
try {
|