Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kevinelliott/962ab6a7a5b8f43bfc0c979df4ffa609 to your computer and use it in GitHub Desktop.
Save kevinelliott/962ab6a7a5b8f43bfc0c979df4ffa609 to your computer and use it in GitHub Desktop.
Effort to Reverse Engineer WebSDR @ Twente

Trying to figure out how to capture the audio from the WebSDR @ Twente.

http://websdr.ewi.utwente.nl:8901

Mirror the websdr site

wget --mirror http://websdr.ewi.utwente.nl:8901

Current Efforts

The ruby script will successfully pull down the audio IQ, however the IQ cannot be played in Audacity. I believe this is because the audio is encoded or otherwise slightly mangled to deter us.

To figure this out, I am deobfuscating the websdr-sound.js that handles the data coming in from the WebSocket from the server to see what they are doing to be able to play it with HTML5's AudioContext.

I have also decompiled the Java Applet version of the sound player websdrsound.class that is optionally used if the user's browser cannot do HTML5 Audio.

require 'faye/websocket'
require 'eventmachine'
frequency = "1010"
band = "0"
EM.run {
output = nil
ws = Faye::WebSocket::Client.new('ws://websdr.ewi.utwente.nl:8901/~~stream?v=11', [], headers: {
'Connection' => 'Upgrade',
'Host' => 'websdr.ewi.utwente.nl:8901',
'Origin' => 'http://websdr.ewi.utwente.nl:8901',
'Cookie' => 'view=2; ID=5d83b2fd9c13',
'Pragma' => 'no-cache',
'Cache-Control' => 'no-cache',
'Sec-WebSocket-Key' => 'K+3pZ6WnO+JMDVF5CX4J+w==',
'Sec-WebSocket-Version' => '13',
'Sec-WebSocket-Extensions' => 'x-webkit-deflate-frame',
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15'
})
ws.on :open do |event|
puts "WebSocket connected, sending params to set the tuner..."
pcm_output = File.open('pcm', 'wb')
ws.send("GET /~~param?f=#{frequency}&band=#{band}&lo=-4dd.5&hi=4.5&mode=1&name=")
end
ws.on :message do |event|
puts "Received #{event.data.size} bytes"
event.data.each do |byte|
pcm_output.print byte.chr
end
# p [:message, event.data]
end
ws.on :close do |event|
pcm_output.close
puts "Closed."
ws = nil
end
}
// Originally from http://websdr.ewi.utwente.nl:8901/websdr-sound.js
// Effort made to de-obfuscate
//WebSDR HTML5 client side - Copyright 2013-2020, pa3fwm@websdr.org - all rights reserved
//Since the intended use of this code involves sending a copy to the client computer, I (PA3FWM) hereby allow making it available unmodified, via my original WebSDR server software, to original WebSDR clients. Other use, including distribution in part or entirety or as part of other software, or reverse engineering, is not allowed without my explicit prior permission.
(function () {
var h = null,
AudioContext = window.AudioContext || window.webkitAudioContext;
if (AudioContext) {
document.audioContext || (document.audioContext = new AudioContext());
var convolver;
try {
convolver = document.audioContext.createConvolver;
} catch (wa) {}
convolver || ((document.audioContext = h), (sup_webaudio = !1));
}
var F = 32768;
function za() {
function processEvent(audioProcessEvent) {
var channelData = audioProcessEvent.outputBuffer.getChannelData(0),
bufferIndex;
var timeDifference;
var bufferLength = audioProcessEvent.outputBuffer.length;
processStartTime = new Date().getTime();
if (ha || 2 <= P)
(ha = 0),
3 < P && (P = 0),
(channelData = p),
(timeDifference = processStartTime - wsMessageReceiveTime),
0 <= R && ((R = -1), (actualRemoteSampleRate *= remoteSampleRate / v), (v = remoteSampleRate)),
(p = qa + (timeDifference / 1e3) * remoteSampleRate - H * remoteSampleRate - (bufferLength * v) / audioSampleRate),
(p = Math.round(p)),
(p = (2 * F + p) % F);
200 < processStartTime - lastProcessTime && 0 < lastProcessTime && (ha = 1);
lastProcessTime = processStartTime;
for (bufferIndex = 0; bufferIndex < bufferLength; bufferIndex++) {
var d = 0,
f = (x * v) / audioSampleRate;
q += f;
1 <= q
? ((q -= 1),
(y[p] = 0),
p++,
p >= F && (p -= F),
p == R && ((R = -1), (actualRemoteSampleRate *= remoteSampleRate / v), (v = remoteSampleRate)),
p == g && (P = 1),
(d = q / f),
(d *= y[p]),
(d /= f))
: q < 2 * f && ((d = (2 * f - q) / f), (d *= y[p]), (d /= f));
muted && (d = 0);
channelData[bufferIndex] = 2e-5 * d * volume;
}
M += (1e3 * bufferLength) / actualAudioSampleRate;
processStartTime < M && (M = processStartTime);
V += bufferLength;
V >= audioSampleRate &&
((channelData = 1e3 * (V / (M - sa))),
channelData < 1.01 * audioSampleRate && channelData > 0.99 * audioSampleRate && (actualAudioSampleRate += (channelData - actualAudioSampleRate) / W),
(sa = M),
(V = 0),
(M = processStartTime));
}
document.getElementById("soundappletdiv").innerHTML =
'<div onclick="var e=document.getElementById(\'soundappletdebug\'); e.style.display=(e.style.display==\'none\')?\'block\':\'none\';" style="max-width:400px; min-height:50px; border-style:solid; border-color:black; background-color:white; color:black; border-width:1px; margin:2px; padding:2px; font-family:sans-serif; font-size:x-small;">WebSDR HTML5 sound - Copyright 2007-2020, P.T. de Boer, pa3fwm@websdr.org<br><span id="soundappletdebug" style="display:none"></span></div><span id="debug2"></span>';
var y = new Int16Array(F),
g = 0,
p = 6144,
q = 0,
remoteSampleRate = 8e3,
v = 8e3,
R = -1,
actualRemoteSampleRate = 8e3,
audioSampleRate = 48e3,
actualAudioSampleRate = 48e3,
x = 1,
volume = 1,
ja = -1,
S,
A = 0,
B = [],
ka,
X,
Y = 0,
soundApplet = this,
webSocket = h,
ya = [
-5504,
-5248,
-6016,
-5760,
-4480,
-4224,
-4992,
-4736,
-7552,
-7296,
-8064,
-7808,
-6528,
-6272,
-7040,
-6784,
-2752,
-2624,
-3008,
-2880,
-2240,
-2112,
-2496,
-2368,
-3776,
-3648,
-4032,
-3904,
-3264,
-3136,
-3520,
-3392,
-22016,
-20992,
-24064,
-23040,
-17920,
-16896,
-19968,
-18944,
-30208,
-29184,
-32256,
-31232,
-26112,
-25088,
-28160,
-27136,
-11008,
-10496,
-12032,
-11520,
-8960,
-8448,
-9984,
-9472,
-15104,
-14592,
-16128,
-15616,
-13056,
-12544,
-14080,
-13568,
-344,
-328,
-376,
-360,
-280,
-264,
-312,
-296,
-472,
-456,
-504,
-488,
-408,
-392,
-440,
-424,
-88,
-72,
-120,
-104,
-24,
-8,
-56,
-40,
-216,
-200,
-248,
-232,
-152,
-136,
-184,
-168,
-1376,
-1312,
-1504,
-1440,
-1120,
-1056,
-1248,
-1184,
-1888,
-1824,
-2016,
-1952,
-1632,
-1568,
-1760,
-1696,
-688,
-656,
-752,
-720,
-560,
-528,
-624,
-592,
-944,
-912,
-1008,
-976,
-816,
-784,
-880,
-848,
5504,
5248,
6016,
5760,
4480,
4224,
4992,
4736,
7552,
7296,
8064,
7808,
6528,
6272,
7040,
6784,
2752,
2624,
3008,
2880,
2240,
2112,
2496,
2368,
3776,
3648,
4032,
3904,
3264,
3136,
3520,
3392,
22016,
20992,
24064,
23040,
17920,
16896,
19968,
18944,
30208,
29184,
32256,
31232,
26112,
25088,
28160,
27136,
11008,
10496,
12032,
11520,
8960,
8448,
9984,
9472,
15104,
14592,
16128,
15616,
13056,
12544,
14080,
13568,
344,
328,
376,
360,
280,
264,
312,
296,
472,
456,
504,
488,
408,
392,
440,
424,
88,
72,
120,
104,
24,
8,
56,
40,
216,
200,
248,
232,
152,
136,
184,
168,
1376,
1312,
1504,
1440,
1120,
1056,
1248,
1184,
1888,
1824,
2016,
1952,
1632,
1568,
1760,
1696,
688,
656,
752,
720,
560,
528,
624,
592,
944,
912,
1008,
976,
816,
784,
880,
848,
],
playbackBuffer = [
4.846206e-4,
3.218322e-4,
3.870879e-4,
4.263937e-4,
4.294803e-4,
3.876866e-4,
2.978334e-4,
1.628906e-4,
-6.746e-6,
-1.976636e-4,
-3.887846e-4,
-5.583476e-4,
-6.843798e-4,
-7.475333e-4,
-7.360876e-4,
-6.458231e-4,
-4.834126e-4,
-2.654101e-4,
-1.72358e-5,
2.297496e-4,
4.414505e-4,
5.867386e-4,
6.40364e-4,
5.889058e-4,
4.320051e-4,
1.84623e-4,
-1.245772e-4,
-4.557272e-4,
-7.630407e-4,
-0.0010001924,
-0.0011278035,
-0.0011186013,
-9.630688e-4,
-6.715766e-4,
-2.747173e-4,
1.796051e-4,
6.316952e-4,
0.0010178421,
0.0012788905,
0.0013693135,
0.0012644532,
9.656565e-4,
5.020083e-4,
-7.20758e-5,
-6.82586e-4,
-0.0012452921,
-0.001676923,
-0.0019071107,
-0.0018892901,
-0.0016090151,
-0.0010880322,
-3.838639e-4,
4.162385e-4,
0.0012055137,
0.0018717189,
0.0023126901,
0.0024515221,
0.0022491337,
0.001712324,
8.956676e-4,
-1.030426e-4,
-0.0011539845,
-0.0021116455,
-0.0028343942,
-0.0032049046,
-0.0031482203,
-0.0026451434,
-0.0017384393,
-5.307213e-4,
8.263157e-4,
0.0021501888,
0.0032516099,
0.0039606691,
0.0041522226,
0.0037662639,
0.0028206105,
0.0014132717,
-2.862273e-4,
-0.0020562471,
-0.0036508477,
-0.0048329708,
-0.0054082689,
-0.0052553028,
-0.0043473176,
-0.0027622291,
-6.785974e-4,
0.0016427351,
0.0038897014,
0.0057392293,
0.0069017337,
0.0071638948,
0.0064237642,
0.0047128748,
0.0022013269,
-8.158008e-4,
-0.0039503266,
-0.0067678548,
-0.0088444407,
-0.0098259631,
-0.0094824393,
-0.0077495259,
-0.004750882,
-7.96851e-4,
0.003641892,
0.0079842451,
0.0116072743,
0.0139260255,
0.0144751543,
0.0129821211,
0.0094221367,
0.0040467651,
-0.002619195,
-0.0098143027,
-0.0166082859,
-0.0219950434,
-0.0250012628,
-0.0247990241,
-0.0208094743,
-0.0127853572,
-8.61941e-4,
0.0144307224,
0.0321972603,
0.0512463819,
0.0701941201,
0.08759059,
0.1020573346,
0.1124206916,
0.1178269679,
0.1178269679,
0.1124206916,
0.1020573346,
0.08759059,
0.0701941201,
0.0512463819,
0.0321972603,
0.0144307224,
-8.61941e-4,
-0.0127853572,
-0.0208094743,
-0.0247990241,
-0.0250012628,
-0.0219950434,
-0.0166082859,
-0.0098143027,
-0.002619195,
0.0040467651,
0.0094221367,
0.0129821211,
0.0144751543,
0.0139260255,
0.0116072743,
0.0079842451,
0.003641892,
-7.96851e-4,
-0.004750882,
-0.0077495259,
-0.0094824393,
-0.0098259631,
-0.0088444407,
-0.0067678548,
-0.0039503266,
-8.158008e-4,
0.0022013269,
0.0047128748,
0.0064237642,
0.0071638948,
0.0069017337,
0.0057392293,
0.0038897014,
0.0016427351,
-6.785974e-4,
-0.0027622291,
-0.0043473176,
-0.0052553028,
-0.0054082689,
-0.0048329708,
-0.0036508477,
-0.0020562471,
-2.862273e-4,
0.0014132717,
0.0028206105,
0.0037662639,
0.0041522226,
0.0039606691,
0.0032516099,
0.0021501888,
8.263157e-4,
-5.307213e-4,
-0.0017384393,
-0.0026451434,
-0.0031482203,
-0.0032049046,
-0.0028343942,
-0.0021116455,
-0.0011539845,
-1.030426e-4,
8.956676e-4,
0.001712324,
0.0022491337,
0.0024515221,
0.0023126901,
0.0018717189,
0.0012055137,
4.162385e-4,
-3.838639e-4,
-0.0010880322,
-0.0016090151,
-0.0018892901,
-0.0019071107,
-0.001676923,
-0.0012452921,
-6.82586e-4,
-7.20758e-5,
5.020083e-4,
9.656565e-4,
0.0012644532,
0.0013693135,
0.0012788905,
0.0010178421,
6.316952e-4,
1.796051e-4,
-2.747173e-4,
-6.715766e-4,
-9.630688e-4,
-0.0011186013,
-0.0011278035,
-0.0010001924,
-7.630407e-4,
-4.557272e-4,
-1.245772e-4,
1.84623e-4,
4.320051e-4,
5.889058e-4,
6.40364e-4,
5.867386e-4,
4.414505e-4,
2.297496e-4,
-1.72358e-5,
-2.654101e-4,
-4.834126e-4,
-6.458231e-4,
-7.360876e-4,
-7.475333e-4,
-6.843798e-4,
-5.583476e-4,
-3.887846e-4,
-1.976636e-4,
-6.746e-6,
1.628906e-4,
2.978334e-4,
3.876866e-4,
4.294803e-4,
4.263937e-4,
3.870879e-4,
3.218322e-4,
4.846206e-4,
],
T = [
-1.47942e-4,
-4.63086e-4,
-5.43866e-4,
-8.37905e-4,
-0.001014311,
-0.00116118,
-0.001180796,
-0.001076634,
-8.36391e-4,
-4.92451e-4,
-9.4469e-5,
2.87595e-4,
5.82401e-4,
7.30717e-4,
7.01055e-4,
4.9903e-4,
1.69525e-4,
-2.11135e-4,
-5.51117e-4,
-7.64022e-4,
-7.90178e-4,
-6.13389e-4,
-2.67748e-4,
1.67964e-4,
5.87153e-4,
8.80407e-4,
9.63624e-4,
8.01554e-4,
4.19872e-4,
-9.7144e-5,
-6.23995e-4,
-0.001024122,
-0.001184736,
-0.001047445,
-6.27522e-4,
-1.5309e-5,
6.42685e-4,
0.001177774,
0.001441643,
0.001347024,
8.94359e-4,
1.77665e-4,
-6.33187e-4,
-0.001332504,
-0.001730079,
-0.001701687,
-0.001226744,
-4.00227e-4,
5.84703e-4,
0.001480338,
0.002046494,
0.002113569,
0.001631749,
6.92239e-4,
-4.88223e-4,
-0.001615646,
-0.002391073,
-0.002589193,
-0.002121436,
-0.001068587,
3.30072e-4,
0.001729551,
0.002762744,
0.003135904,
0.002709835,
0.001546543,
-9.4626e-5,
-0.001812887,
-0.003161817,
-0.00376451,
-0.003416048,
-0.002148579,
-2.37525e-4,
0.001855519,
0.003592039,
0.004493442,
0.004269849,
0.002908814,
6.95458e-4,
-0.001842797,
-0.004059329,
-0.005350342,
-0.005315623,
-0.003877314,
-0.001320828,
0.001755334,
0.004576368,
0.006381587,
0.006625592,
0.005135045,
0.002180561,
-0.001563598,
-0.005167068,
-0.00766869,
-0.008325453,
-0.006823363,
-0.003391342,
0.001216581,
0.005877394,
0.00936274,
0.010650623,
0.009208796,
0.005175064,
-6.20228e-4,
-0.006807588,
-0.011783774,
-0.014104442,
-0.012872482,
-0.008024648,
-4.34977e-4,
0.008206407,
0.015731357,
0.019986001,
0.019373693,
0.013324602,
0.002574305,
-0.010829893,
-0.023820926,
-0.032862179,
-0.034655123,
-0.026862623,
-0.008693659,
0.018783377,
0.052680302,
0.088692158,
0.121798708,
0.147134469,
0.160859545,
0.160859545,
0.147134469,
0.121798708,
0.088692158,
0.052680302,
0.018783377,
-0.008693659,
-0.026862623,
-0.034655123,
-0.032862179,
-0.023820926,
-0.010829893,
0.002574305,
0.013324602,
0.019373693,
0.019986001,
0.015731357,
0.008206407,
-4.34977e-4,
-0.008024648,
-0.012872482,
-0.014104442,
-0.011783774,
-0.006807588,
-6.20228e-4,
0.005175064,
0.009208796,
0.010650623,
0.00936274,
0.005877394,
0.001216581,
-0.003391342,
-0.006823363,
-0.008325453,
-0.00766869,
-0.005167068,
-0.001563598,
0.002180561,
0.005135045,
0.006625592,
0.006381587,
0.004576368,
0.001755334,
-0.001320828,
-0.003877314,
-0.005315623,
-0.005350342,
-0.004059329,
-0.001842797,
6.95458e-4,
0.002908814,
0.004269849,
0.004493442,
0.003592039,
0.001855519,
-2.37525e-4,
-0.002148579,
-0.003416048,
-0.00376451,
-0.003161817,
-0.001812887,
-9.4626e-5,
0.001546543,
0.002709835,
0.003135904,
0.002762744,
0.001729551,
3.30072e-4,
-0.001068587,
-0.002121436,
-0.002589193,
-0.002391073,
-0.001615646,
-4.88223e-4,
6.92239e-4,
0.001631749,
0.002113569,
0.002046494,
0.001480338,
5.84703e-4,
-4.00227e-4,
-0.001226744,
-0.001701687,
-0.001730079,
-0.001332504,
-6.33187e-4,
1.77665e-4,
8.94359e-4,
0.001347024,
0.001441643,
0.001177774,
6.42685e-4,
-1.5309e-5,
-6.27522e-4,
-0.001047445,
-0.001184736,
-0.001024122,
-6.23995e-4,
-9.7144e-5,
4.19872e-4,
8.01554e-4,
9.63624e-4,
8.80407e-4,
5.87153e-4,
1.67964e-4,
-2.67748e-4,
-6.13389e-4,
-7.90178e-4,
-7.64022e-4,
-5.51117e-4,
-2.11135e-4,
1.69525e-4,
4.9903e-4,
7.01055e-4,
7.30717e-4,
5.82401e-4,
2.87595e-4,
-9.4469e-5,
-4.92451e-4,
-8.36391e-4,
-0.001076634,
-0.001180796,
-0.00116118,
-0.001014311,
-8.37905e-4,
-5.43866e-4,
-4.63086e-4,
-1.47942e-4,
],
da = [
-1.559505e-4,
-7.98112e-5,
-9.80814e-5,
-1.173125e-4,
-1.369746e-4,
-1.565189e-4,
-1.753732e-4,
-1.929362e-4,
-2.083552e-4,
-2.206804e-4,
-2.291911e-4,
-2.333843e-4,
-2.318305e-4,
-2.244133e-4,
-2.102e-4,
-1.887765e-4,
-1.597355e-4,
-1.22856e-4,
-7.82038e-5,
-2.59739e-5,
3.34012e-5,
9.91605e-5,
1.702513e-4,
2.45599e-4,
3.235647e-4,
4.025475e-4,
4.805722e-4,
5.555847e-4,
6.253709e-4,
6.875873e-4,
7.399121e-4,
7.800625e-4,
8.058147e-4,
8.15116e-4,
8.062358e-4,
7.776257e-4,
7.282308e-4,
6.573325e-4,
5.647707e-4,
4.50904e-4,
3.166371e-4,
1.635138e-4,
-6.3141e-6,
-1.901069e-4,
-3.845389e-4,
-5.857031e-4,
-7.892655e-4,
-9.904092e-4,
-0.001184062,
-0.0013648737,
-0.0015274109,
-0.0016662822,
-0.0017762342,
-0.0018523274,
-0.0018900859,
-0.0018856324,
-0.0018358173,
-0.0017383931,
-0.0015920662,
-0.0013966904,
-0.0011532549,
-8.640083e-4,
-5.324827e-4,
-1.6347e-4,
2.369773e-4,
6.616157e-4,
0.0011021011,
0.0015491213,
0.0019925324,
0.0024215833,
0.0028250632,
0.0031916142,
0.0035099281,
0.0037690342,
0.0039585921,
0.0040691533,
0.0040924552,
0.0040216824,
0.0038517234,
0.0035793947,
0.003203659,
0.0027257456,
0.0021493323,
0.0014805737,
7.281494e-4,
-9.67559e-5,
-9.805496e-4,
-0.0019073471,
-0.002859177,
-0.0038162186,
-0.0047570964,
-0.0056592108,
-0.0064991489,
-0.0072530544,
-0.0078971131,
-0.0084079899,
-0.0087633047,
-0.0089421178,
-0.008925372,
-0.0086963572,
-0.0082411169,
-0.0075488253,
-0.0066121147,
-0.0054273698,
-0.0039949083,
-0.0023191615,
-4.087211e-4,
0.0017236549,
0.0040611162,
0.0065829025,
0.0092645575,
0.0120782551,
0.0149931771,
0.0179759604,
0.0209911855,
0.0240019478,
0.0269704134,
0.0298584578,
0.0326282789,
0.035243024,
0.0376674322,
0.0398684103,
0.0418156203,
0.0434819958,
0.0448442166,
0.0458831097,
0.046584001,
0.0469369495,
0.0469369495,
0.046584001,
0.0458831097,
0.0448442166,
0.0434819958,
0.0418156203,
0.0398684103,
0.0376674322,
0.035243024,
0.0326282789,
0.0298584578,
0.0269704134,
0.0240019478,
0.0209911855,
0.0179759604,
0.0149931771,
0.0120782551,
0.0092645575,
0.0065829025,
0.0040611162,
0.0017236549,
-4.087211e-4,
-0.0023191615,
-0.0039949083,
-0.0054273698,
-0.0066121147,
-0.0075488253,
-0.0082411169,
-0.0086963572,
-0.008925372,
-0.0089421178,
-0.0087633047,
-0.0084079899,
-0.0078971131,
-0.0072530544,
-0.0064991489,
-0.0056592108,
-0.0047570964,
-0.0038162186,
-0.002859177,
-0.0019073471,
-9.805496e-4,
-9.67559e-5,
7.281494e-4,
0.0014805737,
0.0021493323,
0.0027257456,
0.003203659,
0.0035793947,
0.0038517234,
0.0040216824,
0.0040924552,
0.0040691533,
0.0039585921,
0.0037690342,
0.0035099281,
0.0031916142,
0.0028250632,
0.0024215833,
0.0019925324,
0.0015491213,
0.0011021011,
6.616157e-4,
2.369773e-4,
-1.6347e-4,
-5.324827e-4,
-8.640083e-4,
-0.0011532549,
-0.0013966904,
-0.0015920662,
-0.0017383931,
-0.0018358173,
-0.0018856324,
-0.0018900859,
-0.0018523274,
-0.0017762342,
-0.0016662822,
-0.0015274109,
-0.0013648737,
-0.001184062,
-9.904092e-4,
-7.892655e-4,
-5.857031e-4,
-3.845389e-4,
-1.901069e-4,
-6.3141e-6,
1.635138e-4,
3.166371e-4,
4.50904e-4,
5.647707e-4,
6.573325e-4,
7.282308e-4,
7.776257e-4,
8.062358e-4,
8.15116e-4,
8.058147e-4,
7.800625e-4,
7.399121e-4,
6.875873e-4,
6.253709e-4,
5.555847e-4,
4.805722e-4,
4.025475e-4,
3.235647e-4,
2.45599e-4,
1.702513e-4,
9.91605e-5,
3.34012e-5,
-2.59739e-5,
-7.82038e-5,
-1.22856e-4,
-1.597355e-4,
-1.887765e-4,
-2.102e-4,
-2.244133e-4,
-2.318305e-4,
-2.333843e-4,
-2.291911e-4,
-2.206804e-4,
-2.083552e-4,
-1.929362e-4,
-1.753732e-4,
-1.565189e-4,
-1.369746e-4,
-1.173125e-4,
-9.80814e-5,
-7.98112e-5,
-1.559505e-4,
],
Z = [
7.0433e-5,
-1.0611e-5,
-8.6755e-5,
-1.81287e-4,
-2.40082e-4,
-2.16126e-4,
-1.04338e-4,
4.4967e-5,
1.48777e-4,
1.41957e-4,
2.4902e-5,
-1.26821e-4,
-2.06025e-4,
-1.44934e-4,
3.0288e-5,
2.06761e-4,
2.55662e-4,
1.2428e-4,
-1.1508e-4,
-3.01598e-4,
-2.92187e-4,
-6.8791e-5,
2.32511e-4,
4.01522e-4,
2.98948e-4,
-3.3133e-5,
-3.8003e-4,
-4.90923e-4,
-2.57989e-4,
1.88334e-4,
5.47393e-4,
5.48608e-4,
1.52152e-4,
-3.96707e-4,
-7.15685e-4,
-5.49251e-4,
3.1938e-5,
6.48678e-4,
8.57479e-4,
4.66461e-4,
-3.00057e-4,
-9.23468e-4,
-9.38715e-4,
-2.77012e-4,
6.4652e-4,
0.001188228,
9.213e-4,
-3.4936e-5,
-0.001051564,
-0.001399457,
-7.68199e-4,
4.72146e-4,
0.001478988,
0.00150551,
4.48904e-4,
-0.001020195,
-0.001876749,
-0.001451986,
5.3805e-5,
0.001643867,
0.002179009,
0.001188116,
-7.3768e-4,
-0.002285796,
-0.002311045,
-6.74762e-4,
0.001575511,
0.002867565,
0.002196431,
-1.07222e-4,
-0.002511465,
-0.003293514,
-0.001765763,
0.001149421,
0.003460246,
0.003457538,
9.66687e-4,
-0.002409513,
-0.004308854,
-0.003251791,
2.2654e-4,
0.003807624,
0.004921598,
0.002577091,
-0.001804315,
-0.005225193,
-0.005147223,
-0.001353262,
0.003715307,
0.006506739,
0.004827221,
-4.72053e-4,
-0.005863008,
-0.007463412,
-0.003802999,
0.002917889,
0.008104906,
0.007875542,
0.001918029,
-0.005970371,
-0.010253403,
-0.007489417,
9.91323e-4,
0.009592392,
0.012074666,
0.005996842,
-0.005130313,
-0.013749242,
-0.013274935,
-0.002967159,
0.010844556,
0.018471983,
0.013448699,
-0.002354894,
-0.018901844,
-0.024024383,
-0.011880584,
0.011749681,
0.03149634,
0.031517411,
0.006673294,
-0.031328123,
-0.057596682,
-0.046701295,
0.012224635,
0.106626251,
0.203735462,
0.265089227,
0.265089227,
0.203735462,
0.106626251,
0.012224635,
-0.046701295,
-0.057596682,
-0.031328123,
0.006673294,
0.031517411,
0.03149634,
0.011749681,
-0.011880584,
-0.024024383,
-0.018901844,
-0.002354894,
0.013448699,
0.018471983,
0.010844556,
-0.002967159,
-0.013274935,
-0.013749242,
-0.005130313,
0.005996842,
0.012074666,
0.009592392,
9.91323e-4,
-0.007489417,
-0.010253403,
-0.005970371,
0.001918029,
0.007875542,
0.008104906,
0.002917889,
-0.003802999,
-0.007463412,
-0.005863008,
-4.72053e-4,
0.004827221,
0.006506739,
0.003715307,
-0.001353262,
-0.005147223,
-0.005225193,
-0.001804315,
0.002577091,
0.004921598,
0.003807624,
2.2654e-4,
-0.003251791,
-0.004308854,
-0.002409513,
9.66687e-4,
0.003457538,
0.003460246,
0.001149421,
-0.001765763,
-0.003293514,
-0.002511465,
-1.07222e-4,
0.002196431,
0.002867565,
0.001575511,
-6.74762e-4,
-0.002311045,
-0.002285796,
-7.3768e-4,
0.001188116,
0.002179009,
0.001643867,
5.3805e-5,
-0.001451986,
-0.001876749,
-0.001020195,
4.48904e-4,
0.00150551,
0.001478988,
4.72146e-4,
-7.68199e-4,
-0.001399457,
-0.001051564,
-3.4936e-5,
9.213e-4,
0.001188228,
6.4652e-4,
-2.77012e-4,
-9.38715e-4,
-9.23468e-4,
-3.00057e-4,
4.66461e-4,
8.57479e-4,
6.48678e-4,
3.1938e-5,
-5.49251e-4,
-7.15685e-4,
-3.96707e-4,
1.52152e-4,
5.48608e-4,
5.47393e-4,
1.88334e-4,
-2.57989e-4,
-4.90923e-4,
-3.8003e-4,
-3.3133e-5,
2.98948e-4,
4.01522e-4,
2.32511e-4,
-6.8791e-5,
-2.92187e-4,
-3.01598e-4,
-1.1508e-4,
1.2428e-4,
2.55662e-4,
2.06761e-4,
3.0288e-5,
-1.44934e-4,
-2.06025e-4,
-1.26821e-4,
2.4902e-5,
1.41957e-4,
1.48777e-4,
4.4967e-5,
-1.04338e-4,
-2.16126e-4,
-2.40082e-4,
-1.81287e-4,
-8.6755e-5,
-1.0611e-5,
7.0433e-5,
],
J = [
0.0065862,
-0.0022838,
-0.0059202,
-0.0112239,
-0.0169697,
-0.0214685,
-0.022742,
-0.0189184,
-0.0086407,
0.0084932,
0.0316914,
0.0588926,
0.0870663,
0.1126093,
0.1320398,
0.1425063,
0.1425063,
0.1320398,
0.1126093,
0.0870663,
0.0588926,
0.0316914,
0.0084932,
-0.0086407,
-0.0189184,
-0.022742,
-0.0214685,
-0.0169697,
-0.0112239,
-0.0059202,
-0.0022838,
0.0065862,
],
la = [
-0.0086492,
-0.0044524,
-0.0043664,
-0.0030946,
-3.094e-4,
0.0042348,
0.010627,
0.018809,
0.028525,
0.039333,
0.050605,
0.061655,
0.071697,
0.079997,
0.085925,
0.089013,
0.089013,
0.085925,
0.079997,
0.071697,
0.061655,
0.050605,
0.039333,
0.028525,
0.018809,
0.010627,
0.0042348,
-3.094e-4,
-0.0030946,
-0.0043664,
-0.0044524,
-0.0086492,
],
ea = [
0.0080236,
0.001488,
-0.0074204,
-0.0175495,
-0.0195816,
-0.0075536,
0.0136434,
0.0283156,
0.020311,
-0.0121801,
-0.0489419,
-0.0561146,
-0.0078976,
0.0922184,
0.2069483,
0.2833355,
0.2833355,
0.2069483,
0.0922184,
-0.0078976,
-0.0561146,
-0.0489419,
-0.0121801,
0.020311,
0.0283156,
0.0136434,
-0.0075536,
-0.0195816,
-0.0175495,
-0.0074204,
0.001488,
0.0080236,
],
ta = 1e3,
N = 0.125,
muted = !1,
processStartTime = 0,
M = 0,
V = 0,
sa = 0,
P = 1,
lastProcessTime = 0,
ha = 0,
currentAudioContext,
scriptProcessor,
currentConvolver,
$,
K = [],
ma = 1;
if ((currentAudioContext = document.audioContext)) {
currentAudioContext.sampleRate = audioSampleRate;
var actualAudioSampleRate = (audioSampleRate = currentAudioContext.sampleRate),
na;
na = 4096;
try {
scriptProcessor = currentAudioContext.createScriptProcessor(na, 0, 1);
} catch (Aa) {
scriptProcessor = currentAudioContext.createJavaScriptNode(na, 1, 1);
}
scriptProcessor.onaudioprocess = processEvent;
this.currentScriptProcessor = scriptProcessor;
currentConvolver = currentAudioContext.createConvolver();
scriptProcessor.connect(currentConvolver);
currentConvolver.connect(currentAudioContext.destination);
var channelDataChunk;
if (window.sup_android)
(playbackBuffer = currentAudioContext.createBuffer(1, 32, audioSampleRate)),
(channelDataChunk = playbackBuffer.getChannelData(0)),
channelDataChunk.set(J),
(K[0] = playbackBuffer),
(playbackBuffer = currentAudioContext.createBuffer(1, 32, audioSampleRate)),
(channelDataChunk = playbackBuffer.getChannelData(0)),
channelDataChunk.set(J),
(K[1] = playbackBuffer),
(playbackBuffer = currentAudioContext.createBuffer(1, 32, audioSampleRate)),
(channelDataChunk = playbackBuffer.getChannelData(0)),
channelDataChunk.set(la),
(K[2] = playbackBuffer),
(playbackBuffer = currentAudioContext.createBuffer(1, 32, audioSampleRate)),
(channelDataChunk = playbackBuffer.getChannelData(0)),
channelDataChunk.set(ea),
(K[3] = playbackBuffer);
else {
J = Math.round(audioSampleRate / 48e3);
1 > J && (J = 1);
la = 512 * J;
da = [T, playbackBuffer, da, Z];
for (T = 0; T < da.length; T++) {
for (var ea = da[T], D = [], playbackBuffer = 0; playbackBuffer < ea.length; playbackBuffer++)
for (Z = 0; Z < J; Z++) D[playbackBuffer * J + Z] = ea[playbackBuffer];
playbackBuffer = currentAudioContext.createBuffer(1, la, audioSampleRate);
channelDataChunk = playbackBuffer.getChannelData(0);
channelDataChunk.set(D);
K[T] = playbackBuffer;
}
}
currentConvolver.normalize = !1;
currentConvolver.buffer = K[0];
} else window.browsersupporterror && window.browsersupporterror();
var fa,
ua,
z,
oa,
D = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
E = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
aa = 0,
webSocket = new WebSocket("ws://" + window.location.host + "/~~stream");
webSocket.binaryType = "arraybuffer";
var H = 0.0625,
L = 0,
va = 0,
ba = 0,
O = 1,
W = 2,
wsMessageReceiveTime,
qa = 0;
webSocket.onmessage = function (c) {
P && P++;
wsMessageReceiveTime = new Date().getTime();
qa = g;
var a = (2 * F + g - p - ((wsMessageReceiveTime - processStartTime) * v) / 1e3) % F,
b = a;
a > F / 2 && (a = 0);
b > F / 2 && (b -= F);
b /= v;
H += 0.01 * (a / v - H);
1e9 > L && (H = N);
var d = H - N;
if (!(0 <= R))
if (O && 0.05 > Math.abs(d) / N) (O = 0), (x = actualRemoteSampleRate / actualAudioSampleRate / (v / audioSampleRate));
else {
if (d < 0.25 * -N || d > 0.5 * N) O = 1;
0.01 < Math.abs(d) && 20 > W && (O = 1);
a = O ? 1 + 0.1 * d : 1 + 0.01 * d;
a *= actualRemoteSampleRate / actualAudioSampleRate / (v / audioSampleRate);
x = O ? a : x + 0.003 * (a - x);
}
1.005 < x && (x = 1.005);
0.995 > x && (x = 0.995);
var soundAppletDebugHtml =
Math.round(1e3 * b) +
" " +
Math.round(1e3 * N) +
" " +
Math.round(1e3 * H) +
" " +
Math.round(1e6 * (x - 1)) +
" " +
O +
"<br>";
soundAppletDebugHtml += Math.round(audioSampleRate) + " " + Math.round(remoteSampleRate) + " " + fa;
soundAppletDebugHtml += currentAudioContext ? " WebAudio " : " none ";
soundAppletDebugHtml += actualAudioSampleRate.toFixed(2) + " " + actualRemoteSampleRate.toFixed(2);
document.getElementById("soundappletdebug").innerHTML = soundAppletDebugHtml;
b = new Uint8Array(c.data);
c = g;
lastlen = b.length;
for (a = 0; a < b.length; a++) {
var f = 0,
l = 0;
if (240 == (b[a] & 240))
(smeter = 256 * (b[a] & 15) + b[a + 1]),
soundApplet.smetercallback && soundApplet.smetercallback(10 * smeter),
a++;
else if (128 == b[a]) {
var e;
for (e = Y = 0; 128 > e; e++) y[g + e] = ya[b[a + 1 + e]];
g += 128;
g >= F && (g -= F);
var a = a + 128,
j;
for (j = 0; 20 > j; j++) D[j] = E[j] = 0;
aa = 0;
} else if (144 <= b[a] && 223 >= b[a])
(l = 4), (f = 2), (z = 14 - (b[a] >> 4));
else if (128 != (b[a] & 128)) (l = 1), (f = 2);
else if (129 == b[a])
(j = 256 * b[a + 1] + b[a + 2]),
j != remoteSampleRate && ((remoteSampleRate = j), (R = g)),
webSocket && webSocket.postMessage({ type: "samplerate", samplerate: remoteSampleRate }, "*"),
0 < remoteSampleRate ? (ja = 1) : ((ja = 0), stopall()),
(a += 2);
else if (130 == b[a]) (ua = 256 * b[a + 1] + b[a + 2]), (a += 2);
else if (131 == b[a])
(oa = b[a + 1]),
(j = b[a + 1] & 15),
j != fa && ((fa = j), currentConvolver && (currentConvolver.buffer = K[fa])),
a++;
else if (132 == b[a]) {
Y += 128;
for (e = 0; 128 > e; e++) y[g + e] = 0;
g += 128;
g >= F && (g -= F);
for (j = 0; 20 > j; j++) D[j] = E[j] = 0;
aa = 0;
} else
133 == b[a] &&
((d =
16777216 *
(((b[a + 1] & 15) << 16) + (b[a + 2] << 8) + b[a + 3]) +
(b[a + 4] << 16) +
(b[a + 5] << 8) +
b[a + 6]),
(e = b[a + 1] >> 4),
soundApplet.truefreqcallback && soundApplet.truefreqcallback(d, e),
(a += 6));
if (2 == f) {
f = Y = 0;
for (j = 16 == (oa & 16) ? 12 : 14; 128 > f; ) {
d =
(b[a + 3] & 255) |
((b[a + 2] & 255) << 8) |
((b[a + 1] & 255) << 16) |
((b[a + 0] & 255) << 24);
d <<= l;
e = 0;
var n;
n = 15 - z;
var s = ua,
u = [999, 999, 8, 4, 2, 1, 99, 99];
if (0 != d) for (; 0 == (d & 2147483648) && e < n; ) (d <<= 1), e++;
e < n
? ((n = e), e++, (d <<= 1))
: ((n = (d >> 24) & 255), (e += 8), (d <<= 8));
var q = 0;
n >= u[z] && q++;
n >= u[z - 1] && q++;
q > z - 1 && (q = z - 1);
u = (((d >> 16) & 65535) >> (17 - z)) & (-1 << q);
u += n << (z - 1);
0 != (d & (1 << (32 - z + q))) && ((u |= (1 << q) - 1), (u = ~u));
for (l += e + z - q; 8 <= l; ) a++, (l -= 8);
for (e = d = 0; 20 > e; e++) d += D[e] * E[e];
d |= 0;
d = 0 <= d ? d >> 12 : (d + 4095) >> 12;
s = u * s + s / 2;
u = s >> 4;
for (e = 19; 0 <= e; e--) {
D[e] += -(D[e] >> 7) + ((E[e] * u) >> j);
if (0 == e) break;
E[e] = E[e - 1];
}
E[0] = d + s;
d = E[0] + (aa >> 4);
aa = 16 == (oa & 16) ? 0 : aa + ((E[0] << 4) >> 3);
y[g++] = d;
g >= F && (g -= F);
f++;
}
0 == l && a--;
}
}
e = g - c;
0 > e && (e += F);
ba += e;
L += (1e3 * e) / remoteSampleRate;
wsMessageReceiveTime < L && (L = wsMessageReceiveTime);
ba >= remoteSampleRate &&
((j = 1e3 * (ba / (L - va))),
j < 1.01 * remoteSampleRate && j > 0.99 * remoteSampleRate && (actualRemoteSampleRate += (j - actualRemoteSampleRate) / W),
(ba = 0),
100 > W && W++,
(va = L),
(L = wsMessageReceiveTime));
webSocket &&
((b = c),
c > g && (webSocket.postMessage(y.subarray(c), "*"), (b = 0)),
g > b && webSocket.postMessage(y.subarray(b, g), "*"));
if (S && !(Y > 2 * remoteSampleRate))
for (; c != g; ) {
for (X += ka / remoteSampleRate; 1 <= X; )
S.setInt16(A, y[c], !0),
(A += 2),
65536 <= A &&
((b = new ArrayBuffer(65536)),
(A = 0),
(S = new DataView(b)),
B.push(b)),
X--;
c++;
c >= F && (c -= F);
}
if (ma) {
if ((c = document.getElementById("audiostartbutton")))
c.style.display = "suspended" === currentAudioContext.state ? "block" : "none";
"running" === currentAudioContext.state && (ma = 0);
}
};
webSocket.onopen = function () {
soundappletstarted();
};
webSocket.onclose = function () {
for (var c = 0; c < F; c++) y[c] = 0;
webSocket.onclose = h;
webSocket = webSocket.onmessage = h;
};
this.setparam = function (c) {
try {
webSocket.send("GET /~~param?" + c);
} catch (a) {}
};
this.smeter = function () {
return 10 * smeter;
};
this.getid = function () {
return ja;
};
this.mute = function (newValue) {
muted = newValue;
!S && !webSocket && this.setparam("mute=" + newValue);
};
this.setvolume = function (newVolume) {
volume = newVolume;
};
this.setdelay1 = function (c) {
ta = c;
H = N = c / 8e3;
p = (F + g - ta) % F;
};
stopall = function () {
currentAudioContext
? (webSocket.close(),
(scriptProcessor.onaudioprocess = h),
scriptProcessor.disconnect(),
(channelDataChunk = K = this.p = currentAudioContext = $ = currentConvolver = scriptProcessor = scriptProcessor.destination = h))
: webSocket.close();
};
this.restartaudio = function () {
stopall();
document.audioContext = new AudioContext();
window.prep_html5sound();
};
this.destroy = function () {
stopall();
window.soundapplet = h;
};
this.rec_start = function () {
A = 0;
ka = remoteSampleRate;
X = 0;
var c = new ArrayBuffer(65536);
S = new DataView(c);
B = [c];
muted && this.setparam("mute=0");
};
this.rec_finish = function () {
B[B.length - 1] = B[B.length - 1].slice(0, A);
S = h;
var c = {};
c.wavdata = B;
c.len = 65536 * (B.length - 1) + A;
c.sr = ka;
!webSocket && muted && this.setparam("mute=1");
return c;
};
this.rec_length_kB = function () {
return (65536 * (B.length - 1) + A) / 1024;
};
this.setbcaudio = function (c) {
webSocket = c;
muted &&
(c && this.setparam("mute=0"),
!c && !recaudio && this.setparam("mute=1"));
c && webSocket.postMessage({ type: "samplerate", samplerate: remoteSampleRate }, "*");
};
this.setstereo = function (c) {
0 > c
? (currentConvolver.disconnect(), currentConvolver.connect(currentAudioContext.destination))
: ($ || (($ = currentAudioContext.createChannelMerger()), $.connect(currentAudioContext.destination)),
currentConvolver.disconnect(),
currentConvolver.connect($, 0, c));
};
this.audioresume = function () {
currentAudioContext.resume();
var audioStartButton = document.getElementById("audiostartbutton");
audioStartButton && (audioStartButton.style.display = "none");
ma = 0;
};
}
window.prep_html5sound = function () {
window.soundapplet = new za();
};
prep_html5sound();
})();
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import netscape.javascript.JSObject;
public class websdrsound extends Applet implements LineListener, Runnable, MouseListener {
private SourceDataLine I;
private Socket I1;
private InputStream II;
OutputStream Il;
static final long serialVersionUID = 1L;
int I11 = -2;
int II1 = -2;
int Il1 = -1;
int I1I = 0;
int III = 0;
final float IlI = 200.0F;
int I1l = 0;
String IIl = "";
int Ill = -1;
Thread I111;
boolean II11 = true;
boolean Il11 = false;
public int smeter = -32767;
public int l = 0;
public int I1I1 = this.l;
double III1 = 1.0D;
float IlI1 = 1.0F;
double I1l1 = 0.0D;
double IIl1 = 0.0D;
final int Ill1 = 23;
final int I11I = 128;
final int II1I = 48;
float Il1I = 1.0F;
final float[] lll1l1l = new float[3];
float lll1ll1;
long I1II = 0L;
long llll11l = 0L;
float llll111 = 0.0F;
final float[] lll1lll = new float[4];
final short[] lll11ll = new short[] {
-5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296,
-8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880,
-2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136,
-3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
-30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496,
-12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616,
-13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264,
-312, -296, -472, -456, -504, -488, -408, -392, -440, -424,
-88, -72, -120, -104, -24, -8, -56, -40, -216, -200,
-248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440,
-1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568,
-1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592,
-944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248,
6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808,
6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112,
2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184,
32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520,
8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544,
14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296,
472, 456, 504, 488, 408, 392, 440, 424, 88, 72,
120, 104, 24, 8, 56, 40, 216, 200, 248, 232,
152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056,
1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
688, 656, 752, 720, 560, 528, 624, 592, 944, 912,
1008, 976, 816, 784, 880, 848 };
boolean IIII = false;
int IlII = 5;
float I1lI = 0.0F;
int IIlI = 0;
float IllI = 0.0F;
float[] lll1111 = new float[272];
float[] lll111l = new float[1552];
byte[] lll11l1 = new byte[3120];
int I11l = 1;
float[] lll1l11 = new float[20];
int II1l = 1;
int Il1l = 0;
static Class I1Il;
public static void main(String[] paramArrayOfString) {
System.out.println("Copyright 2007-2016, Pieter-Tjerk de Boer, PA3FWM, pa3fwm@websdr.org - All rights reserved.");
System.out.println("Since the intended use of this (or any) applet involves sending a copy to the client computer, I (PA3FWM) hereby allow making it available unmodified, as part of the original .jar file, via my original WebSDR server software, to original WebSDR clients.");
System.out.println("Other use, including distribution in part or entirety in other forms or as part of other software, or reverse engineering is not allowed without my explicit prior permission.");
}
public void stop() {
this.I111 = null;
this.IIl = "stop()";
I();
}
public void destroy() {
stop();
}
public void paint(Graphics paramGraphics) {
paramGraphics.drawString("WebSDR sound applet", 10, 10);
paramGraphics.drawString("Copyright 2007-2016, P.T. de Boer, pa3fwm@websdr.org", 10, 24);
paramGraphics.drawString("Java version: " + System.getProperty("java.version"), 10, 88);
if (this.II11)
return;
paramGraphics.drawString(this.I11 + " " + this.IIl + " " + this.Ill + this.l, 10, 40);
paramGraphics.drawString(this.III + " " + this.I1I, 10, 52);
paramGraphics.drawString(this.I1l + " " + 200.0F, 10, 64);
paramGraphics.drawString((int)(0.5D + (this.IlI1 * 8000.0F)) + " " + (int)(0.5D + (this.III1 - 1.0D) * 1000000.0D) + " " + (int)(0.5D + (1.0D - this.IIl1 / 6.0D / this.I1l1 * this.IlI1) * 1000000.0D), 10, 76);
}
void I() {
if (this.II11)
return;
repaint();
}
public void mouseEntered(MouseEvent paramMouseEvent) {}
public void mouseExited(MouseEvent paramMouseEvent) {}
public void mouseReleased(MouseEvent paramMouseEvent) {}
public void mousePressed(MouseEvent paramMouseEvent) {}
public void I(MouseEvent paramMouseEvent) {}
public void mouseClicked(MouseEvent paramMouseEvent) {
this.II11 = !this.II11;
repaint();
}
public int getid() {
return this.Ill;
}
public int I1() {
return this.smeter;
}
public String javaversion() {
return System.getProperty("java.version");
}
public void setparam(String paramString) {
paramString = "GET /~~param?ppm=" + (int)(0.5D + (this.III1 - 1.0D) * 1000000.0D) + "&ppml=" + (int)(0.5D + (1.0D - this.IIl1 / 6.0D / this.I1l1 * this.IlI1) * 1000000.0D) + "&" + paramString + "\r\n\r\n";
try {
this.Il.write(paramString.getBytes(), 0, paramString.length());
} catch (Exception exception) {}
this.IIl1 = this.I1l1 = 0.0D;
}
public void setvolume(float paramFloat) {
this.Il1I = paramFloat;
}
public void start() {
AudioFormat audioFormat = new AudioFormat(48000.0F, 16, 1, true, false);
DataLine.Info info = new DataLine.Info((I1Il == null) ? (I1Il = I("javax.sound.sampled.SourceDataLine")) : I1Il, audioFormat, 96000);
try {
this.I = (SourceDataLine)AudioSystem.getLine(info);
this.I.open(audioFormat, 96000);
} catch (LineUnavailableException lineUnavailableException) {}
this.I.addLineListener(this);
this.I.start();
try {
int i = getCodeBase().getPort();
if (i < 0)
i = 80;
this.I1 = new Socket(getCodeBase().getHost(), i);
this.II = this.I1.getInputStream();
this.Il = this.I1.getOutputStream();
this.Il.write("GET /~~stream?java=1&23\r\n\r\n".getBytes(), 0, 27);
this.I11 = 1;
I();
} catch (Exception exception) {
this.I11 = -3;
I();
}
this.I11 = 4;
this.IIl = "start()";
this.I111 = new Thread(this);
this.I111.start();
JSObject.getWindow(this).eval("soundappletstarted()");
addMouseListener(this);
I();
this.I1II = System.currentTimeMillis();
}
void I(int paramInt) {
if (this.Ill == -1) {
this.Ill = paramInt;
} else if ((paramInt & 0x8000) == 0) {
this.smeter = paramInt;
} else {
paramInt &= 0x7FFF;
if ((paramInt & 0x4000) == 0)
this.IlI1 = paramInt / 8000.0F;
}
}
void I1(int paramInt) {
this.I1l1 += paramInt;
this.Il1 = this.I.getBufferSize() - this.I.available();
if (!this.I.isActive()) {
this.I1I++;
this.Il1 = -1;
}
this.I11++;
this.lll1l1l[0] = this.lll1l1l[1];
this.lll1l1l[1] = this.lll1l1l[2];
this.lll1l1l[2] = this.I.getFramePosition() / 48.0F - (float)(System.currentTimeMillis() - this.I1II);
if (this.lll1l1l[1] > this.lll1l1l[0] && this.lll1l1l[1] > this.lll1l1l[2])
this.lll1ll1 = 0.1F * this.lll1l1l[1] + 0.9F * this.lll1ll1;
for (byte b2 = 0; b2 < paramInt; b2++) {
for (byte b = 0; b < 6; b++) {
byte b3;
float[] arrayOfFloat2 = {
-0.0030657F, -0.0027421F, -0.0028342F, -0.0018084F, 5.5067E-4F, 0.0040855F, 0.0081821F, 0.011793F, 0.01366F, 0.01262F,
0.0080115F, 1.7366E-5F, -0.010139F, -0.020236F, -0.027388F, -0.028593F, -0.02145F, -0.0048089F, 0.020752F, 0.052804F,
0.087352F, 0.11948F, 0.14428F, 0.15778F, 0.15778F, 0.14428F, 0.11948F, 0.087352F, 0.052804F, 0.020752F,
-0.0048089F, -0.02145F, -0.028593F, -0.027388F, -0.020236F, -0.010139F, 1.7366E-5F, 0.0080115F, 0.01262F, 0.01366F,
0.011793F, 0.0081821F, 0.0040855F, 5.5067E-4F, -0.0018084F, -0.0028342F, -0.0027421F, -0.0030657F };
float[] arrayOfFloat1 = {
-0.0024615F, -0.0072497F, -0.0080908F, -0.0078587F, -0.0024454F, 0.0045784F, 0.010045F, 0.009404F, 0.0018009F, -0.0092801F,
-0.016675F, -0.013973F, -1.8887E-4F, 0.017873F, 0.028294F, 0.020954F, -0.0048033F, -0.036754F, -0.053709F, -0.035879F,
0.023444F, 0.11149F, 0.19934F, 0.25408F, 0.25408F, 0.19934F, 0.11149F, 0.023444F, -0.035879F, -0.053709F,
-0.036754F, -0.0048033F, 0.020954F, 0.028294F, 0.017873F, -1.8887E-4F, -0.013973F, -0.016675F, -0.0092801F, 0.0018009F,
0.009404F, 0.010045F, 0.0045784F, -0.0024454F, -0.0078587F, -0.0080908F, -0.0072497F, -0.0024615F };
this.lll111l[16 + 6 * b2 + b] = 0.0F;
if (this.Il11) {
for (b3 = 0; b3 < 8; b3++)
this.lll111l[16 + 6 * b2 + b] = this.lll111l[16 + 6 * b2 + b] + this.lll1111[b2 + 7 + b3] * arrayOfFloat1[6 * b3 + 5 - b];
} else {
for (byte b4 = 0; b4 < 8; b4++)
this.lll111l[16 + 6 * b2 + b] = this.lll111l[16 + 6 * b2 + b] + this.lll1111[b2 + 7 + b4] * b3[6 * b4 + 5 - b];
}
this.lll111l[16 + 6 * b2 + b] = this.lll111l[16 + 6 * b2 + b] * 6.0F;
}
}
int i = paramInt * 6;
byte b1;
for (b1 = 0; this.I1lI < i; b1++) {
int j = (int)this.I1lI + 16;
float f1 = this.I1lI - (j - 16);
f1 = (1.0F - f1) * this.lll111l[j - 1] + f1 * this.lll111l[j];
if (2 * b1 > 3100)
break;
this.lll11l1[2 * b1] = (byte)((int)f1 & 0xFF);
this.lll11l1[2 * b1 + 1] = (byte)((int)f1 >> 8);
this.I1lI = (float)(this.I1lI + this.III1 * this.IlI1);
}
this.I1lI -= i;
if (this.IIlI == 0) {
this.I.write(this.lll11l1, 0, b1 * 2);
this.IIl1 += b1;
} else if (b1 < this.IIlI) {
this.IIlI -= b1;
} else {
this.I.write(this.lll11l1, this.IIlI * 2, (b1 - this.IIlI) * 2);
this.IIlI = 0;
this.IIl1 += (b1 - this.IIlI);
}
if (this.llll11l == 0L)
this.llll111 = (float)this.llll11l;
this.llll11l += b1;
this.lll1lll[0] = this.lll1lll[1];
this.lll1lll[1] = this.lll1lll[2];
this.lll1lll[2] = this.lll1lll[3];
this.lll1lll[3] = (float)this.llll11l / 48.0F - (float)(System.currentTimeMillis() - this.I1II);
if (this.IIlI == 0 && this.lll1lll[3] < this.lll1ll1 && this.llll111 > this.lll1ll1 + 150.0F) {
this.IIlI = (int)(this.lll1ll1 - this.lll1lll[3]);
this.III++;
this.llll111 -= this.IIlI;
this.lll1lll[0] = this.lll1lll[0] - this.IIlI;
this.lll1lll[1] = this.lll1lll[1] - this.IIlI;
this.lll1lll[2] = this.lll1lll[2] - this.IIlI;
this.lll1lll[3] = this.lll1lll[3] - this.IIlI;
this.lll1ll1 -= this.IIlI;
this.IIlI *= 48;
this.llll11l -= this.IIlI;
}
if (this.lll1lll[1] > this.lll1lll[0] && this.lll1lll[1] > this.lll1lll[2] && this.lll1lll[1] > this.lll1lll[3])
this.llll111 = this.lll1lll[1];
for (paramInt = 0; paramInt < 16; paramInt++) {
this.lll111l[paramInt] = this.lll111l[i + paramInt];
this.lll1111[paramInt] = this.lll1111[i / 6 + paramInt];
}
float f = this.llll111 - this.lll1ll1;
this.I1l = (int)f;
f -= 200.0F;
f /= 3.0F;
this.IllI = 0.999F * this.IllI + 0.001F * f;
if (this.IllI < -40.0F)
this.IllI = -40.0F;
if (this.IllI > 40.0F)
this.IllI = 40.0F;
this.III1 = (1.0F + this.IllI * 5.0E-5F);
if (f > 200.0F) {
this.IIlI = (int)f;
this.III++;
this.llll111 -= this.IIlI;
this.lll1lll[0] = this.lll1lll[0] - this.IIlI;
this.lll1lll[1] = this.lll1lll[1] - this.IIlI;
this.lll1lll[2] = this.lll1lll[2] - this.IIlI;
this.lll1lll[3] = this.lll1lll[3] - this.IIlI;
this.IIlI *= 48;
this.llll11l -= this.IIlI;
}
}
void I(float paramFloat, int paramInt) {
for (byte b = 19; b > 0; b--)
this.lll1l11[b] = this.lll1l11[b - 1];
this.lll1l11[0] = paramFloat;
float f = this.lll1l11[10];
if (this.II1l >= 0) {
f = 0.0F;
float[][] arrayOfFloat = { { 0.0416798F, -0.0010372F, -0.0316519F, 0.0592284F, -0.0496101F, -0.0066906F, 0.0774353F, -0.0963F, -0.0179755F, 0.5594503F }, { 0.030725F, 0.062421F, -0.028814F, -0.027426F, -0.056624F, -0.034655F, 0.021408F, 0.110595F, 0.199341F, 0.255473F } };
for (byte b1 = 0; b1 < 10; b1++)
f += arrayOfFloat[this.II1l][b1] * (this.lll1l11[b1] + this.lll1l11[19 - b1]);
}
this.lll1111[paramInt + 16] = f * this.Il1I;
if (paramInt == 127)
I1(128);
}
public void run() {
byte[] arrayOfByte = new byte[264];
int[] arrayOfInt3 = new int[20];
int[] arrayOfInt2 = new int[20];
int[] arrayOfInt1 = new int[20];
int m = 0;
byte b1 = 0;
byte b = -1;
char c = Character.MIN_VALUE;
int k = 0;
int j = 256;
int i = 0;
this.Ill = -1;
try {
while (Thread.currentThread() == this.I111) {
this.I11++;
I();
this.I1I1 = this.l;
int i1 = 0;
int n = 0;
while (c < ') {
i1 = this.II.read(arrayOfByte, m, 260 - m);
if (i1 < 0)
break;
m += i1;
boolean bool = true;
while (bool && m > 0) {
int i2 = 0;
if (b == -1) {
if (m < 2) {
bool = false;
} else {
b = 0;
int i3 = (arrayOfByte[0] & 0xFF) + ((arrayOfByte[1] & 0xFF) << 8);
I(i3);
i2 = 2;
}
} else if (b == 0) {
if ((arrayOfByte[0] & 0x80) != 128) {
n = 1;
b = 2;
c = Character.MIN_VALUE;
} else if (arrayOfByte[0] >= -112 && arrayOfByte[0] <= -33) {
n = 4;
b = 2;
c = Character.MIN_VALUE;
i = 6 - (0xF & arrayOfByte[0] - 128 >> 4);
} else if (arrayOfByte[0] == Byte.MIN_VALUE) {
b = 1;
i2 = 1;
} else if ((arrayOfByte[0] & 0xF0) == 240) {
if (m < 2) {
bool = false;
} else {
this.smeter = 10 * (((arrayOfByte[0] & 0xF) << 8) + (arrayOfByte[1] & 0xFF));
i2 = 2;
}
} else if (arrayOfByte[0] == -127) {
if (m < 3) {
bool = false;
} else {
int i3 = (arrayOfByte[1] << 8) + (arrayOfByte[2] & 0xFF);
this.IlI1 = i3 / 8000.0F;
i2 = 3;
}
} else if (arrayOfByte[0] == -126) {
if (m < 3) {
bool = false;
} else {
int i3 = (arrayOfByte[1] << 8) + (arrayOfByte[2] & 0xFF);
j = i3;
i2 = 3;
}
} else if (arrayOfByte[0] == -125) {
if (m < 2) {
bool = false;
} else {
this.Il1l = arrayOfByte[1];
this.II1l = (arrayOfByte[1] & 0xF) - 1;
if (this.II1l == 2) {
this.II1l = 0;
this.Il11 = true;
} else {
this.Il11 = false;
}
i2 = 2;
}
} else if (arrayOfByte[0] == -124) {
i2 = 1;
c = ';
for (byte b2 = 0; b2 < '; b2++)
this.lll1111[b2 + 16] = 0.0F;
I1(128);
for (i1 = 0; i1 < 20; i1++) {
arrayOfInt2[i1] = 0;
arrayOfInt3[i1] = 0;
}
k = 0;
} else if (arrayOfByte[0] == -123) {
if (m < 7) {
bool = false;
} else {
i2 = 7;
}
} else {
i2 = 1;
this.IIII = true;
bool = false;
}
} else if (b == 1) {
if (m < 128 || c == ') {
bool = false;
} else {
for (byte b2 = 0; b2 < 20; b2++) {
arrayOfInt2[b2] = 0;
arrayOfInt3[b2] = 0;
}
k = 0;
i1 = 0;
while (i1 < m && c < ') {
this.lll1111[c + 16] = this.lll11ll[(short)arrayOfByte[i1] & 0xFF];
I(this.lll11ll[(short)arrayOfByte[i1] & 0xFF], c);
i1++;
c++;
}
i2 = 128;
b = 0;
bool = false;
}
}
if (b == 2) {
i1 = 0;
byte b2 = ((this.Il1l & 0x10) == 16) ? 12 : 14;
while (i1 < m && c < ') {
int i4 = (arrayOfByte[i1 + 3] & 0xFF) + ((arrayOfByte[i1 + 2] & 0xFF) << 8) + ((arrayOfByte[i1 + 1] & 0xFF) << 16) + ((arrayOfByte[i1 + 0] & 0xFF) << 24);
int i5 = i4 << n;
int i10 = n;
int i9 = i5;
byte b3 = 0;
int i6 = 15 - i;
int i8 = j;
int[] arrayOfInt = { 999, 999, 8, 4, 2, 1, 99, 99 };
if (i5 != 0)
while ((i5 & Integer.MIN_VALUE) == 0 && b3 < i6) {
i5 <<= 1;
b3++;
}
if (b3 < i6) {
i7 = b3;
b3++;
i6 = i5 << 1;
} else {
i7 = i5 >> 24 & 0xFF;
b3 += 8;
i6 = i5 << 8;
}
i5 = 0;
if (i7 >= arrayOfInt[i])
i5++;
if (i7 >= arrayOfInt[i - 1])
i5++;
if (i5 > i - 1)
i5 = i - 1;
int i3 = (i6 >> 16 & 0xFFFF) >> 17 - i & -1 << i5;
i3 += i7 << i - 1;
if ((i6 & 1 << 32 - i + i5) != 0) {
i3 |= (1 << i5) - 1;
i3 ^= 0xFFFFFFFF;
}
for (n += b3 + i - i5; n >= 8; n -= 8)
i1++;
if (i9 == 0 || i1 + (7 + n) / 8 > m) {
bool = false;
n = i10;
break;
}
i2 = i1;
i6 = 0;
for (i5 = 0; i5 < 20; i5++)
i6 += arrayOfInt3[i5] * arrayOfInt2[i5];
i5 = i6 / 4096;
int i7 = i3 * i8 + i8 / 2;
i6 = i7 >> 4;
for (i3 = 0; i3 < 20; i3++)
arrayOfInt3[i3] = arrayOfInt3[i3] + -(arrayOfInt3[i3] >> 7) + (arrayOfInt2[i3] * i6 >> b2);
for (i3 = 19; i3 > 0; i3--) {
arrayOfInt2[i3] = arrayOfInt2[i3 - 1];
arrayOfInt1[i3] = arrayOfInt1[i3 - 1];
}
arrayOfInt2[0] = i5 + i7;
i3 = i5 + i7 * this.I1I1 + (k >> 4);
if ((this.Il1l & 0x10) == 16) {
k = 0;
} else {
k += arrayOfInt2[0] << 4 >> 3;
}
I(i3, c);
c++;
}
if (c == ') {
b = 0;
if (n > 0) {
i2++;
n = 0;
}
}
b1++;
}
if (i2 > 0)
for (i1 = i2; i1 < m; i1++)
arrayOfByte[i1 - i2] = arrayOfByte[i1];
m -= i2;
}
if (this.IIII || m < 0)
break;
}
if (c == ')
c = Character.MIN_VALUE;
this.II1 = i1;
this.I11++;
if (this.IIII || i1 == -1)
break;
}
} catch (IOException iOException) {
this.IIl = "!" + iOException.getMessage();
}
this.IIl = "^" + this.IIl;
this.I.flush();
this.I.stop();
this.I.close();
try {
this.I1.close();
} catch (Exception exception) {}
this.I11 = -5;
I();
}
public void update(LineEvent paramLineEvent) {}
static Class I(String paramString) {
try {
return Class.forName(paramString);
} catch (ClassNotFoundException classNotFoundException) {
throw (new NoClassDefFoundError()).initCause(classNotFoundException);
}
}
}
@endiny
Copy link

endiny commented Aug 23, 2022

I suspect there might be a raw radio signal on the websocket that needs to be demodulated

@kevinelliott
Copy link
Author

I suspect there might be a raw radio signal on the websocket that needs to be demodulated

Any interest in fixing this to work?

@natsuru-san
Copy link

natsuru-san commented Sep 10, 2022

Any interest in fixing this to work?
I do not know if I can help you, but I can give you some direction of thought :)
The audio from websocket encoded to G911-format (aLaw). Audiacity plays it well. You need a decoder of this format. I have one in my project, but it is written in java...

@endiny
Copy link

endiny commented Sep 13, 2022

Any interest in fixing this to work?
Actually, I believe this helped me to get an applet with no syntax errors. That helped me to make it run at least and change frequencies

@natsuru-san gonna check this out. There is also a golang lib for that

@mrzachhigginsofficial
Copy link

I suspect there might be a raw radio signal on the websocket that needs to be demodulated

Tackling this in python and I think this is where I'm stuck. I think the keys to the kingdom are locked away here processEvent(audioProcessEvent). Gonna start picking it apart tomorrow or friday.

@einball
Copy link

einball commented Jun 11, 2023

@natsuru-san I'm not able to get anything usable out of Audacity using RAW audio import, aLaw, little-Endian, FS 8kHz. I made sure to modify the frequency into one I should be able to listen to. Am I missing something? Can you confirm the above code works on your machine ™️?

@natsuru-san
Copy link

@einball Seems that audio stream codec been changed or modified by the server owner which (I suppose) knew about our research his facility. I think too because my app's playing with a some issues at last time. Your problem (as is my) might be into it. And I have no idea how to solve it. May be you have any idea?

@realies
Copy link

realies commented Aug 10, 2023

@natsuru-san, do you know the diff on the frontend so we can narrow down the change?

@realies
Copy link

realies commented Aug 10, 2023

I've been trying to capture the WebSocket stream on websdr.info:8902, which uses an older version of the websdr frontend using this node script:

const WebSocket = require('ws');
const fs = require('fs');

// GET /~~param?f=145625&band=0&lo=-6.2&hi=6.2&mode=4&name=
const frequency = "145625";
const band = "0";
const lo = "-6.2";
const hi = "6.2";
const mode = "4";
const ws = new WebSocket('ws://websdr.info:8902/~~stream?v=11', { headers: {
  'Connection': 'Upgrade',
  'Host': 'websdr.info:8902',
  'Origin': 'http://websdr.info:8902',
  'Cookie': 'view=2; ID=5d83b2fd9c13',
  'Pragma': 'no-cache',
  'Cache-Control': 'no-cache',
  'Sec-WebSocket-Key': 'K+3pZ6WnO+JMDVF5CX4J+w==',
  'Sec-WebSocket-Version': '13',
  'Sec-WebSocket-Extensions': 'x-webkit-deflate-frame',
  'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15'
}, binaryType: 'arraybuffer' });

const dataBuffer = [];

ws.on('open', function open() {
  console.log('Connection opened...');
  ws.send(`GET /~~param?f=${frequency}&band=${band}&lo=${lo}&hi=${hi}&mode=${mode}&name=`, () => {
    ws.send(`GET /~~param?mute=0`, () => {
      ws.send(`GET /~~param?squelch=0`, () => {
        ws.send(`GET /~~param?autonotch=0`, () => {
          ws.on('message', function incoming(data) {
            console.log(`Received ${data.length} bytes`);
            dataBuffer.push(data);
          });
          setTimeout(() => {
            ws.close();
            console.log('Connection closed.');
          }, 1000 * 60);
        });
      });
    });
  });
});

ws.on('error', function error(err) {
  console.error('Error:', err);
});

ws.on('close', function close() {
  console.log('Connection closed by server.');
  fs.writeFile('capturedAudio.raw', Buffer.concat(dataBuffer), (err) => {
    if (err) throw err;
    console.log('Data saved to file.');
  });
});

Unfortunately, reading the file in Audacity, or converting it with sox (sox -t raw -r 8000 -e a-law input.raw output.wav) produces only white noise-like output. A strange thing I noticed is that while I 'record' for 60 seconds, the resulting file is around ~42 seconds long.

Any ideas or suggestions on how to capture and decode this? Here's a captured file: https://github.com/realies/websdr-capture/raw/master/capturedAudio.raw

PS: websdr.info:8902 works fine when intialised with this, much older websdr-sound.js: https://github.com/FarnhamSDR/websdr-webpages/blob/master/websdr-sound.js

@mrzachhigginsofficial
Copy link

@realies - you need to demodulate the stream. You can check try to reverse engineer the JS or I can provide an example in python if you're interested.

@realies
Copy link

realies commented Aug 11, 2023

@mrzachhigginsofficial, an example would be greatly appreciated.

@einball
Copy link

einball commented Aug 11, 2023

I have reason to believe that there was a kind of packet structure / framing introduced. The first byte in every package is the almost everytime the same. I did not get it to run but did not sink a lot of time into it by now. This leads me to believe that the author started to do asynchronous resampling or injecting data into the stream. In any case, it seems like there's a 'length' field now.

Screenshot from 2023-08-11 09-57-33

Screenshot from 2023-08-11 09-57-21

Screenshot from 2023-08-11 09-57-06

The code is so convoluted it's very hard to read it. It might be better to reimplement the functionality using the webaudio API and/or run our own server.

@mrzachhigginsofficial Did you run this through a codec, deinterleave the obtained samples and IQ demodulate it after?

When I tune to a stationary signal (keyed beacon for example) the data rate drops from 750bytes/message to 420bytes/message so I assume the/a codec is still in play.

@mrzachhigginsofficial
Copy link

I checked the project from my phone. Honestly I don't understand it anymore (or at least enough to read from this screen on github) and need to step through it to find the relevant portions. Will do this tomorrow. It's been a while since I touched it.

@einball
Copy link

einball commented Aug 11, 2023

@mrzachhigginsofficial Your project will probably no longer work. The current implementation of this SDR does some more things than simply decode some fixed-rate samples from the server. This version does asynchronous samplerate conversion to adapt its playback rate to what's sent from the server. After staring at the code for a while I think I'm starting to get the hang of it.

@realies
Copy link

realies commented Aug 11, 2023

@einball, I had a feeling that something like this is happening based on some byte flags: https://github.com/FarnhamSDR/websdr-webpages/blob/951cbfc5433b845bdcf600c42ae2739e32123e9a/websdr-sound.js#L223-L299 Although I'm still lost in the data flow.

@einball
Copy link

einball commented Aug 11, 2023

I already decoded parts of the file and have a basic understanding of what's going on. However, I'd like to respect the authors copyright and will not post my results publicly.

@realies
Copy link

realies commented Aug 11, 2023

@einball, can you share if you decoded parts of the file I posted (capturedAudio.raw)?

@kevinelliott
Copy link
Author

@einball I'd love to see what you've done. Any chance you could contact me privately about it?

@realies
Copy link

realies commented Aug 11, 2023

@einball I'd love to see what you've done. Any chance you could contact me privately about it?

+1

@idramm25
Copy link

idramm25 commented Jan 17, 2024

I made a python script to connect to the server and record the stream to a file. then try to listen to it with the second script. in the speakers there is something similar to white noise with sound artifacts in the form of snatches of speech.
making raw: https://pastebin.com/SPhn5bS8
play raw: https://pastebin.com/m2qxAeFh
wav to raw from web: https://pastebin.com/M0xfJfvs
my goal is something like that:
121212

@kevinelliott
Copy link
Author

Interesting. I would be willing to bet there is some encoding happening to prevent this very thing that we need to figure out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment