diff --git a/shared/js/codec/Codec.ts b/shared/js/codec/Codec.ts
index 125110e3..d5ed395f 100644
--- a/shared/js/codec/Codec.ts
+++ b/shared/js/codec/Codec.ts
@@ -4,7 +4,12 @@ interface CodecCostructor {
enum CodecType {
OPUS_VOICE,
- OPUS_MUSIC
+ OPUS_MUSIC,
+
+ SPEEX_NARROWBAND,
+ SPEEX_WIDEBAND,
+ SPEEX_ULTRA_WIDEBAND,
+ CELT_MONO
}
class BufferChunk {
diff --git a/shared/js/load.ts b/shared/js/load.ts
index 957dc055..201bdb12 100644
--- a/shared/js/load.ts
+++ b/shared/js/load.ts
@@ -121,6 +121,7 @@ function loadDebug() {
if(!window.require) {
console.log("Adding browser audio player");
custom_scripts.push(["js/audio/AudioPlayer.js"]);
+ custom_scripts.push(["js/audio/WebCodec.js"]);
}
load_wait_scripts([
diff --git a/shared/js/voice/VoiceHandler.ts b/shared/js/voice/VoiceHandler.ts
index 56ea4d28..a799ea7f 100644
--- a/shared/js/voice/VoiceHandler.ts
+++ b/shared/js/voice/VoiceHandler.ts
@@ -13,7 +13,7 @@ class CodecPool {
handle: VoiceConnection;
codecIndex: number;
name: string;
- creator: () => BasicCodec;
+ type: CodecType;
entries: CodecPoolEntry[] = [];
maxInstances: number = 2;
@@ -26,6 +26,7 @@ class CodecPool {
console.log("Release again! (%o)", codec);
this.releaseCodec(i + 1);
}).catch(error => {
+ console.warn("Disabling codec support for " + this.name);
if(this._supported) {
createErrorModal("Could not load codec driver", "Could not load or initialize codec " + this.name + "
" +
"Error: " + JSON.stringify(error) + "
").open();
@@ -35,11 +36,11 @@ class CodecPool {
});
}
- supported() { return this.creator != undefined && this._supported; }
+ supported() { return this._supported; }
ownCodec?(clientId: number, create: boolean = true) : Promise {
return new Promise((resolve, reject) => {
- if(!this.creator || !this._supported) {
+ if(!this._supported) {
reject("unsupported codec!");
return;
}
@@ -72,7 +73,7 @@ class CodecPool {
if(freeSlot == 0){
freeSlot = this.entries.length;
let entry = new CodecPoolEntry();
- entry.instance = this.creator();
+ entry.instance = audio.codec.new_instance(this.type);
entry.instance.on_encoded_data = buffer => this.handle.handleEncodedVoicePacket(buffer, this.codecIndex);
this.entries.push(entry);
}
@@ -93,11 +94,13 @@ class CodecPool {
if(this.entries[index].owner == clientId) this.entries[index].owner = 0;
}
- constructor(handle: VoiceConnection, index: number, name: string, creator: () => BasicCodec){
- this.creator = creator;
+ constructor(handle: VoiceConnection, index: number, name: string, type: CodecType){
this.handle = handle;
this.codecIndex = index;
this.name = name;
+ this.type = type;
+
+ this._supported = this.type !== undefined && audio.codec.supported(this.type);
}
}
@@ -121,17 +124,17 @@ class VoiceConnection {
dataChannel: RTCDataChannel;
voiceRecorder: VoiceRecorder;
- private _type: VoiceConnectionType = VoiceConnectionType.NATIVE_ENCODE;
+ private _type: VoiceConnectionType = VoiceConnectionType.JS_ENCODE;
local_audio_stream: any;
private codec_pool: CodecPool[] = [
- new CodecPool(this,0,"Spex A", undefined), //Spex
- new CodecPool(this,1,"Spex B", undefined), //Spex
- new CodecPool(this,2,"Spex C", undefined), //Spex
- new CodecPool(this,3,"CELT Mono", undefined), //CELT Mono
- new CodecPool(this,4,"Opus Voice", () => { return audio.codec.new_instance(CodecType.OPUS_VOICE) }), //opus voice
- new CodecPool(this,5,"Opus Music", () => { return audio.codec.new_instance(CodecType.OPUS_MUSIC) }) //opus music
+ new CodecPool(this,0,"Speex Narrowband", CodecType.SPEEX_NARROWBAND),
+ new CodecPool(this,1,"Speex Wideband", CodecType.SPEEX_WIDEBAND),
+ new CodecPool(this,2,"Speex Ultra Wideband", CodecType.SPEEX_ULTRA_WIDEBAND),
+ new CodecPool(this,3,"CELT Mono", CodecType.CELT_MONO),
+ new CodecPool(this,4,"Opus Voice", CodecType.OPUS_VOICE),
+ new CodecPool(this,5,"Opus Music", CodecType.OPUS_MUSIC)
];
private vpacketId: number = 0;
@@ -148,6 +151,12 @@ class VoiceConnection {
audio.player.on_ready(() => {
log.info(LogCategory.VOICE, "Initializing voice handler after AudioController has been initialized!");
+ if(native_client) {
+ this.codec_pool[0].initialize(2);
+ this.codec_pool[1].initialize(2);
+ this.codec_pool[2].initialize(2);
+ this.codec_pool[3].initialize(2);
+ }
this.codec_pool[4].initialize(2);
this.codec_pool[5].initialize(2);
@@ -415,6 +424,10 @@ class VoiceConnection {
}
}
+ private current_channel_codec() : number {
+ return (this.client.getClient().currentChannel() || {properties: { channel_codec: 4}}).properties.channel_codec;
+ }
+
private handleVoiceData(data: AudioBuffer, head: boolean) {
if(!this.voiceRecorder) return;
if(!this.client.connected) return false;
@@ -426,8 +439,9 @@ class VoiceConnection {
}
//TODO Use channel codec!
- this.codec_pool[4].ownCodec(this.client.getClientId())
- .then(encoder => encoder.encodeSamples(this.client.getClient().getAudioController().codecCache(4), data));
+ const codec = this.current_channel_codec();
+ this.codec_pool[codec].ownCodec(this.client.getClientId())
+ .then(encoder => encoder.encodeSamples(this.client.getClient().getAudioController().codecCache(codec), data));
}
private handleVoiceEnded() {
@@ -439,7 +453,7 @@ class VoiceConnection {
console.log("Local voice ended");
if(this.dataChannel)
- this.sendVoicePacket(new Uint8Array(0), 5); //TODO Use channel codec!
+ this.sendVoicePacket(new Uint8Array(0), this.current_channel_codec()); //TODO Use channel codec!
}
private handleVoiceStarted() {
diff --git a/shared/js/workers/codec/CodecWorker.ts b/shared/js/workers/codec/CodecWorker.ts
index 2b8fedb9..1563e1c5 100644
--- a/shared/js/workers/codec/CodecWorker.ts
+++ b/shared/js/workers/codec/CodecWorker.ts
@@ -23,6 +23,7 @@ onmessage = function(e: MessageEvent) {
//console.log(prefix + " Got from main: %o", data);
switch (data.command) {
case "initialise":
+ let error;
console.log(prefix + "Got initialize for type " + CodecType[data.type as CodecType]);
switch (data.type as CodecType) {
case CodecType.OPUS_MUSIC:
@@ -32,12 +33,12 @@ onmessage = function(e: MessageEvent) {
codecInstance = new OpusWorker(1, OpusType.VOIP);
break;
default:
- res.message = "Could not find worker type!";
+ error = "Could not find worker type!";
console.error("Could not resolve opus type!");
- return;
+ break;
}
- let error = codecInstance.initialise();
+ error = error || codecInstance.initialise();
if(error)
res["message"] = error;
else
diff --git a/shared/js/workers/tsconfig_worker_codec.json b/shared/js/workers/tsconfig_worker_codec.json
index 974251fc..b2cd3a97 100644
--- a/shared/js/workers/tsconfig_worker_codec.json
+++ b/shared/js/workers/tsconfig_worker_codec.json
@@ -7,6 +7,7 @@
},
"files": [
"codec/CodecWorker.ts",
- "codec/OpusCodec.ts"
+ "codec/OpusCodec.ts",
+ "../codec/Codec.ts"
]
}
\ No newline at end of file
diff --git a/web/js/audio/Codec.ts b/web/js/audio/WebCodec.ts
similarity index 58%
rename from web/js/audio/Codec.ts
rename to web/js/audio/WebCodec.ts
index 5ec59443..fa472b71 100644
--- a/web/js/audio/Codec.ts
+++ b/web/js/audio/WebCodec.ts
@@ -4,4 +4,8 @@ namespace audio.codec {
export function new_instance(type: CodecType) : BasicCodec {
return new CodecWrapperWorker(type);
}
+
+ export function supported(type: CodecType) : boolean {
+ return type == CodecType.OPUS_MUSIC || type == CodecType.OPUS_VOICE;
+ }
}
\ No newline at end of file