replace sent/received bit panels
This commit is contained in:
@@ -35,10 +35,9 @@ class BasePanel {
|
|||||||
input.name = name;
|
input.name = name;
|
||||||
input.checked = checked;
|
input.checked = checked;
|
||||||
input.value = value;
|
input.value = value;
|
||||||
input.id = id;
|
input.id = this.childId(id);
|
||||||
input.addEventListener('change', e => {
|
input.addEventListener('change', e => {
|
||||||
this.dispatcher.emit(eventName, {
|
this.dispatcher.emit(eventName, {
|
||||||
panel: this.id,
|
|
||||||
name,
|
name,
|
||||||
id,
|
id,
|
||||||
index,
|
index,
|
||||||
@@ -58,7 +57,7 @@ class BasePanel {
|
|||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'text';
|
input.type = 'text';
|
||||||
input.value = value;
|
input.value = value;
|
||||||
input.id = id;
|
input.id = this.childId(id);
|
||||||
input.addEventListener('input', e => {
|
input.addEventListener('input', e => {
|
||||||
this.dispatcher.emit(eventName, {
|
this.dispatcher.emit(eventName, {
|
||||||
panel: this.id,
|
panel: this.id,
|
||||||
@@ -70,7 +69,7 @@ class BasePanel {
|
|||||||
}
|
}
|
||||||
addButton = (id, text, eventName = 'click') => {
|
addButton = (id, text, eventName = 'click') => {
|
||||||
const button = document.createElement('button');
|
const button = document.createElement('button');
|
||||||
button.id = id;
|
button.id = this.childId(id);
|
||||||
button.innerText = text;
|
button.innerText = text;
|
||||||
button.addEventListener('click', e => {
|
button.addEventListener('click', e => {
|
||||||
this.dispatcher.emit(eventName, {
|
this.dispatcher.emit(eventName, {
|
||||||
@@ -85,27 +84,32 @@ class BasePanel {
|
|||||||
const progressBar = document.createElement('div');
|
const progressBar = document.createElement('div');
|
||||||
progressBar.className = 'progress-container';
|
progressBar.className = 'progress-container';
|
||||||
const bar = document.createElement('div');
|
const bar = document.createElement('div');
|
||||||
bar.id = id;
|
bar.id = this.childId(id);
|
||||||
bar.className = 'progress-bar';
|
bar.className = 'progress-bar';
|
||||||
bar.style.width = `${clamp(percent, 0, 1) * 100}%`;
|
bar.style.width = `${clamp(percent, 0, 1) * 100}%`;
|
||||||
progressBar.append(bar);
|
progressBar.append(bar);
|
||||||
this.append(progressBar);
|
this.append(progressBar);
|
||||||
}
|
}
|
||||||
setProgressById = (id, percent) => {
|
setProgressById = (id, percent) => {
|
||||||
const element = document.getElementById(id);
|
const element = document.getElementById(this.childId(id));
|
||||||
if(!element) throw new Error(`Unable to find ${id}`);
|
if(!element) throw new Error(`Unable to find ${id}`);
|
||||||
element.style.width = `${clamp(percent, 0, 1) * 100}%`;
|
element.style.width = `${clamp(percent, 0, 1) * 100}%`;
|
||||||
}
|
}
|
||||||
addCode = (id, value, type = '') => {
|
childId = id => `${this.id}-${id}`;
|
||||||
|
getElement = id => {
|
||||||
|
const element = document.getElementById(this.childId(id));
|
||||||
|
if(!element) throw new Error(`Unable to find ${id}`);
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
addCode = (id, value = '', type = '') => {
|
||||||
const code = document.createElement('div');
|
const code = document.createElement('div');
|
||||||
code.id = id;
|
code.id = this.childId(id);
|
||||||
code.innerText = value;
|
code.innerText = value;
|
||||||
code.className = type === '' ? 'raw-data' : `raw-data-${type}`;
|
code.className = type === '' ? 'raw-data' : `raw-data-${type}`;
|
||||||
this.append(code);
|
this.append(code);
|
||||||
}
|
}
|
||||||
setValueById = (id, value) => {
|
setValueById = (id, value) => {
|
||||||
const element = document.getElementById(id);
|
const element = this.getElement(id);
|
||||||
if(!element) throw new Error(`Unable to find ${id}`);
|
|
||||||
switch(element.tagName) {
|
switch(element.tagName) {
|
||||||
case 'INPUT':
|
case 'INPUT':
|
||||||
case 'SELECT':
|
case 'SELECT':
|
||||||
@@ -116,13 +120,11 @@ class BasePanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setHtmlById = (id, html) => {
|
setHtmlById = (id, html) => {
|
||||||
const element = document.getElementById(id);
|
const element = this.getElement(id);
|
||||||
if(!element) throw new Error(`Unable to find ${id}`);
|
|
||||||
element.innerHTML = html;
|
element.innerHTML = html;
|
||||||
}
|
}
|
||||||
getValueById = (id) => {
|
getValueById = (id) => {
|
||||||
const element = document.getElementById(id);
|
const element = this.getElement(id);
|
||||||
if(!element) throw new Error(`Unable to find ${id}`);
|
|
||||||
switch(element.tagName) {
|
switch(element.tagName) {
|
||||||
case 'INPUT':
|
case 'INPUT':
|
||||||
case 'SELECT':
|
case 'SELECT':
|
||||||
@@ -131,16 +133,10 @@ class BasePanel {
|
|||||||
return element.innerText;
|
return element.innerText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCheckedById = (id, checked) => {
|
setCheckedById = (id, checked = true) => {
|
||||||
const element = document.getElementById(id);
|
this.getElement(id).checked = !!checked;
|
||||||
if(!element) throw new Error(`Unable to find ${id}`);
|
|
||||||
element.checked = checked;
|
|
||||||
}
|
|
||||||
getCheckedById = (id) => {
|
|
||||||
const element = document.getElementById(id);
|
|
||||||
if(!element) throw new Error(`Unable to find ${id}`);
|
|
||||||
return element.checked;
|
|
||||||
}
|
}
|
||||||
|
getCheckedById = (id) => !!(this.getElement(id).checked);
|
||||||
append = (element) => this.container.appendChild(element);
|
append = (element) => this.container.appendChild(element);
|
||||||
clear = () => this.container.innerHTML = '';
|
clear = () => this.container.innerHTML = '';
|
||||||
addEventListener = (eventName, callback) => this.dispatcher.addListener(eventName, callback);
|
addEventListener = (eventName, callback) => this.dispatcher.addListener(eventName, callback);
|
||||||
|
|||||||
11
Panels/CodePanel.js
Normal file
11
Panels/CodePanel.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import BasePanel from './BasePanel';
|
||||||
|
|
||||||
|
class CodePanel extends BasePanel {
|
||||||
|
constructor(title) {
|
||||||
|
super(title);
|
||||||
|
this.addCode('code');
|
||||||
|
}
|
||||||
|
setCode = (html) => this.setHtmlById('code', html);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CodePanel;
|
||||||
@@ -60,6 +60,10 @@ export const addBits = (
|
|||||||
if(hasNewBits(oldBits, bits))
|
if(hasNewBits(oldBits, bits))
|
||||||
dispatcher.emit('change');
|
dispatcher.emit('change');
|
||||||
}
|
}
|
||||||
|
const sumSegmentBits = (sum, segment) => sum + segment.length;
|
||||||
|
const sumPacketBits = (sum, packet) => sum + packet.reduce(sumSegmentBits, 0);
|
||||||
|
export const sumTotalBits = () => BITS.reduce(sumPacketBits, 0);
|
||||||
|
|
||||||
const hasNewBits = (oldBits = [], bits = []) => {
|
const hasNewBits = (oldBits = [], bits = []) => {
|
||||||
if(oldBits.length === 0 && bits.length === BITS_PER_SEGMENT)
|
if(oldBits.length === 0 && bits.length === BITS_PER_SEGMENT)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
13
index.html
13
index.html
@@ -10,19 +10,6 @@
|
|||||||
<body>
|
<body>
|
||||||
<h1>Data Over Audio</h1>
|
<h1>Data Over Audio</h1>
|
||||||
<div class="panels" id="panel-container">
|
<div class="panels" id="panel-container">
|
||||||
<div>
|
|
||||||
<h2>Encoded segments to send</h2>
|
|
||||||
<div>
|
|
||||||
<div class="raw-data" id="actual-bits-to-send"></div><br />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h2>Encoded Segments Received</h2>
|
|
||||||
<div>
|
|
||||||
<div class="raw-data" id="received-encoded-segment-bits"></div><br />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2>Configuration</h2>
|
<h2>Configuration</h2>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
40
index.js
40
index.js
@@ -9,6 +9,7 @@ import * as AudioReceiver from './AudioReceiver';
|
|||||||
import * as CRC from './CRC.js';
|
import * as CRC from './CRC.js';
|
||||||
import CommunicationsPanel from './Panels/CommunicationsPanel';
|
import CommunicationsPanel from './Panels/CommunicationsPanel';
|
||||||
import MessagePanel from "./Panels/MessagePanel.js";
|
import MessagePanel from "./Panels/MessagePanel.js";
|
||||||
|
import CodePanel from "./Panels/CodePanel.js";
|
||||||
|
|
||||||
var audioContext;
|
var audioContext;
|
||||||
var microphoneStream;
|
var microphoneStream;
|
||||||
@@ -63,9 +64,13 @@ var PACKET_SIZE_BITS = 5; // 32 bytes, 256 bits
|
|||||||
|
|
||||||
const communicationsPanel = new CommunicationsPanel();
|
const communicationsPanel = new CommunicationsPanel();
|
||||||
const messagePanel = new MessagePanel();
|
const messagePanel = new MessagePanel();
|
||||||
|
const bitsSentPanel = new CodePanel('Bits Sent');
|
||||||
|
const bitsReceivedPanel = new CodePanel('Bits Received');
|
||||||
|
|
||||||
function handleWindowLoad() {
|
function handleWindowLoad() {
|
||||||
const panelContainer = document.getElementById('panel-container');
|
const panelContainer = document.getElementById('panel-container');
|
||||||
|
panelContainer.prepend(bitsReceivedPanel.getDomElement());
|
||||||
|
panelContainer.prepend(bitsSentPanel.getDomElement());
|
||||||
panelContainer.prepend(messagePanel.getDomElement());
|
panelContainer.prepend(messagePanel.getDomElement());
|
||||||
panelContainer.prepend(communicationsPanel.getDomElement());
|
panelContainer.prepend(communicationsPanel.getDomElement());
|
||||||
|
|
||||||
@@ -79,6 +84,9 @@ function handleWindowLoad() {
|
|||||||
messagePanel.setReceived('');
|
messagePanel.setReceived('');
|
||||||
messagePanel.setSendButtonText('Send');
|
messagePanel.setSendButtonText('Send');
|
||||||
|
|
||||||
|
bitsSentPanel.setCode('');
|
||||||
|
bitsReceivedPanel.setCode('');
|
||||||
|
|
||||||
// Communications Events
|
// Communications Events
|
||||||
communicationsPanel.addEventListener('listeningChange', handleChangeListening);
|
communicationsPanel.addEventListener('listeningChange', handleChangeListening);
|
||||||
communicationsPanel.addEventListener('sendSpeakersChange', handleChangeSendSpeakers);
|
communicationsPanel.addEventListener('sendSpeakersChange', handleChangeSendSpeakers);
|
||||||
@@ -233,6 +241,7 @@ function showChannelList() {
|
|||||||
|
|
||||||
function handleAudioSenderSend({bits}) {
|
function handleAudioSenderSend({bits}) {
|
||||||
SENT_TRANSFER_BITS.push(...bits);
|
SENT_TRANSFER_BITS.push(...bits);
|
||||||
|
showSentBits();
|
||||||
}
|
}
|
||||||
function configurationChanged() {
|
function configurationChanged() {
|
||||||
updatePacketUtils();
|
updatePacketUtils();
|
||||||
@@ -489,6 +498,14 @@ function sendBytes(bytes) {
|
|||||||
}
|
}
|
||||||
AudioSender.stopAt(startSeconds + totalDurationSeconds);
|
AudioSender.stopAt(startSeconds + totalDurationSeconds);
|
||||||
|
|
||||||
|
showSentBits();
|
||||||
|
|
||||||
|
// start the graph moving again
|
||||||
|
resumeGraph();
|
||||||
|
}
|
||||||
|
function showSentBits() {
|
||||||
|
const channelCount = getChannels().length;
|
||||||
|
|
||||||
// original bits
|
// original bits
|
||||||
document.getElementById('sent-data').innerHTML =
|
document.getElementById('sent-data').innerHTML =
|
||||||
SENT_ORIGINAL_BITS.reduce(bitReducer(
|
SENT_ORIGINAL_BITS.reduce(bitReducer(
|
||||||
@@ -506,16 +523,12 @@ function sendBytes(bytes) {
|
|||||||
} else {
|
} else {
|
||||||
document.getElementById('error-correcting-data').innerHTML = '';
|
document.getElementById('error-correcting-data').innerHTML = '';
|
||||||
}
|
}
|
||||||
|
bitsSentPanel.setCode(
|
||||||
document.getElementById('actual-bits-to-send').innerHTML =
|
SENT_TRANSFER_BITS.reduce(bitReducer(
|
||||||
SENT_TRANSFER_BITS.reduce(bitReducer(
|
|
||||||
PacketUtils.getPacketMaxBitCount() + PacketUtils.getPacketLastSegmentUnusedBitCount(),
|
PacketUtils.getPacketMaxBitCount() + PacketUtils.getPacketLastSegmentUnusedBitCount(),
|
||||||
channelCount,
|
channelCount,
|
||||||
(packetIndex, blockIndex) => `${blockIndex === 0 ? '' : '<br>'}Segment ${blockIndex}: `
|
(packetIndex, blockIndex) => `${blockIndex === 0 ? '' : '<br>'}Segment ${blockIndex}: `
|
||||||
), '');
|
), ''));
|
||||||
|
|
||||||
// start the graph moving again
|
|
||||||
resumeGraph();
|
|
||||||
}
|
}
|
||||||
function sendPacket(bits, packetStartSeconds) {
|
function sendPacket(bits, packetStartSeconds) {
|
||||||
const channels = getChannels();
|
const channels = getChannels();
|
||||||
@@ -619,11 +632,10 @@ function handleStreamManagerChange() {
|
|||||||
const correctEncodedBits = allEncodedBits.filter((b, i) => i < encodedBitCount && b === SENT_ENCODED_BITS[i]).length;
|
const correctEncodedBits = allEncodedBits.filter((b, i) => i < encodedBitCount && b === SENT_ENCODED_BITS[i]).length;
|
||||||
const correctedDecodedBits = allDecodedBits.filter((b, i) => i < decodedBitCount && b === SENT_ORIGINAL_BITS[i]).length;
|
const correctedDecodedBits = allDecodedBits.filter((b, i) => i < decodedBitCount && b === SENT_ORIGINAL_BITS[i]).length;
|
||||||
|
|
||||||
const receivedProgess = document.getElementById('received-progress');
|
let percentReceived = StreamManager.sumTotalBits() / totalBitsTransferring;
|
||||||
let percentReceived = allRawBits.length / totalBitsTransferring;
|
messagePanel.setProgress(percentReceived);
|
||||||
receivedProgess.style.width = `${Math.floor(Math.min(1, percentReceived) * 100)}%`;
|
|
||||||
|
|
||||||
document.getElementById('received-encoded-segment-bits').innerHTML = allRawBits
|
bitsReceivedPanel.setCode(allRawBits
|
||||||
.reduce(
|
.reduce(
|
||||||
bitExpectorReducer(
|
bitExpectorReducer(
|
||||||
SENT_TRANSFER_BITS,
|
SENT_TRANSFER_BITS,
|
||||||
@@ -631,7 +643,7 @@ function handleStreamManagerChange() {
|
|||||||
channelCount,
|
channelCount,
|
||||||
(packetIndex, blockIndex) => `${blockIndex === 0 ? '' : '<br>'}Segment ${blockIndex}: `
|
(packetIndex, blockIndex) => `${blockIndex === 0 ? '' : '<br>'}Segment ${blockIndex}: `
|
||||||
),
|
),
|
||||||
'');
|
''));
|
||||||
if(HAMMING_ERROR_CORRECTION) {
|
if(HAMMING_ERROR_CORRECTION) {
|
||||||
document.getElementById('received-encoded-bits').innerHTML = allEncodedBits
|
document.getElementById('received-encoded-bits').innerHTML = allEncodedBits
|
||||||
.reduce(
|
.reduce(
|
||||||
@@ -671,7 +683,9 @@ function handleStreamManagerChange() {
|
|||||||
).toLocaleString();
|
).toLocaleString();
|
||||||
// ArrayBuffer / ArrayBufferView
|
// ArrayBuffer / ArrayBufferView
|
||||||
const receivedText = bitsToText(allDecodedBits);
|
const receivedText = bitsToText(allDecodedBits);
|
||||||
document.getElementById('decoded-text').innerHTML = receivedText.split('').reduce(textExpectorReducer(SENT_ORIGINAL_TEXT), '');
|
messagePanel.setReceived(
|
||||||
|
receivedText.split('').reduce(textExpectorReducer(SENT_ORIGINAL_TEXT), '')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
function asHex(length) {
|
function asHex(length) {
|
||||||
return (number) => number.toString(16).padStart(length, '0').toUpperCase();
|
return (number) => number.toString(16).padStart(length, '0').toUpperCase();
|
||||||
|
|||||||
Reference in New Issue
Block a user