From 78568bdbaf3512facf5fc65966344288a22dea71 Mon Sep 17 00:00:00 2001 From: Lewis Moten Date: Sat, 11 May 2024 17:44:26 -0400 Subject: [PATCH] replace sent/received bit panels --- Panels/BasePanel.js | 42 +++++++++++++++++++----------------------- Panels/CodePanel.js | 11 +++++++++++ StreamManager.js | 4 ++++ index.html | 13 ------------- index.js | 40 +++++++++++++++++++++++++++------------- 5 files changed, 61 insertions(+), 49 deletions(-) create mode 100644 Panels/CodePanel.js diff --git a/Panels/BasePanel.js b/Panels/BasePanel.js index 9f36abe..02eca3f 100644 --- a/Panels/BasePanel.js +++ b/Panels/BasePanel.js @@ -35,10 +35,9 @@ class BasePanel { input.name = name; input.checked = checked; input.value = value; - input.id = id; + input.id = this.childId(id); input.addEventListener('change', e => { this.dispatcher.emit(eventName, { - panel: this.id, name, id, index, @@ -58,7 +57,7 @@ class BasePanel { const input = document.createElement('input'); input.type = 'text'; input.value = value; - input.id = id; + input.id = this.childId(id); input.addEventListener('input', e => { this.dispatcher.emit(eventName, { panel: this.id, @@ -70,7 +69,7 @@ class BasePanel { } addButton = (id, text, eventName = 'click') => { const button = document.createElement('button'); - button.id = id; + button.id = this.childId(id); button.innerText = text; button.addEventListener('click', e => { this.dispatcher.emit(eventName, { @@ -85,27 +84,32 @@ class BasePanel { const progressBar = document.createElement('div'); progressBar.className = 'progress-container'; const bar = document.createElement('div'); - bar.id = id; + bar.id = this.childId(id); bar.className = 'progress-bar'; bar.style.width = `${clamp(percent, 0, 1) * 100}%`; progressBar.append(bar); this.append(progressBar); } setProgressById = (id, percent) => { - const element = document.getElementById(id); + const element = document.getElementById(this.childId(id)); if(!element) throw new Error(`Unable to find ${id}`); 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'); - code.id = id; + code.id = this.childId(id); code.innerText = value; code.className = type === '' ? 'raw-data' : `raw-data-${type}`; this.append(code); } setValueById = (id, value) => { - const element = document.getElementById(id); - if(!element) throw new Error(`Unable to find ${id}`); + const element = this.getElement(id); switch(element.tagName) { case 'INPUT': case 'SELECT': @@ -116,13 +120,11 @@ class BasePanel { } } setHtmlById = (id, html) => { - const element = document.getElementById(id); - if(!element) throw new Error(`Unable to find ${id}`); + const element = this.getElement(id); element.innerHTML = html; } getValueById = (id) => { - const element = document.getElementById(id); - if(!element) throw new Error(`Unable to find ${id}`); + const element = this.getElement(id); switch(element.tagName) { case 'INPUT': case 'SELECT': @@ -131,16 +133,10 @@ class BasePanel { return element.innerText; } } - setCheckedById = (id, checked) => { - const element = document.getElementById(id); - 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; + setCheckedById = (id, checked = true) => { + this.getElement(id).checked = !!checked; } + getCheckedById = (id) => !!(this.getElement(id).checked); append = (element) => this.container.appendChild(element); clear = () => this.container.innerHTML = ''; addEventListener = (eventName, callback) => this.dispatcher.addListener(eventName, callback); diff --git a/Panels/CodePanel.js b/Panels/CodePanel.js new file mode 100644 index 0000000..37f68a3 --- /dev/null +++ b/Panels/CodePanel.js @@ -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; \ No newline at end of file diff --git a/StreamManager.js b/StreamManager.js index 4f9a5aa..5fb599e 100644 --- a/StreamManager.js +++ b/StreamManager.js @@ -60,6 +60,10 @@ export const addBits = ( if(hasNewBits(oldBits, bits)) 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 = []) => { if(oldBits.length === 0 && bits.length === BITS_PER_SEGMENT) return true; diff --git a/index.html b/index.html index 68d8a6f..fd20438 100644 --- a/index.html +++ b/index.html @@ -10,19 +10,6 @@

Data Over Audio

-
-

Encoded segments to send

-
-

-
-
-
-

Encoded Segments Received

-
-

-
-
-

Configuration

diff --git a/index.js b/index.js index 2cb4186..d612041 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,7 @@ import * as AudioReceiver from './AudioReceiver'; import * as CRC from './CRC.js'; import CommunicationsPanel from './Panels/CommunicationsPanel'; import MessagePanel from "./Panels/MessagePanel.js"; +import CodePanel from "./Panels/CodePanel.js"; var audioContext; var microphoneStream; @@ -63,9 +64,13 @@ var PACKET_SIZE_BITS = 5; // 32 bytes, 256 bits const communicationsPanel = new CommunicationsPanel(); const messagePanel = new MessagePanel(); +const bitsSentPanel = new CodePanel('Bits Sent'); +const bitsReceivedPanel = new CodePanel('Bits Received'); function handleWindowLoad() { const panelContainer = document.getElementById('panel-container'); + panelContainer.prepend(bitsReceivedPanel.getDomElement()); + panelContainer.prepend(bitsSentPanel.getDomElement()); panelContainer.prepend(messagePanel.getDomElement()); panelContainer.prepend(communicationsPanel.getDomElement()); @@ -79,6 +84,9 @@ function handleWindowLoad() { messagePanel.setReceived(''); messagePanel.setSendButtonText('Send'); + bitsSentPanel.setCode(''); + bitsReceivedPanel.setCode(''); + // Communications Events communicationsPanel.addEventListener('listeningChange', handleChangeListening); communicationsPanel.addEventListener('sendSpeakersChange', handleChangeSendSpeakers); @@ -233,6 +241,7 @@ function showChannelList() { function handleAudioSenderSend({bits}) { SENT_TRANSFER_BITS.push(...bits); + showSentBits(); } function configurationChanged() { updatePacketUtils(); @@ -489,6 +498,14 @@ function sendBytes(bytes) { } AudioSender.stopAt(startSeconds + totalDurationSeconds); + showSentBits(); + + // start the graph moving again + resumeGraph(); +} +function showSentBits() { + const channelCount = getChannels().length; + // original bits document.getElementById('sent-data').innerHTML = SENT_ORIGINAL_BITS.reduce(bitReducer( @@ -506,16 +523,12 @@ function sendBytes(bytes) { } else { document.getElementById('error-correcting-data').innerHTML = ''; } - - document.getElementById('actual-bits-to-send').innerHTML = - SENT_TRANSFER_BITS.reduce(bitReducer( + bitsSentPanel.setCode( + SENT_TRANSFER_BITS.reduce(bitReducer( PacketUtils.getPacketMaxBitCount() + PacketUtils.getPacketLastSegmentUnusedBitCount(), channelCount, (packetIndex, blockIndex) => `${blockIndex === 0 ? '' : '
'}Segment ${blockIndex}: ` - ), ''); - - // start the graph moving again - resumeGraph(); + ), '')); } function sendPacket(bits, packetStartSeconds) { const channels = getChannels(); @@ -619,11 +632,10 @@ function handleStreamManagerChange() { 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 receivedProgess = document.getElementById('received-progress'); - let percentReceived = allRawBits.length / totalBitsTransferring; - receivedProgess.style.width = `${Math.floor(Math.min(1, percentReceived) * 100)}%`; + let percentReceived = StreamManager.sumTotalBits() / totalBitsTransferring; + messagePanel.setProgress(percentReceived); - document.getElementById('received-encoded-segment-bits').innerHTML = allRawBits + bitsReceivedPanel.setCode(allRawBits .reduce( bitExpectorReducer( SENT_TRANSFER_BITS, @@ -631,7 +643,7 @@ function handleStreamManagerChange() { channelCount, (packetIndex, blockIndex) => `${blockIndex === 0 ? '' : '
'}Segment ${blockIndex}: ` ), - ''); + '')); if(HAMMING_ERROR_CORRECTION) { document.getElementById('received-encoded-bits').innerHTML = allEncodedBits .reduce( @@ -671,7 +683,9 @@ function handleStreamManagerChange() { ).toLocaleString(); // ArrayBuffer / ArrayBufferView 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) { return (number) => number.toString(16).padStart(length, '0').toUpperCase();