request failing packets
This commit is contained in:
@@ -37,6 +37,16 @@ export const changeConfiguration = ({
|
||||
|
||||
export const setAudioContext = ctx => audioContext = ctx;
|
||||
|
||||
export const setDestination = destination => {
|
||||
DESTINATION = destination;
|
||||
const oscillators = getOscillators();
|
||||
oscillators.forEach(
|
||||
oscillator => {
|
||||
oscillator?.disconnect();
|
||||
oscillator?.connect(destination);
|
||||
}
|
||||
)
|
||||
}
|
||||
function getAudioContext() {
|
||||
if(!audioContext) {
|
||||
throw 'Audio context not provided.';
|
||||
@@ -128,10 +138,7 @@ export function stopAt(streamEndSeconds) {
|
||||
oscillator?.stop(streamEndSeconds);
|
||||
}
|
||||
stopTimeout();
|
||||
stopOscillatorsTimeoutId = window.setTimeout(
|
||||
stop,
|
||||
delayMs(streamEndSeconds)
|
||||
);
|
||||
stopOscillatorsTimeoutId = window.setTimeout(stop, delayMs(streamEndSeconds));
|
||||
}
|
||||
export function stop() {
|
||||
const oscillators = getOscillators();
|
||||
|
||||
@@ -231,6 +231,14 @@ class BasePanel {
|
||||
const element = this.getElement(id);
|
||||
element.innerHTML = html;
|
||||
}
|
||||
getHtmlById = (id) => {
|
||||
const element = this.getElement(id);
|
||||
return element.innerHTML;
|
||||
}
|
||||
scrollToBottom = id => {
|
||||
const element = this.getElement(id);
|
||||
element.scrollIntoView(false);
|
||||
}
|
||||
getNumberById = id => {
|
||||
const value = this.getValueById(id);
|
||||
return parseFloat(value);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { htmlEncode } from '../converters';
|
||||
import BasePanel from './BasePanel';
|
||||
|
||||
class CodePanel extends BasePanel {
|
||||
@@ -6,6 +7,18 @@ class CodePanel extends BasePanel {
|
||||
this.addCode('code');
|
||||
}
|
||||
setCode = (html) => this.setHtmlById('code', html);
|
||||
appendCode = html => {
|
||||
let current = this.getHtmlById('code');
|
||||
if(current !== '') current += document.createElement('br').outerHTML;
|
||||
this.setHtmlById('code', current + html);
|
||||
this.scrollToBottom('code');
|
||||
}
|
||||
appendText = text => {
|
||||
let current = this.getHtmlById('code');
|
||||
if(current !== '') current += document.createElement('br').outerHTML;
|
||||
this.setHtmlById('code', current + htmlEncode(text));
|
||||
this.scrollToBottom('code');
|
||||
}
|
||||
}
|
||||
|
||||
export default CodePanel;
|
||||
@@ -109,7 +109,8 @@ class FrequencyGraphPanel extends BasePanel {
|
||||
const canvas = this.getElement('frequency-graph');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const {height, width} = canvas;
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
let now;
|
||||
|
||||
if(this.samples.length > 1) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import BasePanel from './BasePanel';
|
||||
|
||||
class CommunicationsPanel extends BasePanel {
|
||||
class OutputPanel extends BasePanel {
|
||||
constructor() {
|
||||
super('Audio Sender');
|
||||
super('Outut');
|
||||
this.addRadios('send-via', [
|
||||
{text: 'Analyzer', id: 'send-via-analyzer', eventName: 'sendAnalyzerChange'},
|
||||
{text: 'Speakers', id: 'send-via-speaker', eventName: 'sendSpeakersChange'}
|
||||
@@ -12,4 +12,4 @@ class CommunicationsPanel extends BasePanel {
|
||||
setSendAnalyzer = checked => this.setCheckedById('send-via-analyzer', checked);
|
||||
}
|
||||
|
||||
export default CommunicationsPanel;
|
||||
export default OutputPanel;
|
||||
@@ -20,8 +20,8 @@ class PacketErrorPanel extends BasePanel {
|
||||
this.addSection('Packet Retransmission')
|
||||
|
||||
this.addRadios('repeat', [
|
||||
{ text: 'Automatic Repeat Request', value: 'arq', checked: true, eventName: 'hi' },
|
||||
{ text: 'Manual Repeat Request', value: 'manual', checked: true, eventName: 'hi' }
|
||||
{ text: 'Automatic Repeat Request', id:'arq', value: 'arq', checked: true, eventName: 'automaticRepeatRequestChange' },
|
||||
{ text: 'Manual Repeat Request', id:'manual', value: 'manual', checked: true, eventName: 'manualRepeatRequestChange' }
|
||||
]);
|
||||
|
||||
this.openField('Packets');
|
||||
@@ -30,6 +30,9 @@ class PacketErrorPanel extends BasePanel {
|
||||
|
||||
this.addButton('request-button', 'Request', 'requestPackets');
|
||||
}
|
||||
getAutomaticRepeatRequest = () => {
|
||||
return this.getCheckedById('arq');
|
||||
}
|
||||
reset = () => {
|
||||
this.setFailedPacketIndeces([]);
|
||||
this.setSizeCrcUnavailable();
|
||||
@@ -41,7 +44,7 @@ class PacketErrorPanel extends BasePanel {
|
||||
}
|
||||
getFailedPacketIndeces = () => {
|
||||
let text = this.getValueById('request-packet-indexes');
|
||||
return text.replace(/\s+/g, '').split(',').map(Number);
|
||||
return text.replace(/\s+/g, '').split(',').filter(v => v !== '').map(Number);
|
||||
}
|
||||
setCrcPassed = (passed) => this.setValueById('crc', passed ? 'Pass' : 'Fail');
|
||||
setCrcUnavailable = () => this.setValueById('crc', 'N/A');
|
||||
|
||||
@@ -15,7 +15,7 @@ class ReceivePanel extends BasePanel {
|
||||
this.addNewLine();
|
||||
this.addDynamicText('id-state', 'Offline.');
|
||||
|
||||
this.addProgressBar('progress', .50, .25);
|
||||
this.addProgressBar('progress', 0, 0);
|
||||
|
||||
this.addCode('text', '', 'small');
|
||||
this.addImage('image', undefined, {width: 32, height: 32});
|
||||
@@ -45,6 +45,10 @@ class ReceivePanel extends BasePanel {
|
||||
this.addEventListener('resetClick', () => {
|
||||
AudioReceiver.reset();
|
||||
StreamManager.reset();
|
||||
this.setReceivedBytes([]);
|
||||
this.setExpectedPacketCount(0);
|
||||
this.setFailedPacketCount(0);
|
||||
this.setSuccessfulPacketCount(0);
|
||||
});
|
||||
}
|
||||
isOnline = () => this.getCheckedById('is-online');
|
||||
@@ -58,17 +62,6 @@ class ReceivePanel extends BasePanel {
|
||||
this.setValueById('id-state', 'offline');
|
||||
}
|
||||
}
|
||||
|
||||
// waitForSignal = () => {
|
||||
// AudioReceiver.start();
|
||||
// }
|
||||
// reset = () => {
|
||||
// AudioReceiver.reset();
|
||||
// StreamManager.reset();
|
||||
// }
|
||||
// stopWaitingForSignal = () => {
|
||||
// AudioReceiver.stop();
|
||||
// }
|
||||
setProgress = (percent, percent2 = 0) => {
|
||||
this.setProgressById('progress', percent, percent2);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,9 @@ import Dispatcher from "./Dispatcher";
|
||||
import * as CRC from './CRC';
|
||||
import * as PacketUtils from './PacketUtils';
|
||||
import {
|
||||
bitsToBytes,
|
||||
bitsToInt,
|
||||
bytesToBits,
|
||||
numberToBytes,
|
||||
numberToHex,
|
||||
numberToAscii,
|
||||
bytesToNumber
|
||||
} from "./converters";
|
||||
|
||||
const dispatcher = new Dispatcher('StreamManager', [
|
||||
@@ -41,7 +37,9 @@ export const removeEventListener = dispatcher.removeListener;
|
||||
|
||||
const isPacketInRange = (packetIndex) => {
|
||||
// Blindly accept. We can't do anything about it for now
|
||||
if(!isSizeTrusted()) return true;
|
||||
if(!isSizeTrusted()){
|
||||
return packetIndex < PacketUtils.getMaxPackets();
|
||||
}
|
||||
const { packetCount } = PacketUtils.packetStats(getSize());
|
||||
return packetIndex < packetCount;
|
||||
}
|
||||
@@ -125,11 +123,23 @@ export const applyPacket = ({
|
||||
}
|
||||
delete BITS[packetIndex]
|
||||
}
|
||||
export const getFailedPacketIndeces = () => FAILED_SEQUENCES;
|
||||
export const getFailedPacketIndeces = () => {
|
||||
return FAILED_SEQUENCES.filter(isPacketInRange);
|
||||
}
|
||||
export const getNeededPacketIndeces = () => {
|
||||
if(!isSizeTrusted()) return getFailedPacketIndeces();
|
||||
const packetCount = countExpectedPackets();
|
||||
let indeces = [];
|
||||
for(let i = 0; i < packetCount; i++) {
|
||||
if(SUCCESS_SEQUENCES.includes(i)) continue;
|
||||
indeces.push(i);
|
||||
}
|
||||
return indeces;
|
||||
};
|
||||
export const countFailedPackets = () => FAILED_SEQUENCES.length;
|
||||
export const countSuccessfulPackets = () => SUCCESS_SEQUENCES.length;
|
||||
export const countExpectedPackets = () => {
|
||||
if(!isSizeTrusted()) return 0;
|
||||
if(!isSizeTrusted()) return PacketUtils.getMaxPackets();
|
||||
return PacketUtils.packetStats(getSize()).packetCount;
|
||||
}
|
||||
export const setPacketsExpected = packetCount => {
|
||||
@@ -138,11 +148,27 @@ export const setPacketsExpected = packetCount => {
|
||||
SAMPLES_EXPECTED = packetCount * PacketUtils.getPacketSegmentCount();
|
||||
}
|
||||
|
||||
const hasPackets = (start, end) => {
|
||||
for(let packetIndex = start; packetIndex <= end; packetIndex++) {
|
||||
// We need this packet, but it failed to transfer
|
||||
if(FAILED_SEQUENCES.includes(packetIndex)) return false;
|
||||
// We need this packet, but it hasn't come through yet
|
||||
if(!SUCCESS_SEQUENCES.includes(packetIndex)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const hasBytes = (index, length) => {
|
||||
if(DATA.length < index + length) return false;
|
||||
const packetSize = PacketUtils.getPacketDataByteCount();
|
||||
const start = Math.floor(index / packetSize);
|
||||
const end = Math.floor(index + length / packetSize);
|
||||
return hasPackets(start, end);
|
||||
}
|
||||
export const getSizeAvailable = () => {
|
||||
if(DATA_SIZE_BIT_COUNT === 0) return 1;
|
||||
let lastBit = DATA_SIZE_BIT_COUNT;
|
||||
let lastByte = Math.ceil(lastBit / 8);
|
||||
if(DATA.length < lastByte) return false;
|
||||
if(!hasBytes(0, lastByte)) return false;
|
||||
|
||||
// Do we have a crc check on the size?
|
||||
if(DATA_SIZE_CRC_BIT_COUNT !== 0) {
|
||||
@@ -209,13 +235,14 @@ export const getSizeCrcAvailable = () => {
|
||||
if (DATA_SIZE_BIT_COUNT === 0) return false;
|
||||
if (DATA_SIZE_CRC_BIT_COUNT === 0) return false;
|
||||
const bitsNeeded = DATA_SIZE_BIT_COUNT + DATA_SIZE_CRC_BIT_COUNT;
|
||||
return DATA.length >= Math.ceil(bitsNeeded / 8);
|
||||
const bytesNeeded = Math.ceil(bitsNeeded / 8);
|
||||
return hasBytes(0, bytesNeeded);
|
||||
}
|
||||
export const getCrcAvailable = () => {
|
||||
if(DATA_CRC_BIT_COUNT === 0) return false;
|
||||
if(!getSizeAvailable()) return false;
|
||||
let byteCount = getSize();
|
||||
if(DATA.length < byteCount) return false;
|
||||
|
||||
// Do we have enough bytes for the headers and underlying data?
|
||||
let headerBitCount = DATA_SIZE_BIT_COUNT + DATA_CRC_BIT_COUNT + DATA_SIZE_CRC_BIT_COUNT;
|
||||
if(headerBitCount % 8 !== 0)
|
||||
@@ -223,7 +250,7 @@ export const getCrcAvailable = () => {
|
||||
const headerByteCount = headerBitCount / 8;
|
||||
byteCount += headerByteCount;
|
||||
|
||||
return DATA.length >= byteCount;
|
||||
return hasBytes(0, byteCount);
|
||||
}
|
||||
export const getSizeCrcPassed = () => {
|
||||
if(!getSizeCrcAvailable()) return false;
|
||||
|
||||
@@ -90,3 +90,8 @@ export const bytesToUrl = bytes => {
|
||||
const blob = new Blob([new Uint8Array(bytes)]);
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
export function htmlEncode(text) {
|
||||
const element = document.createElement('div');
|
||||
element.textContent = text;
|
||||
return element.innerHTML;
|
||||
}
|
||||
30
index.html
30
index.html
@@ -10,12 +10,6 @@
|
||||
<body>
|
||||
<h1>Data Over Audio</h1>
|
||||
<div class="panels" id="panel-container">
|
||||
<div class="chart">
|
||||
<h2>Channel Graph</h2>
|
||||
<div>
|
||||
<canvas id="received-channel-graph" width="800" height="300"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Data</h2>
|
||||
<div>
|
||||
@@ -28,18 +22,6 @@
|
||||
Unused bits in last packet: <span id="last-packet-unused-bit-count"></span><br>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Original Data to send</h2>
|
||||
<div>
|
||||
<div class="raw-data" id="sent-data"></div><br />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Encoded packets to send</h2>
|
||||
<div>
|
||||
<div class="raw-data" id="error-correcting-data"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Decoded</h2>
|
||||
<div>
|
||||
@@ -52,18 +34,6 @@
|
||||
Decoded Packets: <span id="received-decoded-bits-error-percent">N/A</span>%<br />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Encoded Packets Received</h2>
|
||||
<div>
|
||||
<div class="raw-data" id="received-encoded-bits"></div><br />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Decoded Packets Received</h2>
|
||||
<div>
|
||||
<div class="raw-data" id="received-decoded-bits"></div><br />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Selected</h2>
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user