Skip to content

Commit

Permalink
Merge pull request #51 from Picovoice/wasm-detach
Browse files Browse the repository at this point in the history
  • Loading branch information
laves authored Jul 20, 2023
2 parents 24e0ce8 + dd2c9b0 commit 49988c9
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 87 deletions.
2 changes: 1 addition & 1 deletion demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down
8 changes: 4 additions & 4 deletions demo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
85 changes: 28 additions & 57 deletions src/resampler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,13 @@ class Resampler {
private readonly _outputBufferAddress: number;

private _wasmMemory: WebAssembly.Memory;
private _memoryBuffer: Int16Array;
private _memoryBufferView: DataView;

private readonly _frameLength: number;
private readonly _inputBufferLength: number;

private static _wasm: string;
public static _version: string;

private _isWasmMemoryDetached: boolean = false;

private constructor(handleWasm: ResamplerWasmOutput) {
Resampler._version = handleWasm.version;

Expand All @@ -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;
}
Expand Down Expand Up @@ -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}.`);
}
Expand All @@ -269,29 +258,29 @@ 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 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,
);

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,
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 {
Expand All @@ -316,35 +305,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,
);
}
}

Expand Down
24 changes: 0 additions & 24 deletions src/resampler_worker_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -81,14 +79,6 @@ onmessage = async function (event: MessageEvent<ResamplerWorkerRequest>): 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);
Expand All @@ -105,15 +95,6 @@ onmessage = async function (event: MessageEvent<ResamplerWorkerRequest>): 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',
Expand All @@ -125,11 +106,6 @@ onmessage = async function (event: MessageEvent<ResamplerWorkerRequest>): 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,
Expand Down

0 comments on commit 49988c9

Please sign in to comment.