From a50fa9eff0b87f5d8698c172b1e570a14e704e21 Mon Sep 17 00:00:00 2001 From: Kwangsoo Yeo Date: Wed, 19 Jul 2023 12:37:56 -0700 Subject: [PATCH 1/3] change wasm memory detach handler --- package.json | 2 +- src/resampler.ts | 83 +++++++++++---------------------- src/resampler_worker_handler.ts | 24 ---------- 3 files changed, 27 insertions(+), 82 deletions(-) diff --git a/package.json b/package.json index 4a398d9..8be8687 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@picovoice/web-voice-processor", - "version": "4.0.7", + "version": "4.0.8", "description": "Real-time audio processing for voice, in web browsers", "entry": "src/index.ts", "module": "dist/esm/index.js", diff --git a/src/resampler.ts b/src/resampler.ts index 0054b17..cedc49b 100644 --- a/src/resampler.ts +++ b/src/resampler.ts @@ -56,8 +56,6 @@ class Resampler { private readonly _outputBufferAddress: number; private _wasmMemory: WebAssembly.Memory; - private _memoryBuffer: Int16Array; - private _memoryBufferView: DataView; private readonly _frameLength: number; private readonly _inputBufferLength: number; @@ -65,8 +63,6 @@ class Resampler { private static _wasm: string; public static _version: string; - private _isWasmMemoryDetached: boolean = false; - private constructor(handleWasm: ResamplerWasmOutput) { Resampler._version = handleWasm.version; @@ -85,9 +81,6 @@ class Resampler { this._objectAddress = handleWasm.objectAddress; this._outputBufferAddress = handleWasm.outputBufferAddress; - this._memoryBuffer = new Int16Array(handleWasm.memory.buffer); - this._memoryBufferView = new DataView(handleWasm.memory.buffer); - this._frameLength = handleWasm.frameLength; this._inputBufferLength = handleWasm.inputFrameLength; } @@ -246,10 +239,6 @@ class Resampler { inputFrame: Int16Array | Float32Array, outputBuffer: Int16Array, ): number { - if (this._isWasmMemoryDetached) { - return 0; - } - if (inputFrame.length > this._inputBufferLength) { throw new Error(`InputFrame length '${inputFrame.length}' must be smaller than ${this._inputBufferLength}.`); } @@ -269,29 +258,27 @@ class Resampler { throw new Error(`Invalid inputFrame type: ${typeof inputFrame}. Expected Float32Array or Int16Array.`); } - try { - this._memoryBuffer.set( - inputBuffer, - this._inputBufferAddress / Int16Array.BYTES_PER_ELEMENT, - ); + const memoryBuffer = new Int16Array(this._wasmMemory.buffer); + const memoryBufferView = new DataView(this._wasmMemory.buffer); - const processedSamples = this._pvResamplerProcess( - this._objectAddress, - this._inputBufferAddress, - inputFrame.length, - this._outputBufferAddress, + memoryBuffer.set( + inputBuffer, + this._inputBufferAddress / Int16Array.BYTES_PER_ELEMENT, + ); + + const processedSamples = this._pvResamplerProcess( + this._objectAddress, + this._inputBufferAddress, + inputFrame.length, + this._outputBufferAddress, + ); + for (let i = 0; i < processedSamples; i++) { + outputBuffer[i] = memoryBufferView.getInt16( + this._outputBufferAddress + i * Int16Array.BYTES_PER_ELEMENT, + true, ); - for (let i = 0; i < processedSamples; i++) { - outputBuffer[i] = this._memoryBufferView.getInt16( - this._outputBufferAddress + i * Int16Array.BYTES_PER_ELEMENT, - true, - ); - } - return processedSamples; - } catch (error: any) { - this._errorHandler(); - throw error; } + return processedSamples; } public reset(): void { @@ -316,35 +303,17 @@ class Resampler { } public getNumRequiredInputSamples(numSample: number): number { - try { - return this._pvResamplerConvertNumSamplesToInputSampleRate( - this._objectAddress, - numSample, - ); - } catch (error: any) { - this._errorHandler(); - throw error; - } + return this._pvResamplerConvertNumSamplesToInputSampleRate( + this._objectAddress, + numSample, + ); } public getNumRequiredOutputSamples(numSample: number): number { - try { - return this._pvResamplerConvertNumSamplesToOutputSampleRate( - this._objectAddress, - numSample, - ); - } catch (error: any) { - this._errorHandler(); - throw error; - } - } - - private _errorHandler(): void { - if (this._memoryBuffer.length === 0) { - this._isWasmMemoryDetached = true; - this.release(); - throw new Error("Invalid memory state: browser might have cleaned resources automatically. Re-initialize Resampler."); - } + return this._pvResamplerConvertNumSamplesToOutputSampleRate( + this._objectAddress, + numSample, + ); } } diff --git a/src/resampler_worker_handler.ts b/src/resampler_worker_handler.ts index 8bb0a8a..b970937 100644 --- a/src/resampler_worker_handler.ts +++ b/src/resampler_worker_handler.ts @@ -17,8 +17,6 @@ import Resampler from './resampler'; let accumulator: BufferAccumulator | null = null; let resampler: Resampler | null = null; -let isResamplerDetached = false; -let initParams: any = {}; class BufferAccumulator { private readonly _frameLength: number; @@ -81,14 +79,6 @@ onmessage = async function (event: MessageEvent): Promis event.data.filterOrder, event.data.frameLength, ); - - initParams = { - inputSampleRate: event.data.inputSampleRate, - outputSampleRate: event.data.outputSampleRate, - filterOrder: event.data.filterOrder, - frameLength: event.data.frameLength, - }; - accumulator = new BufferAccumulator( resampler.frameLength, resampler.inputBufferLength); @@ -105,15 +95,6 @@ onmessage = async function (event: MessageEvent): Promis } break; case 'process': - if (isResamplerDetached) { - isResamplerDetached = false; - resampler = await Resampler.create( - initParams.inputSampleRate, - initParams.outputSampleRate, - initParams.filterOrder, - initParams.frameLength, - ); - } if (resampler === null) { self.postMessage({ command: 'error', @@ -125,11 +106,6 @@ onmessage = async function (event: MessageEvent): Promis const {inputFrame} = event.data; accumulator?.process(inputFrame); } catch (e: any) { - if (e.message.includes('Invalid memory state')) { - resampler.release(); - resampler = null; - isResamplerDetached = true; - } self.postMessage({ command: 'error', message: e.message, From ccb24ed665e990ddcdf0ba28ba2779ea09375a15 Mon Sep 17 00:00:00 2001 From: Kwangsoo Yeo Date: Wed, 19 Jul 2023 13:06:41 -0700 Subject: [PATCH 2/3] rev --- src/resampler.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/resampler.ts b/src/resampler.ts index cedc49b..75d27ea 100644 --- a/src/resampler.ts +++ b/src/resampler.ts @@ -259,7 +259,6 @@ class Resampler { } const memoryBuffer = new Int16Array(this._wasmMemory.buffer); - const memoryBufferView = new DataView(this._wasmMemory.buffer); memoryBuffer.set( inputBuffer, @@ -272,6 +271,9 @@ class Resampler { inputFrame.length, this._outputBufferAddress, ); + + const memoryBufferView = new DataView(this._wasmMemory.buffer); + for (let i = 0; i < processedSamples; i++) { outputBuffer[i] = memoryBufferView.getInt16( this._outputBufferAddress + i * Int16Array.BYTES_PER_ELEMENT, From dd2c9b0b320fd6341c22eaaabf2e32cd36d16d8c Mon Sep 17 00:00:00 2001 From: Kwangsoo Yeo Date: Wed, 19 Jul 2023 13:40:18 -0700 Subject: [PATCH 3/3] release + demo update --- demo/package.json | 2 +- demo/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/demo/package.json b/demo/package.json index 478c665..3609d2b 100644 --- a/demo/package.json +++ b/demo/package.json @@ -17,7 +17,7 @@ "author": "Picovoice Inc", "license": "Apache-2.0", "dependencies": { - "@picovoice/web-voice-processor": "^4.0.7", + "@picovoice/web-voice-processor": "^4.0.8", "http-server": "^14.0.0", "wavefile": "^11.0.0" } diff --git a/demo/yarn.lock b/demo/yarn.lock index 34bea20..dd42930 100644 --- a/demo/yarn.lock +++ b/demo/yarn.lock @@ -9,10 +9,10 @@ dependencies: commander "^9.2.0" -"@picovoice/web-voice-processor@^4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@picovoice/web-voice-processor/-/web-voice-processor-4.0.7.tgz#5df76c3b283a4c90ee53865cdd5dab0099acb823" - integrity sha512-LtZDNrtezi7B/1CWeda4YE7M+SAKN7ALvGf+j357TmmJRqnMnt21urAiZ90zSMUbFCoYqKIeq8rMGU7RkKaeEw== +"@picovoice/web-voice-processor@^4.0.8": + version "4.0.8" + resolved "https://registry.yarnpkg.com/@picovoice/web-voice-processor/-/web-voice-processor-4.0.8.tgz#95247a5393cac4d16490a53feb0f413c902ee5fa" + integrity sha512-/OSHn8YKniMo0jP5EwGimLOxvLQl/Yx4Hs+LydNmoSu4hfBrDdzhhfhB79118uDiK4aUUKx2A/RAD9TG0mQ/ng== dependencies: "@picovoice/web-utils" "=1.3.1"