Skip to content

Commit ad3b2a0

Browse files
committed
improve audio stack using 16 bit integers and syncing to video, also use zero data detection instead of a bit threshold
1 parent b30b63e commit ad3b2a0

File tree

5 files changed

+76
-7
lines changed

5 files changed

+76
-7
lines changed

index.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,13 @@ aio.on('connection', function (socket) {
161161
device: 'auto_null.monitor',
162162
channels: 2,
163163
rate: 44100,
164-
format: 'F32LE',
164+
format: 'S16LE',
165165
});
166166
record.on('connection', function(){
167167
record.on('data', function(chunk) {
168-
// Only send real audio data
169-
if (chunk.length < 26456) {
168+
// Only send non-zero audio data
169+
let i16Array = Int16Array.from(chunk);
170+
if (! i16Array.every(item => item === 0)) {
170171
aio.sockets.to(id).emit('audio', chunk);
171172
}
172173
});

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "kclient",
3-
"version": "0.4.0",
3+
"version": "0.4.1",
44
"description": "Kclient is a wrapper for KasmVNC to add functionality to a containerized environment",
55
"main": "index.js",
66
"dependencies": {

public/js/kclient.js

+70-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,75 @@ eventer(messageEvent,function(e) {
1818
}
1919
},false);
2020

21+
//// PCM player ////
22+
var buffer = [];
23+
var playing = false;
24+
var lock = false;
25+
// Check for audio stop to reset buffer
26+
setInterval(function() {
27+
if (playing) {
28+
if (!lock) {
29+
buffer = [];
30+
playing = false;
31+
}
32+
lock = false;
33+
}
34+
}, 100);
35+
function PCM() {
36+
this.init()
37+
}
38+
// Player Init
39+
PCM.prototype.init = function() {
40+
// Establish audio context
41+
this.audioCtx = new(window.AudioContext || window.webkitAudioContext)({
42+
sampleRate: 44100
43+
})
44+
this.audioCtx.resume()
45+
this.gainNode = this.audioCtx.createGain()
46+
this.gainNode.gain.value = 1
47+
this.gainNode.connect(this.audioCtx.destination)
48+
this.startTime = this.audioCtx.currentTime
49+
}
50+
// Stereo player
51+
PCM.prototype.feed = function(data) {
52+
lock = true;
53+
// Convert bytes to typed array then float32 array
54+
let i16Array = new Int16Array(data, 0, data.length);
55+
let f32Array = Float32Array.from(i16Array, x => x / 32767);
56+
buffer = new Float32Array([...buffer, ...f32Array]);
57+
let buffAudio = this.audioCtx.createBuffer(2, buffer.length, 44100);
58+
let duration = buffAudio.duration / 2;
59+
if ((duration > .05) || (playing)) {
60+
playing = true;
61+
let buffSource = this.audioCtx.createBufferSource();
62+
let arrLength = buffer.length / 2;
63+
let left = buffAudio.getChannelData(0);
64+
let right = buffAudio.getChannelData(1);
65+
let byteCount = 0;
66+
let offset = 1;
67+
for (let count = 0; count < arrLength; count++) {
68+
left[count] = buffer[byteCount];
69+
byteCount += 2;
70+
right[count] = buffer[offset];
71+
offset += 2;
72+
}
73+
buffer = [];
74+
if (this.startTime < this.audioCtx.currentTime) {
75+
this.startTime = this.audioCtx.currentTime;
76+
}
77+
buffSource.buffer = buffAudio;
78+
buffSource.connect(this.gainNode);
79+
buffSource.start(this.startTime);
80+
this.startTime += duration;
81+
}
82+
}
83+
// Destroy player
84+
PCM.prototype.destroy = function() {
85+
buffer = [];
86+
playing = false;
87+
this.audioCtx.close();
88+
this.audioCtx = null;
89+
};
2190

2291
// Handle Toggle divs
2392
function openToggle(id) {
@@ -76,7 +145,7 @@ function audio() {
76145
return;
77146
}
78147
socket.emit('open', '');
79-
player = new PCMPlayer();
148+
player = new PCM();
80149
$('#audioButton').addClass("icons-selected");
81150
}
82151

public/js/pcm-player.js

-1
This file was deleted.

public/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "<%- title -%>",
33
"short_name": "<%- title -%>",
44
"manifest_version": 2,
5-
"version": "0.4.0",
5+
"version": "0.4.1",
66
"display": "fullscreen",
77
"background_color": "#000000",
88
"theme_color": "#000000",

0 commit comments

Comments
 (0)