More work on audio

This commit is contained in:
Pax1601
2024-09-04 19:41:05 +02:00
parent a64ccab15f
commit 9bbcdac704
22 changed files with 555 additions and 291 deletions

View File

@@ -3,6 +3,7 @@ const { OpusEncoder } = require("@discordjs/opus");
const encoder = new OpusEncoder(16000, 1);
var net = require("net");
var bufferString = "";
const SRS_VERSION = "2.1.0.10";
@@ -13,43 +14,43 @@ enum MessageType {
settings,
}
function fromBytes(array) {
let res = 0;
for (let i = 0; i < array.length; i++) {
res = res << 8;
res += array[array.length - i - 1];
}
return res;
}
function getBytes(value, length) {
let res: number[] = [];
for (let i = 0; i < length; i++) {
res.push(value & 255);
value = value >> 8;
}
return res;
}
export class SRSHandler {
ws: any;
tcp = new net.Socket();
udp = require("dgram").createSocket("udp4");
data = JSON.parse(JSON.stringify(defaultSRSData));
syncInterval: any;
packetQueue = [];
clients = [];
SRSPort = 0;
constructor(ws, SRSPort) {
this.data.Name = `Olympus${globalIndex}`;
this.SRSPort = SRSPort;
globalIndex += 1;
/* Websocket */
this.ws = ws;
this.ws.on("error", console.error);
this.ws.on("message", (data) => {
switch (data[0]) {
case MessageType.audio:
let audioBuffer = data.slice(1);
this.packetQueue.push(audioBuffer);
this.udp.send(audioBuffer, SRSPort, "localhost", (error) => {
if (error)
console.log(`Error sending data to SRS server: ${error}`);
});
break;
case MessageType.settings:
let message = JSON.parse(data.slice(1));
this.data.ClientGuid = message.guid;
this.data.Coalition = message.coalition;
message.settings.forEach((setting, idx) => {
this.data.RadioInfo.radios[idx].freq = setting.frequency;
this.data.RadioInfo.radios[idx].modulation = setting.modulation;
});
break;
default:
break;
}
this.decodeData(data);
});
this.ws.on("close", () => {
this.tcp.end();
@@ -81,6 +82,20 @@ export class SRSHandler {
}, 1000);
});
this.tcp.on("data", (data) => {
bufferString += data.toString();
while (bufferString.includes("\n")) {
try {
let message = JSON.parse(bufferString.split("\n")[0]);
bufferString = bufferString.slice(bufferString.indexOf("\n") + 1);
if (message.Clients !== undefined)
this.clients = message.Clients;
} catch (e) {
console.log(e);
}
}
});
/* UDP */
this.udp.on("listening", () => {
console.log(`Listening to SRS Server on UDP port ${SRSPort}`);
@@ -90,4 +105,52 @@ export class SRSHandler {
if (this.ws && message.length > 22) this.ws.send(message);
});
}
decodeData(data){
switch (data[0]) {
case MessageType.audio:
let packetUint8Array = new Uint8Array(data.slice(1));
let audioLength = fromBytes(packetUint8Array.slice(2, 4));
let frequenciesLength = fromBytes(packetUint8Array.slice(4, 6));
let modulation = fromBytes(packetUint8Array.slice(6 + audioLength + 8, 6 + audioLength + 8 + 1));
let offset = 6 + audioLength + frequenciesLength;
if (modulation == 255) {
packetUint8Array[6 + audioLength + 8] = 2;
this.clients.forEach((client) => {
getBytes(client.RadioInfo.unitId, 4).forEach((value, idx) => {
packetUint8Array[offset + idx] = value;
});
var dst = new ArrayBuffer(packetUint8Array.byteLength);
let newBuffer = new Uint8Array(dst);
newBuffer.set(new Uint8Array(packetUint8Array));
this.udp.send(newBuffer, this.SRSPort, "localhost", (error) => {
if (error)
console.log(`Error sending data to SRS server: ${error}`);
})
})
} else {
this.udp.send(packetUint8Array, this.SRSPort, "localhost", (error) => {
if (error)
console.log(`Error sending data to SRS server: ${error}`);
});
}
break;
case MessageType.settings:
let message = JSON.parse(data.slice(1));
this.data.ClientGuid = message.guid;
this.data.Coalition = message.coalition;
message.settings.forEach((setting, idx) => {
this.data.RadioInfo.radios[idx].freq = setting.frequency;
this.data.RadioInfo.radios[idx].modulation = setting.modulation;
});
break;
default:
break;
}
}
}