Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@speechly/browser-client

Package Overview
Dependencies
Maintainers
6
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@speechly/browser-client - npm Package Compare versions

Comparing version 1.0.14 to 1.0.15

15

index.d.ts

@@ -22,2 +22,13 @@

*
* This method will be called by the Client as part of the initialisation process.
*
* @param apiUrl - url.
* @param authToken - authentication token.
* @param targetSampleRate - target sample rate of audio.
* @param debug - debug flag.
*/
initialize(apiUrl: string, authToken: string, targetSampleRate: number, debug: boolean): Promise<void>;
/**
* Initialises the client.
*
* This should prepare websocket to be used (set source sample rate).

@@ -28,3 +39,3 @@ * This method will be called by the Client as part of the initialisation process.

*/
initialize(sourceSampleRate: number): Promise<void>;
setSourceSampleRate(sourceSampleRate: number): Promise<void>;
/**

@@ -97,2 +108,4 @@ * Closes the client.

private initializeMicrophonePromise?;
private readonly initializeApiClientPromise;
private resolveInitialization?;
private resolveStopContext?;

@@ -99,0 +112,0 @@ private readonly deviceId;

2

package.json
{
"name": "@speechly/browser-client",
"version": "1.0.14",
"version": "1.0.15",
"description": "Browser client for Speechly API",

@@ -5,0 +5,0 @@ "private": false,

@@ -31,2 +31,4 @@ import { ClientOptions, StateChangeCallback, SegmentChangeCallback, TentativeTranscriptCallback, TranscriptCallback, TentativeEntitiesCallback, EntityCallback, IntentCallback } from './types';

private initializeMicrophonePromise?;
private readonly initializeApiClientPromise;
private resolveInitialization?;
private resolveStopContext?;

@@ -33,0 +35,0 @@ private readonly deviceId;

@@ -162,2 +162,5 @@ "use strict";

// 2. Fetch auth token. It doesn't matter if it's not present.
this.initializeApiClientPromise = new Promise(resolve => {
this.resolveInitialization = resolve;
});
if (storedToken == null || !token_1.validateToken(storedToken, this.projectId, this.appId, this.deviceId)) {

@@ -197,9 +200,11 @@ token_1.fetchToken(this.loginUrl, this.projectId, this.appId, this.deviceId)

connect(apiUrl) {
this.apiClient.postMessage({
type: 'INIT',
apiUrl: apiUrl,
authToken: this.authToken,
targetSampleRate: this.sampleRate,
debug: this.debug,
});
if (this.authToken != null) {
this.apiClient.initialize(apiUrl, this.authToken, this.sampleRate, this.debug).then(() => {
if (this.resolveInitialization != null) {
this.resolveInitialization();
}
}).catch(err => {
throw err;
});
}
}

@@ -217,2 +222,3 @@ /**

return __awaiter(this, void 0, void 0, function* () {
yield this.initializeApiClientPromise;
if (this.state !== types_1.ClientState.Disconnected) {

@@ -263,3 +269,3 @@ throw Error('Cannot initialize client - client is not in Disconnected state');

// 3. Initialise websocket.
yield this.apiClient.initialize(this.audioContext.sampleRate);
yield this.apiClient.setSourceSampleRate(this.audioContext.sampleRate);
this.initializeMicrophonePromise = this.microphone.initialize(this.audioContext, opts);

@@ -266,0 +272,0 @@ yield this.initializeMicrophonePromise;

@@ -154,2 +154,13 @@ /**

*
* This method will be called by the Client as part of the initialisation process.
*
* @param apiUrl - url.
* @param authToken - authentication token.
* @param targetSampleRate - target sample rate of audio.
* @param debug - debug flag.
*/
initialize(apiUrl: string, authToken: string, targetSampleRate: number, debug: boolean): Promise<void>;
/**
* Initialises the client.
*
* This should prepare websocket to be used (set source sample rate).

@@ -160,3 +171,3 @@ * This method will be called by the Client as part of the initialisation process.

*/
initialize(sourceSampleRate: number): Promise<void>;
setSourceSampleRate(sourceSampleRate: number): Promise<void>;
/**

@@ -163,0 +174,0 @@ * Closes the client.

@@ -5,2 +5,3 @@ import { APIClient, ResponseCallback, CloseCallback } from './types';

private resolveInitialization?;
private resolveSourceSampleRateSet?;
private startCbs;

@@ -13,3 +14,4 @@ private stopCbs;

constructor();
initialize(sourceSampleRate: number): Promise<void>;
initialize(apiUrl: string, authToken: string, targetSampleRate: number, debug: boolean): Promise<void>;
setSourceSampleRate(sourceSampleRate: number): Promise<void>;
close(): Promise<void>;

@@ -16,0 +18,0 @@ startContext(appId?: string): Promise<string>;

@@ -27,4 +27,2 @@ "use strict";

case types_1.WebsocketResponseType.Opened:
break;
case types_1.WebsocketResponseType.SourceSampleRateSetSuccess:
if (this.resolveInitialization != null) {

@@ -34,2 +32,7 @@ this.resolveInitialization();

break;
case types_1.WebsocketResponseType.SourceSampleRateSetSuccess:
if (this.resolveSourceSampleRateSet != null) {
this.resolveSourceSampleRateSet();
}
break;
case types_1.WebsocketResponseType.Started:

@@ -72,5 +75,19 @@ this.startCbs.forEach(cb => {

}
initialize(sourceSampleRate) {
initialize(apiUrl, authToken, targetSampleRate, debug) {
return __awaiter(this, void 0, void 0, function* () {
this.worker.postMessage({
type: 'INIT',
apiUrl,
authToken,
targetSampleRate,
debug,
});
return new Promise(resolve => {
this.resolveInitialization = resolve;
});
});
}
setSourceSampleRate(sourceSampleRate) {
return __awaiter(this, void 0, void 0, function* () {
this.worker.postMessage({
type: 'SET_SOURSE_SAMPLE_RATE',

@@ -80,3 +97,3 @@ sourceSampleRate,

return new Promise(resolve => {
this.resolveInitialization = resolve;
this.resolveSourceSampleRateSet = resolve;
});

@@ -83,0 +100,0 @@ });

@@ -1,2 +0,2 @@

declare const _default: "/**\n * Known WebSocket response types.\n * @public\n */\nvar WebsocketResponseType;\n(function (WebsocketResponseType) {\n WebsocketResponseType[\"Opened\"] = \"WEBSOCKET_OPEN\";\n WebsocketResponseType[\"SourceSampleRateSetSuccess\"] = \"SOURSE_SAMPLE_RATE_SET_SUCCESS\";\n WebsocketResponseType[\"Started\"] = \"started\";\n WebsocketResponseType[\"Stopped\"] = \"stopped\";\n})(WebsocketResponseType || (WebsocketResponseType = {}));\nvar CONTROL = {\n WRITE_INDEX: 0,\n FRAMES_AVAILABLE: 1,\n LOCK: 2\n};\nvar WebsocketClient = /** @class */ (function () {\n function WebsocketClient(ctx) {\n var _this = this;\n this.isContextStarted = false;\n this.isStartContextConfirmed = false;\n this.shouldResendLastFramesSent = false;\n this.buffer = new Float32Array(0);\n this.lastFramesSent = new Int16Array(0); // to re-send after switch context\n this.debug = false;\n this.initialized = false;\n this.onWebsocketClose = function (event) {\n _this.websocket = undefined;\n _this.connect(0);\n };\n this.onWebsocketOpen = function (_event) {\n if (_this.debug) {\n console.log('[SpeechlyClient]', 'websocket opened');\n }\n _this.workerCtx.postMessage({ type: 'WEBSOCKET_OPEN' });\n };\n this.onWebsocketError = function (_event) {\n if (_this.debug) {\n console.log('[SpeechlyClient]', 'websocket error');\n }\n _this.closeWebsocket();\n };\n this.onWebsocketMessage = function (event) {\n var response;\n try {\n response = JSON.parse(event.data);\n }\n catch (e) {\n console.error('[SpeechlyClient] Error parsing response from the server:', e);\n return;\n }\n if (response.type === WebsocketResponseType.Started) {\n _this.isStartContextConfirmed = true;\n if (_this.shouldResendLastFramesSent) {\n _this.resendLastFrames();\n _this.shouldResendLastFramesSent = false;\n }\n }\n _this.workerCtx.postMessage(response);\n };\n this.workerCtx = ctx;\n }\n WebsocketClient.prototype.init = function (apiUrl, authToken, targetSampleRate, debug) {\n if (this.initialized) {\n console.log('[SpeechlyClient]', 'already initialized');\n return;\n }\n this.debug = debug;\n if (this.debug) {\n console.log('[SpeechlyClient]', 'initialize worker');\n }\n this.apiUrl = apiUrl;\n this.authToken = authToken;\n this.targetSampleRate = targetSampleRate;\n this.initialized = true;\n this.connect(0);\n };\n WebsocketClient.prototype.setSourceSampleRate = function (sourceSampleRate) {\n this.sourceSampleRate = sourceSampleRate;\n this.resampleRatio = this.sourceSampleRate / this.targetSampleRate;\n if (this.debug) {\n console.log('[SpeechlyClient]', 'resampleRatio', this.resampleRatio);\n }\n if (this.resampleRatio > 1) {\n this.filter = generateFilter(this.sourceSampleRate, this.targetSampleRate, 127);\n }\n this.workerCtx.postMessage({ type: 'SOURSE_SAMPLE_RATE_SET_SUCCESS' });\n if (isNaN(this.resampleRatio)) {\n throw Error('resampleRatio is NaN');\n }\n };\n WebsocketClient.prototype.setSharedArrayBuffers = function (controlSAB, dataSAB) {\n this.controlSAB = new Int32Array(controlSAB);\n this.dataSAB = new Float32Array(dataSAB);\n var audioHandleInterval = this.dataSAB.length / 32; // ms\n if (this.debug) {\n console.log('[SpeechlyClient]', 'Audio handle interval', audioHandleInterval, 'ms');\n }\n setInterval(this.sendAudioFromSAB.bind(this), audioHandleInterval);\n };\n WebsocketClient.prototype.connect = function (timeout) {\n if (timeout === void 0) { timeout = 1000; }\n if (this.debug) {\n console.log('[SpeechlyClient]', 'connect in ', timeout / 1000, 'sec');\n }\n setTimeout(this.initializeWebsocket.bind(this), timeout);\n };\n WebsocketClient.prototype.initializeWebsocket = function () {\n if (this.debug) {\n console.log('[SpeechlyClient]', 'connecting to ', this.apiUrl);\n }\n this.websocket = new WebSocket(this.apiUrl, this.authToken);\n this.websocket.addEventListener('open', this.onWebsocketOpen);\n this.websocket.addEventListener('message', this.onWebsocketMessage);\n this.websocket.addEventListener('error', this.onWebsocketError);\n this.websocket.addEventListener('close', this.onWebsocketClose);\n };\n WebsocketClient.prototype.isOpen = function () {\n return this.websocket !== undefined && this.websocket.readyState === this.websocket.OPEN;\n };\n WebsocketClient.prototype.resendLastFrames = function () {\n if (!this.isOpen()) {\n return Error('Cannot resend data through inactive websocket');\n }\n if (this.lastFramesSent.length > 0) {\n this.websocket.send(this.lastFramesSent);\n this.lastFramesSent = new Int16Array(0);\n }\n };\n WebsocketClient.prototype.sendAudio = function (audioChunk) {\n if (!this.isContextStarted) {\n return;\n }\n if (!this.isOpen()) {\n return Error('Cannot send data through inactive websocket');\n }\n if (audioChunk.length > 0) {\n if (this.resampleRatio > 1) {\n // Downsampling\n this.websocket.send(this.downsample(audioChunk));\n }\n else {\n this.websocket.send(float32ToInt16(audioChunk));\n }\n }\n };\n WebsocketClient.prototype.sendAudioFromSAB = function () {\n if (!this.isContextStarted) {\n this.controlSAB[CONTROL.FRAMES_AVAILABLE] = 0;\n this.controlSAB[CONTROL.WRITE_INDEX] = 0;\n return;\n }\n if (this.controlSAB == undefined) {\n return;\n }\n var framesAvailable = this.controlSAB[CONTROL.FRAMES_AVAILABLE];\n var lock = this.controlSAB[CONTROL.LOCK];\n if (lock == 0 && framesAvailable > 0) {\n var data = this.dataSAB.subarray(0, framesAvailable);\n this.controlSAB[CONTROL.FRAMES_AVAILABLE] = 0;\n this.controlSAB[CONTROL.WRITE_INDEX] = 0;\n if (data.length > 0) {\n var frames_1;\n if (this.resampleRatio > 1) {\n frames_1 = this.downsample(data);\n }\n else {\n frames_1 = float32ToInt16(data);\n }\n this.websocket.send(frames_1);\n // 16000 per second, 1000 in 100 ms\n // save last 250 ms\n if (this.lastFramesSent.length > 1024 * 4) {\n this.lastFramesSent = frames_1;\n }\n else {\n var concat = new Int16Array(this.lastFramesSent.length + frames_1.length);\n concat.set(this.lastFramesSent);\n concat.set(frames_1, this.lastFramesSent.length);\n this.lastFramesSent = concat;\n }\n }\n }\n };\n WebsocketClient.prototype.startContext = function (appId) {\n if (!this.isOpen()) {\n throw Error('Cant start context: websocket is inactive');\n }\n if (this.isContextStarted) {\n console.log('Cant start context: it has been already started');\n return;\n }\n this.isContextStarted = true;\n this.isStartContextConfirmed = false;\n if (appId !== undefined) {\n this.websocket.send(JSON.stringify({ event: 'start', appId: appId }));\n }\n else {\n this.websocket.send(JSON.stringify({ event: 'start' }));\n }\n };\n WebsocketClient.prototype.stopContext = function () {\n if (this.websocket == undefined) {\n throw Error('Cant start context: websocket is undefined');\n }\n if (!this.isContextStarted) {\n console.log('Cant stop context: it is not started');\n return;\n }\n this.isContextStarted = false;\n this.isStartContextConfirmed = false;\n var StopEventJSON = JSON.stringify({ event: 'stop' });\n this.websocket.send(StopEventJSON);\n };\n WebsocketClient.prototype.switchContext = function (newAppId) {\n if (this.websocket == undefined) {\n throw Error('Cant switch context: websocket is undefined');\n }\n if (!this.isContextStarted) {\n console.log('Cant switch context: it is not started');\n return;\n }\n if (newAppId == undefined) {\n console.log('Cant switch context: new app id is undefined');\n return;\n }\n this.isStartContextConfirmed = false;\n var StopEventJSON = JSON.stringify({ event: 'stop' });\n this.websocket.send(StopEventJSON);\n this.shouldResendLastFramesSent = true;\n this.websocket.send(JSON.stringify({ event: 'start', appId: newAppId }));\n };\n WebsocketClient.prototype.closeWebsocket = function () {\n if (this.websocket == null) {\n throw Error('Websocket is not open');\n }\n this.websocket.removeEventListener('open', this.onWebsocketOpen);\n this.websocket.removeEventListener('message', this.onWebsocketMessage);\n this.websocket.removeEventListener('error', this.onWebsocketError);\n this.websocket.removeEventListener('close', this.onWebsocketClose);\n this.websocket.close();\n };\n WebsocketClient.prototype.downsample = function (input) {\n var inputBuffer = new Float32Array(this.buffer.length + input.length);\n inputBuffer.set(this.buffer, 0);\n inputBuffer.set(input, this.buffer.length);\n var outputLength = Math.ceil((inputBuffer.length - this.filter.length) / this.resampleRatio);\n var outputBuffer = new Int16Array(outputLength);\n for (var i = 0; i < outputLength; i++) {\n var offset = Math.round(this.resampleRatio * i);\n var val = 0.0;\n for (var j = 0; j < this.filter.length; j++) {\n val += inputBuffer[offset + j] * this.filter[j];\n }\n outputBuffer[i] = val * (val < 0 ? 0x8000 : 0x7fff);\n }\n var remainingOffset = Math.round(this.resampleRatio * outputLength);\n if (remainingOffset < inputBuffer.length) {\n this.buffer = inputBuffer.subarray(remainingOffset);\n }\n else {\n this.buffer = new Float32Array(0);\n }\n return outputBuffer;\n };\n return WebsocketClient;\n}());\nvar ctx = self;\nvar websocketClient = new WebsocketClient(ctx);\nctx.onmessage = function (e) {\n switch (e.data.type) {\n case 'INIT':\n websocketClient.init(e.data.apiUrl, e.data.authToken, e.data.targetSampleRate, e.data.debug);\n break;\n case 'SET_SOURSE_SAMPLE_RATE':\n websocketClient.setSourceSampleRate(e.data.sourceSampleRate);\n break;\n case 'SET_SHARED_ARRAY_BUFFERS':\n websocketClient.setSharedArrayBuffers(e.data.controlSAB, e.data.dataSAB);\n break;\n case 'CLOSE':\n websocketClient.closeWebsocket();\n break;\n case 'START_CONTEXT':\n websocketClient.startContext(e.data.appId);\n break;\n case 'SWITCH_CONTEXT':\n websocketClient.switchContext(e.data.appId);\n break;\n case 'STOP_CONTEXT':\n websocketClient.stopContext();\n break;\n case 'AUDIO':\n websocketClient.sendAudio(e.data.payload);\n break;\n default:\n console.log('WORKER', e);\n }\n};\nfunction float32ToInt16(buffer) {\n var buf = new Int16Array(buffer.length);\n for (var l = 0; l < buffer.length; l++) {\n buf[l] = buffer[l] * (buffer[l] < 0 ? 0x8000 : 0x7fff);\n }\n return buf;\n}\nfunction generateFilter(sourceSampleRate, targetSampleRate, length) {\n if (length % 2 === 0) {\n throw Error('Filter length must be odd');\n }\n var cutoff = targetSampleRate / 2;\n var filter = new Float32Array(length);\n var sum = 0;\n for (var i = 0; i < length; i++) {\n var x = sinc(((2 * cutoff) / sourceSampleRate) * (i - (length - 1) / 2));\n sum += x;\n filter[i] = x;\n }\n for (var i = 0; i < length; i++) {\n filter[i] = filter[i] / sum;\n }\n return filter;\n}\nfunction sinc(x) {\n if (x === 0.0) {\n return 1.0;\n }\n var piX = Math.PI * x;\n return Math.sin(piX) / piX;\n}\n";
declare const _default: "/**\n * Known WebSocket response types.\n * @public\n */\nvar WebsocketResponseType;\n(function (WebsocketResponseType) {\n WebsocketResponseType[\"Opened\"] = \"WEBSOCKET_OPEN\";\n WebsocketResponseType[\"SourceSampleRateSetSuccess\"] = \"SOURSE_SAMPLE_RATE_SET_SUCCESS\";\n WebsocketResponseType[\"Started\"] = \"started\";\n WebsocketResponseType[\"Stopped\"] = \"stopped\";\n})(WebsocketResponseType || (WebsocketResponseType = {}));\nvar CONTROL = {\n WRITE_INDEX: 0,\n FRAMES_AVAILABLE: 1,\n LOCK: 2\n};\nvar WebsocketClient = /** @class */ (function () {\n function WebsocketClient(ctx) {\n var _this = this;\n this.isContextStarted = false;\n this.isStartContextConfirmed = false;\n this.shouldResendLastFramesSent = false;\n this.buffer = new Float32Array(0);\n this.lastFramesSent = new Int16Array(0); // to re-send after switch context\n this.debug = false;\n this.initialized = false;\n this.onWebsocketClose = function (event) {\n _this.websocket = undefined;\n _this.connect(0);\n };\n this.onWebsocketOpen = function (_event) {\n if (_this.debug) {\n console.log('[SpeechlyClient]', 'websocket opened');\n }\n _this.workerCtx.postMessage({ type: 'WEBSOCKET_OPEN' });\n };\n this.onWebsocketError = function (_event) {\n if (_this.debug) {\n console.log('[SpeechlyClient]', 'websocket error');\n }\n _this.closeWebsocket();\n };\n this.onWebsocketMessage = function (event) {\n var response;\n try {\n response = JSON.parse(event.data);\n }\n catch (e) {\n console.error('[SpeechlyClient] Error parsing response from the server:', e);\n return;\n }\n if (response.type === WebsocketResponseType.Started) {\n _this.isStartContextConfirmed = true;\n if (_this.shouldResendLastFramesSent) {\n _this.resendLastFrames();\n _this.shouldResendLastFramesSent = false;\n }\n }\n _this.workerCtx.postMessage(response);\n };\n this.workerCtx = ctx;\n }\n WebsocketClient.prototype.init = function (apiUrl, authToken, targetSampleRate, debug) {\n if (this.initialized) {\n console.log('[SpeechlyClient]', 'already initialized');\n return;\n }\n this.debug = debug;\n if (this.debug) {\n console.log('[SpeechlyClient]', 'initialize worker');\n }\n this.apiUrl = apiUrl;\n this.authToken = authToken;\n this.targetSampleRate = targetSampleRate;\n this.initialized = true;\n this.connect(0);\n };\n WebsocketClient.prototype.setSourceSampleRate = function (sourceSampleRate) {\n this.sourceSampleRate = sourceSampleRate;\n this.resampleRatio = this.sourceSampleRate / this.targetSampleRate;\n if (this.debug) {\n console.log('[SpeechlyClient]', 'resampleRatio', this.resampleRatio);\n }\n if (this.resampleRatio > 1) {\n this.filter = generateFilter(this.sourceSampleRate, this.targetSampleRate, 127);\n }\n this.workerCtx.postMessage({ type: 'SOURSE_SAMPLE_RATE_SET_SUCCESS' });\n if (isNaN(this.resampleRatio)) {\n throw Error(\"resampleRatio is NaN source rate is \" + this.sourceSampleRate + \" and target rate is \" + this.targetSampleRate);\n }\n };\n WebsocketClient.prototype.setSharedArrayBuffers = function (controlSAB, dataSAB) {\n this.controlSAB = new Int32Array(controlSAB);\n this.dataSAB = new Float32Array(dataSAB);\n var audioHandleInterval = this.dataSAB.length / 32; // ms\n if (this.debug) {\n console.log('[SpeechlyClient]', 'Audio handle interval', audioHandleInterval, 'ms');\n }\n setInterval(this.sendAudioFromSAB.bind(this), audioHandleInterval);\n };\n WebsocketClient.prototype.connect = function (timeout) {\n if (timeout === void 0) { timeout = 1000; }\n if (this.debug) {\n console.log('[SpeechlyClient]', 'connect in ', timeout / 1000, 'sec');\n }\n setTimeout(this.initializeWebsocket.bind(this), timeout);\n };\n WebsocketClient.prototype.initializeWebsocket = function () {\n if (this.debug) {\n console.log('[SpeechlyClient]', 'connecting to ', this.apiUrl);\n }\n this.websocket = new WebSocket(this.apiUrl, this.authToken);\n this.websocket.addEventListener('open', this.onWebsocketOpen);\n this.websocket.addEventListener('message', this.onWebsocketMessage);\n this.websocket.addEventListener('error', this.onWebsocketError);\n this.websocket.addEventListener('close', this.onWebsocketClose);\n };\n WebsocketClient.prototype.isOpen = function () {\n return this.websocket !== undefined && this.websocket.readyState === this.websocket.OPEN;\n };\n WebsocketClient.prototype.resendLastFrames = function () {\n if (!this.isOpen()) {\n return Error('Cannot resend data through inactive websocket');\n }\n if (this.lastFramesSent.length > 0) {\n this.websocket.send(this.lastFramesSent);\n this.lastFramesSent = new Int16Array(0);\n }\n };\n WebsocketClient.prototype.sendAudio = function (audioChunk) {\n if (!this.isContextStarted) {\n return;\n }\n if (!this.isOpen()) {\n return Error('Cannot send data through inactive websocket');\n }\n if (audioChunk.length > 0) {\n if (this.resampleRatio > 1) {\n // Downsampling\n this.websocket.send(this.downsample(audioChunk));\n }\n else {\n this.websocket.send(float32ToInt16(audioChunk));\n }\n }\n };\n WebsocketClient.prototype.sendAudioFromSAB = function () {\n if (!this.isContextStarted) {\n this.controlSAB[CONTROL.FRAMES_AVAILABLE] = 0;\n this.controlSAB[CONTROL.WRITE_INDEX] = 0;\n return;\n }\n if (this.controlSAB == undefined) {\n return;\n }\n var framesAvailable = this.controlSAB[CONTROL.FRAMES_AVAILABLE];\n var lock = this.controlSAB[CONTROL.LOCK];\n if (lock == 0 && framesAvailable > 0) {\n var data = this.dataSAB.subarray(0, framesAvailable);\n this.controlSAB[CONTROL.FRAMES_AVAILABLE] = 0;\n this.controlSAB[CONTROL.WRITE_INDEX] = 0;\n if (data.length > 0) {\n var frames_1;\n if (this.resampleRatio > 1) {\n frames_1 = this.downsample(data);\n }\n else {\n frames_1 = float32ToInt16(data);\n }\n this.websocket.send(frames_1);\n // 16000 per second, 1000 in 100 ms\n // save last 250 ms\n if (this.lastFramesSent.length > 1024 * 4) {\n this.lastFramesSent = frames_1;\n }\n else {\n var concat = new Int16Array(this.lastFramesSent.length + frames_1.length);\n concat.set(this.lastFramesSent);\n concat.set(frames_1, this.lastFramesSent.length);\n this.lastFramesSent = concat;\n }\n }\n }\n };\n WebsocketClient.prototype.startContext = function (appId) {\n if (!this.isOpen()) {\n throw Error('Cant start context: websocket is inactive');\n }\n if (this.isContextStarted) {\n console.log('Cant start context: it has been already started');\n return;\n }\n this.isContextStarted = true;\n this.isStartContextConfirmed = false;\n if (appId !== undefined) {\n this.websocket.send(JSON.stringify({ event: 'start', appId: appId }));\n }\n else {\n this.websocket.send(JSON.stringify({ event: 'start' }));\n }\n };\n WebsocketClient.prototype.stopContext = function () {\n if (this.websocket == undefined) {\n throw Error('Cant start context: websocket is undefined');\n }\n if (!this.isContextStarted) {\n console.log('Cant stop context: it is not started');\n return;\n }\n this.isContextStarted = false;\n this.isStartContextConfirmed = false;\n var StopEventJSON = JSON.stringify({ event: 'stop' });\n this.websocket.send(StopEventJSON);\n };\n WebsocketClient.prototype.switchContext = function (newAppId) {\n if (this.websocket == undefined) {\n throw Error('Cant switch context: websocket is undefined');\n }\n if (!this.isContextStarted) {\n console.log('Cant switch context: it is not started');\n return;\n }\n if (newAppId == undefined) {\n console.log('Cant switch context: new app id is undefined');\n return;\n }\n this.isStartContextConfirmed = false;\n var StopEventJSON = JSON.stringify({ event: 'stop' });\n this.websocket.send(StopEventJSON);\n this.shouldResendLastFramesSent = true;\n this.websocket.send(JSON.stringify({ event: 'start', appId: newAppId }));\n };\n WebsocketClient.prototype.closeWebsocket = function () {\n if (this.websocket == null) {\n throw Error('Websocket is not open');\n }\n this.websocket.removeEventListener('open', this.onWebsocketOpen);\n this.websocket.removeEventListener('message', this.onWebsocketMessage);\n this.websocket.removeEventListener('error', this.onWebsocketError);\n this.websocket.removeEventListener('close', this.onWebsocketClose);\n this.websocket.close();\n };\n WebsocketClient.prototype.downsample = function (input) {\n var inputBuffer = new Float32Array(this.buffer.length + input.length);\n inputBuffer.set(this.buffer, 0);\n inputBuffer.set(input, this.buffer.length);\n var outputLength = Math.ceil((inputBuffer.length - this.filter.length) / this.resampleRatio);\n var outputBuffer = new Int16Array(outputLength);\n for (var i = 0; i < outputLength; i++) {\n var offset = Math.round(this.resampleRatio * i);\n var val = 0.0;\n for (var j = 0; j < this.filter.length; j++) {\n val += inputBuffer[offset + j] * this.filter[j];\n }\n outputBuffer[i] = val * (val < 0 ? 0x8000 : 0x7fff);\n }\n var remainingOffset = Math.round(this.resampleRatio * outputLength);\n if (remainingOffset < inputBuffer.length) {\n this.buffer = inputBuffer.subarray(remainingOffset);\n }\n else {\n this.buffer = new Float32Array(0);\n }\n return outputBuffer;\n };\n return WebsocketClient;\n}());\nvar ctx = self;\nvar websocketClient = new WebsocketClient(ctx);\nctx.onmessage = function (e) {\n switch (e.data.type) {\n case 'INIT':\n websocketClient.init(e.data.apiUrl, e.data.authToken, e.data.targetSampleRate, e.data.debug);\n break;\n case 'SET_SOURSE_SAMPLE_RATE':\n websocketClient.setSourceSampleRate(e.data.sourceSampleRate);\n break;\n case 'SET_SHARED_ARRAY_BUFFERS':\n websocketClient.setSharedArrayBuffers(e.data.controlSAB, e.data.dataSAB);\n break;\n case 'CLOSE':\n websocketClient.closeWebsocket();\n break;\n case 'START_CONTEXT':\n websocketClient.startContext(e.data.appId);\n break;\n case 'SWITCH_CONTEXT':\n websocketClient.switchContext(e.data.appId);\n break;\n case 'STOP_CONTEXT':\n websocketClient.stopContext();\n break;\n case 'AUDIO':\n websocketClient.sendAudio(e.data.payload);\n break;\n default:\n console.log('WORKER', e);\n }\n};\nfunction float32ToInt16(buffer) {\n var buf = new Int16Array(buffer.length);\n for (var l = 0; l < buffer.length; l++) {\n buf[l] = buffer[l] * (buffer[l] < 0 ? 0x8000 : 0x7fff);\n }\n return buf;\n}\nfunction generateFilter(sourceSampleRate, targetSampleRate, length) {\n if (length % 2 === 0) {\n throw Error('Filter length must be odd');\n }\n var cutoff = targetSampleRate / 2;\n var filter = new Float32Array(length);\n var sum = 0;\n for (var i = 0; i < length; i++) {\n var x = sinc(((2 * cutoff) / sourceSampleRate) * (i - (length - 1) / 2));\n sum += x;\n filter[i] = x;\n }\n for (var i = 0; i < length; i++) {\n filter[i] = filter[i] / sum;\n }\n return filter;\n}\nfunction sinc(x) {\n if (x === 0.0) {\n return 1.0;\n }\n var piX = Math.PI * x;\n return Math.sin(piX) / piX;\n}\n";
export default _default;

@@ -91,3 +91,3 @@ "use strict";

if (isNaN(this.resampleRatio)) {
throw Error('resampleRatio is NaN');
throw Error("resampleRatio is NaN source rate is " + this.sourceSampleRate + " and target rate is " + this.targetSampleRate);
}

@@ -94,0 +94,0 @@ };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc