TeaWeb/web/js/workers/codec/OpusCodec.ts

175 lines
5.9 KiB
TypeScript
Raw Normal View History

2020-03-31 01:27:59 +02:00
import * as cworker from "./CodecWorker";
import {CodecType} from "tc-backend/web/codec/Codec";
import {CodecWorker} from "./CodecWorker";
const prefix = "OpusWorker";
declare global {
interface Window {
__init_em_module: ((Module: any) => void)[];
}
}
self.__init_em_module = self.__init_em_module || [];
2018-04-11 17:56:09 +02:00
Implemented the Material Design and fixed some bugs (#33) * cleaned up some files * Fundamental style update * Redesigned some style * fixed hostbanner popup * Removed old identity stuff * fixed close listener * Fixed changelog date * fixed release chat icons * fixed url * Fixed hostbanner * Uploaded missing images * Improved update handling * Improved script files * Fixed loading error and icon error * fixed Yes/No modal * Fixed loader issues with MS Edge * fixed modal style bug * Fixed control bar overflow for small devices * Improved error handling on identity creation * Logging generate error to terminal * fixed possible php error * fixed some possible loading errors when other files have'nt been already loaded. * removed debug message * Changed emsrcypten flags * Improved codec error handling * removed webassembly as required dependency * Improved and fixed channel tree issues * Improved the sliders * Removed unneeded files * fixed loader versions cache * second slight performance improved (dont animate elements anymore if they are not shown) * Fixed query visibility setting * not showing useless client infos for query clients * Added an auto reconnect system * Added a canceled message and increased reconnect interval * removed implemented todo * fixed repetitive channel names * Reworked the channel tree selected lines * Fixed channel tree names * Fixed name alignment * fixed the native client * added min width to the server select groups to avoid a disappearing effect on shrink * fixed bugged downloaded icons
2019-02-17 16:08:10 +01:00
const WASM_ERROR_MESSAGES = [
'no native wasm support detected'
];
2020-03-31 01:27:59 +02:00
let Module;
self.__init_em_module.push(m => Module = m);
const runtime_initialize_promise = new Promise((resolve, reject) => {
self.__init_em_module.push(Module => {
const cleanup = () => {
Module['onRuntimeInitialized'] = undefined;
Module['onAbort'] = undefined;
};
Module['onRuntimeInitialized'] = () => {
cleanup();
resolve();
};
Module['onAbort'] = error => {
cleanup();
let message;
if(error instanceof DOMException)
message = "DOMException (" + error.name + "): " + error.code + " => " + error.message;
else {
abort_message = error;
message = error;
if(error.indexOf("no binaryen method succeeded") != -1) {
for(const error of WASM_ERROR_MESSAGES) {
if(last_error_message.indexOf(error) != -1) {
message = "no native wasm support detected, but its required";
break;
}
}
}
}
2018-04-18 20:12:10 +02:00
2020-03-31 01:27:59 +02:00
reject(message);
}
});
});
Implemented the Material Design and fixed some bugs (#33) * cleaned up some files * Fundamental style update * Redesigned some style * fixed hostbanner popup * Removed old identity stuff * fixed close listener * Fixed changelog date * fixed release chat icons * fixed url * Fixed hostbanner * Uploaded missing images * Improved update handling * Improved script files * Fixed loading error and icon error * fixed Yes/No modal * Fixed loader issues with MS Edge * fixed modal style bug * Fixed control bar overflow for small devices * Improved error handling on identity creation * Logging generate error to terminal * fixed possible php error * fixed some possible loading errors when other files have'nt been already loaded. * removed debug message * Changed emsrcypten flags * Improved codec error handling * removed webassembly as required dependency * Improved and fixed channel tree issues * Improved the sliders * Removed unneeded files * fixed loader versions cache * second slight performance improved (dont animate elements anymore if they are not shown) * Fixed query visibility setting * not showing useless client infos for query clients * Added an auto reconnect system * Added a canceled message and increased reconnect interval * removed implemented todo * fixed repetitive channel names * Reworked the channel tree selected lines * Fixed channel tree names * Fixed name alignment * fixed the native client * added min width to the server select groups to avoid a disappearing effect on shrink * fixed bugged downloaded icons
2019-02-17 16:08:10 +01:00
let abort_message: string = undefined;
let last_error_message: string;
2020-03-31 01:27:59 +02:00
self.__init_em_module.push(Module => {
Module['print'] = function() {
if(arguments.length == 1 && arguments[0] == abort_message)
return; /* we don't need to reprint the abort message! */
Implemented the Material Design and fixed some bugs (#33) * cleaned up some files * Fundamental style update * Redesigned some style * fixed hostbanner popup * Removed old identity stuff * fixed close listener * Fixed changelog date * fixed release chat icons * fixed url * Fixed hostbanner * Uploaded missing images * Improved update handling * Improved script files * Fixed loading error and icon error * fixed Yes/No modal * Fixed loader issues with MS Edge * fixed modal style bug * Fixed control bar overflow for small devices * Improved error handling on identity creation * Logging generate error to terminal * fixed possible php error * fixed some possible loading errors when other files have'nt been already loaded. * removed debug message * Changed emsrcypten flags * Improved codec error handling * removed webassembly as required dependency * Improved and fixed channel tree issues * Improved the sliders * Removed unneeded files * fixed loader versions cache * second slight performance improved (dont animate elements anymore if they are not shown) * Fixed query visibility setting * not showing useless client infos for query clients * Added an auto reconnect system * Added a canceled message and increased reconnect interval * removed implemented todo * fixed repetitive channel names * Reworked the channel tree selected lines * Fixed channel tree names * Fixed name alignment * fixed the native client * added min width to the server select groups to avoid a disappearing effect on shrink * fixed bugged downloaded icons
2019-02-17 16:08:10 +01:00
2020-03-31 01:27:59 +02:00
console.log("Print: ", ...arguments);
};
2020-03-31 01:27:59 +02:00
Module['printErr'] = function() {
if(arguments.length == 1 && arguments[0] == abort_message)
return; /* we don't need to reprint the abort message! */
last_error_message = arguments[0];
for(const suppress of WASM_ERROR_MESSAGES)
if((arguments[0] as string).indexOf(suppress) != -1)
return;
console.error("Error: ",...arguments);
};
2018-04-18 20:12:10 +02:00
Module['locateFile'] = file => "../../wasm/" + file;
2020-03-31 01:27:59 +02:00
});
2018-04-11 17:56:09 +02:00
enum OpusType {
VOIP = 2048,
AUDIO = 2049,
RESTRICTED_LOWDELAY = 2051
}
class OpusWorker implements CodecWorker {
private channelCount: number;
private nativeHandle: any;
private type: OpusType;
private fn_newHandle: any;
private fn_decode: any;
private fn_encode: any;
private fn_reset: any;
2020-03-31 01:27:59 +02:00
private fn_error_message: any;
2018-04-11 17:56:09 +02:00
private bufferSize = 4096 * 2;
private encodeBufferRaw: any;
private encodeBuffer: Float32Array;
private decodeBufferRaw: any;
private decodeBuffer: Uint8Array;
constructor(channelCount: number, type: OpusType) {
this.channelCount = channelCount;
this.type = type;
}
name(): string {
return "Opus (Type: " + OpusWorker[this.type] + " Channels: " + this.channelCount + ")";
}
2018-04-19 18:42:34 +02:00
initialise?() : string {
2020-03-31 01:27:59 +02:00
this.fn_newHandle = Module.cwrap("codec_opus_createNativeHandle", "number", ["number", "number"]);
this.fn_decode = Module.cwrap("codec_opus_decode", "number", ["number", "number", "number", "number"]);
2018-04-11 17:56:09 +02:00
/* codec_opus_decode(handle, buffer, length, maxlength) */
2020-03-31 01:27:59 +02:00
this.fn_encode = Module.cwrap("codec_opus_encode", "number", ["number", "number", "number", "number"]);
this.fn_reset = Module.cwrap("codec_opus_reset", "number", ["number"]);
this.fn_error_message = Module.cwrap("opus_error_message", "string", ["number"]);
2018-04-11 17:56:09 +02:00
this.nativeHandle = this.fn_newHandle(this.channelCount, this.type);
this.encodeBufferRaw = Module._malloc(this.bufferSize);
this.encodeBuffer = new Float32Array(Module.HEAPF32.buffer, this.encodeBufferRaw, this.bufferSize / 4);
this.decodeBufferRaw = Module._malloc(this.bufferSize);
this.decodeBuffer = new Uint8Array(Module.HEAPU8.buffer, this.decodeBufferRaw, this.bufferSize);
2018-04-19 18:42:34 +02:00
return undefined;
2018-04-11 17:56:09 +02:00
}
deinitialise() { } //TODO
decode(data: Uint8Array): Float32Array | string {
if (data.byteLength > this.decodeBuffer.byteLength) return "Data to long!";
this.decodeBuffer.set(data);
let result = this.fn_decode(this.nativeHandle, this.decodeBuffer.byteOffset, data.byteLength, this.decodeBuffer.byteLength);
2020-03-31 01:27:59 +02:00
if (result < 0) return this.fn_error_message(result);
2018-04-11 17:56:09 +02:00
return Module.HEAPF32.slice(this.decodeBuffer.byteOffset / 4, (this.decodeBuffer.byteOffset / 4) + (result * this.channelCount));
}
encode(data: Float32Array): Uint8Array | string {
this.encodeBuffer.set(data);
let result = this.fn_encode(this.nativeHandle, this.encodeBuffer.byteOffset, data.length, this.encodeBuffer.byteLength);
2020-03-31 01:27:59 +02:00
if (result < 0) return this.fn_error_message(result);
2018-04-11 17:56:09 +02:00
let buf = Module.HEAP8.slice(this.encodeBuffer.byteOffset, this.encodeBuffer.byteOffset + result);
return Uint8Array.from(buf);
}
reset() {
2018-04-18 20:12:10 +02:00
console.log(prefix + " Reseting opus codec!");
2018-04-11 17:56:09 +02:00
this.fn_reset(this.nativeHandle);
}
2020-03-31 01:27:59 +02:00
}
cworker.register_codec(CodecType.OPUS_MUSIC, async () => new OpusWorker(2, OpusType.AUDIO));
cworker.register_codec(CodecType.OPUS_VOICE, async () => new OpusWorker(1, OpusType.VOIP));
cworker.set_initialize_callback(async () => {
try {
require("tc-generated/codec/opus");
} catch (e) {
if(Module) {
if(typeof(Module['onAbort']) === "function") {
Module['onAbort']("Failed to load native scripts");
} /* else the error had been already handled because its a WASM error */
} else {
throw e;
}
}
if(!Module)
throw "Missing module handle";
await runtime_initialize_promise;
return true;
});