Set segment duration as number

This commit is contained in:
Lewis Moten
2024-05-12 04:55:05 -04:00
parent 99a972e165
commit 56e951e3e1
3 changed files with 46 additions and 26 deletions

View File

@@ -9,6 +9,7 @@ class FrequencyGraphPanel extends BasePanel {
this.signalStart = performance.now(); this.signalStart = performance.now();
this.signalEnd = this.signalStart; this.signalEnd = this.signalStart;
this.samples = []; this.samples = [];
this.samplesPerGroup = 1;
this.duration = 200; this.duration = 200;
this.amplitudeThreshold = 0; this.amplitudeThreshold = 0;
this.addButton('toggle', 'Start', 'toggle'); this.addButton('toggle', 'Start', 'toggle');
@@ -26,8 +27,14 @@ class FrequencyGraphPanel extends BasePanel {
setSignalEnd = milliseconds => { setSignalEnd = milliseconds => {
this.signalEnd = milliseconds; this.signalEnd = milliseconds;
} }
setSamplingPeriod = (milliseconds) => this.samplingPeriod = milliseconds; setSamplingPeriod = (milliseconds) => {
this.samplingPeriod = milliseconds;
if(!this.isRunning()) this.draw();
}
setSamplePeriodsPerGroup = count => {
this.samplesPerGroup = count;
if(!this.isRunning()) this.draw();
}
setAmplitudeThreshold = value => { setAmplitudeThreshold = value => {
this.amplitudeThreshold = value; this.amplitudeThreshold = value;
if(!this.isRunning()) this.draw(); if(!this.isRunning()) this.draw();
@@ -150,7 +157,6 @@ class FrequencyGraphPanel extends BasePanel {
if(!now) now = performance.now(); if(!now) now = performance.now();
let lastPeriodStart = now - ((now - this.signalStart) % this.samplingPeriod); let lastPeriodStart = now - ((now - this.signalStart) % this.samplingPeriod);
let lastTextX = -1000; let lastTextX = -1000;
ctx.lineWidth = 1;
this.lastCountX = -1000; this.lastCountX = -1000;
for(let time = lastPeriodStart; time > now - this.duration; time -= this.samplingPeriod) { for(let time = lastPeriodStart; time > now - this.duration; time -= this.samplingPeriod) {
const end = time + this.samplingPeriod; const end = time + this.samplingPeriod;
@@ -161,6 +167,7 @@ class FrequencyGraphPanel extends BasePanel {
ctx.moveTo(rightX, 0); ctx.moveTo(rightX, 0);
ctx.lineTo(rightX, height); ctx.lineTo(rightX, height);
ctx.strokeStyle = 'hsla(120, 100%, 100%, 50%)'; ctx.strokeStyle = 'hsla(120, 100%, 100%, 50%)';
ctx.lineWidth = 1;
ctx.stroke(); ctx.stroke();
let samplePeriodWidth = rightX - leftX; let samplePeriodWidth = rightX - leftX;
@@ -170,7 +177,19 @@ class FrequencyGraphPanel extends BasePanel {
if(time >= this.signalStart && (this.signalEnd < this.signalStart || time < this.signalEnd)) { if(time >= this.signalStart && (this.signalEnd < this.signalStart || time < this.signalEnd)) {
const signalIndex = Math.floor((time - this.signalStart) / this.samplingPeriod); const signalIndex = Math.floor((time - this.signalStart) / this.samplingPeriod);
let text = signalIndex.toLocaleString();
const indexInGroup = signalIndex % this.samplesPerGroup;
if(indexInGroup === 0) {
// Line for when group started
ctx.beginPath();
ctx.moveTo(rightX, 0);
ctx.lineTo(rightX, height);
ctx.strokeStyle = 'hsla(180, 100%, 50%, 50%)';
ctx.lineWidth = 2;
ctx.stroke();
}
let text = indexInGroup.toLocaleString();
let size = ctx.measureText(text); let size = ctx.measureText(text);
let textX = leftX + (samplePeriodWidth / 2) - (size.width / 2); let textX = leftX + (samplePeriodWidth / 2) - (size.width / 2);
// far enough from prior text? // far enough from prior text?

View File

@@ -5,8 +5,8 @@ const clamp = (value, min, max) => Math.max(min, Math.min(value, max));
class SignalPanel extends BasePanel { class SignalPanel extends BasePanel {
constructor() { constructor() {
super('Signal'); super('Signal');
this.openField('Segment Duration'); this.openField('Sampling Period');
this.addInputNumber('segment-duration', 100, {min: 0, max: 1000, eventName: 'segmentDurationChange'}); this.addInputNumber('segment-duration', 100, {min: 3, max: 1000, eventName: 'segmentDurationChange'});
this.addText('ms'); this.addText('ms');
this.closeField(); this.closeField();
@@ -44,13 +44,13 @@ class SignalPanel extends BasePanel {
getWaveform = () => this.getValueById('wave-form'); getWaveform = () => this.getValueById('wave-form');
setWaveform = (value) => this.setValueById('wave-form', value); setWaveform = (value) => this.setValueById('wave-form', value);
getSegmentDuration = () => parseInt(this.getValueById('segment-duration')); getSegmentDurationMilliseconds = () => this.getNumberById('segment-duration');
setSegmentDuration = value => this.setValueById('segment-duration', value); setSegmentDurationMilliseconds = value => this.setValueById('segment-duration', value);
getAmplitudeThreshold = () => parseInt(this.getValueById('amplitude-threshold')) / 100; getAmplitudeThreshold = () => this.getNumberById('amplitude-threshold') / 100;
setAmplitudeThreshold = value => this.setValueById('amplitude-threshold', clamp(value * 100, 0, 100)); setAmplitudeThreshold = value => this.setValueById('amplitude-threshold', clamp(value * 100, 0, 100));
getSmoothingTimeConstant = () => parseInt(this.getValueById('smoothing-time-constant')) / 100; getSmoothingTimeConstant = () => this.getNumberById('smoothing-time-constant') / 100;
setSmoothingTimeConstant = value => this.setValueById('smoothing-time-constant', clamp(value * 100, 0, 100)); setSmoothingTimeConstant = value => this.setValueById('smoothing-time-constant', clamp(value * 100, 0, 100));
} }

View File

@@ -90,7 +90,7 @@ function handleWindowLoad() {
frequencyPanel.setMultiFskPadding(1); frequencyPanel.setMultiFskPadding(1);
signalPanel.setWaveform('triangle'); signalPanel.setWaveform('triangle');
signalPanel.setSegmentDuration(30); signalPanel.setSegmentDurationMilliseconds(30);
signalPanel.setAmplitudeThreshold(0.78); signalPanel.setAmplitudeThreshold(0.78);
signalPanel.setSmoothingTimeConstant(0); signalPanel.setSmoothingTimeConstant(0);
signalPanel.setTimeoutMilliseconds(60); signalPanel.setTimeoutMilliseconds(60);
@@ -101,7 +101,7 @@ function handleWindowLoad() {
availableFskPairsPanel.setFskPairs(frequencyPanel.getFskPairs()); availableFskPairsPanel.setFskPairs(frequencyPanel.getFskPairs());
graphConfigurationPanel.setDurationMilliseconds(signalPanel.getSegmentDuration() * 20); graphConfigurationPanel.setDurationMilliseconds(signalPanel.getSegmentDurationMilliseconds() * 20);
graphConfigurationPanel.setPauseAfterEnd(true); graphConfigurationPanel.setPauseAfterEnd(true);
frequencyGraphPanel.setFskPairs(availableFskPairsPanel.getSelectedFskPairs()); frequencyGraphPanel.setFskPairs(availableFskPairsPanel.getSelectedFskPairs());
@@ -132,8 +132,8 @@ function handleWindowLoad() {
}); });
signalPanel.addEventListener('waveformChange', updateAudioSender); signalPanel.addEventListener('waveformChange', updateAudioSender);
signalPanel.addEventListener('segmentDurationChange', (event) => { signalPanel.addEventListener('segmentDurationChange', () => {
frequencyGraphPanel.setSamplingPeriod(event.value); frequencyGraphPanel.setSamplingPeriod(signalPanel.getSegmentDurationMilliseconds());
configurationChanged(); configurationChanged();
}); });
signalPanel.addEventListener('amplitudeThresholdChange', ({value}) => { signalPanel.addEventListener('amplitudeThresholdChange', ({value}) => {
@@ -244,7 +244,7 @@ function updateAudioReceiver() {
fskSets: availableFskPairsPanel.getSelectedFskPairs(), fskSets: availableFskPairsPanel.getSelectedFskPairs(),
amplitudeThreshold: Math.floor(signalPanel.getAmplitudeThreshold() * 255), amplitudeThreshold: Math.floor(signalPanel.getAmplitudeThreshold() * 255),
analyser: getAnalyser(), analyser: getAnalyser(),
signalIntervalMs: signalPanel.getSegmentDuration(), signalIntervalMs: signalPanel.getSegmentDurationMilliseconds(),
sampleRate: getAudioContext().sampleRate sampleRate: getAudioContext().sampleRate
}); });
} }
@@ -274,7 +274,7 @@ function updatePacketUtils() {
); );
const bitsPerSegment = availableFskPairsPanel.getSelectedFskPairs().length; const bitsPerSegment = availableFskPairsPanel.getSelectedFskPairs().length;
PacketUtils.changeConfiguration({ PacketUtils.changeConfiguration({
segmentDurationMilliseconds: signalPanel.getSegmentDuration(), segmentDurationMilliseconds: signalPanel.getSegmentDurationMilliseconds(),
packetSizeBitCount: packetizationPanel.getSizePower(), packetSizeBitCount: packetizationPanel.getSizePower(),
dataSizeBitCount: MAXIMUM_PACKETIZATION_SIZE_BITS, dataSizeBitCount: MAXIMUM_PACKETIZATION_SIZE_BITS,
dataSizeCrcBitCount: CRC_BIT_COUNT, dataSizeCrcBitCount: CRC_BIT_COUNT,
@@ -323,6 +323,7 @@ function updatePacketStats() {
document.getElementById('segment-transfer-duration').innerText = Humanize.durationMilliseconds(PacketUtils.getSegmentDurationMilliseconds()); document.getElementById('segment-transfer-duration').innerText = Humanize.durationMilliseconds(PacketUtils.getSegmentDurationMilliseconds());
document.getElementById('data-transfer-duration').innerText = Humanize.durationMilliseconds(PacketUtils.getDataTransferDurationMilliseconds(bitCount)); document.getElementById('data-transfer-duration').innerText = Humanize.durationMilliseconds(PacketUtils.getDataTransferDurationMilliseconds(bitCount));
document.getElementById('segments-per-packet').innerText = PacketUtils.getPacketSegmentCount().toLocaleString(); document.getElementById('segments-per-packet').innerText = PacketUtils.getPacketSegmentCount().toLocaleString();
frequencyGraphPanel.setSamplePeriodsPerGroup(PacketUtils.getPacketSegmentCount());
document.getElementById('total-segments').innerText = getTotalSegmentCount(bitCount).toLocaleString(); document.getElementById('total-segments').innerText = getTotalSegmentCount(bitCount).toLocaleString();
} }
@@ -929,7 +930,7 @@ function drawChannelData() {
// Loop through visible segments // Loop through visible segments
const latestSegmentEnded = Math.min(latest, lastStreamEnded); const latestSegmentEnded = Math.min(latest, lastStreamEnded);
for(let time = latestSegmentEnded; time > graphEarliest; time -= signalPanel.getSegmentDuration()) { for(let time = latestSegmentEnded; time > graphEarliest; time -= signalPanel.getSegmentDurationMilliseconds()) {
// too far back? // too far back?
if(time < RECEIVED_STREAM_START_MS) break; if(time < RECEIVED_STREAM_START_MS) break;
@@ -1016,7 +1017,7 @@ function drawSegmentBackground(
width, width,
height height
) { ) {
const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDuration()); const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDurationMilliseconds());
const hue = 120; const hue = 120;
let luminance = segmentIndex % 2 === 0 ? 30 : 25; let luminance = segmentIndex % 2 === 0 ? 30 : 25;
@@ -1037,7 +1038,7 @@ function drawChannelSegmentForeground(
expectedBit expectedBit
) { ) {
const channelHeight = height / channelCount; const channelHeight = height / channelCount;
const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDuration()); const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDurationMilliseconds());
let fontHeight = Math.min(24, channelHeight, segmentWidth); let fontHeight = Math.min(24, channelHeight, segmentWidth);
let top = channelHeight * channelIndex; let top = channelHeight * channelIndex;
ctx.font = `${fontHeight}px Arial`; ctx.font = `${fontHeight}px Arial`;
@@ -1077,7 +1078,7 @@ function drawChannelSegmentBackground(
if(isSelectedOrOver) luminance += 15; if(isSelectedOrOver) luminance += 15;
const channelHeight = height / channelCount; const channelHeight = height / channelCount;
const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDuration()); const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDurationMilliseconds());
let top = channelHeight * channelIndex; let top = channelHeight * channelIndex;
ctx.fillStyle = `hsl(${hue}, 100%, ${luminance}%)`; ctx.fillStyle = `hsl(${hue}, 100%, ${luminance}%)`;
ctx.fillRect(endX, top, segmentWidth, channelHeight); ctx.fillRect(endX, top, segmentWidth, channelHeight);
@@ -1114,7 +1115,7 @@ function drawChannelNumbers(ctx, channelCount, width, height) {
const offset = 0; const offset = 0;
const channels = availableFskPairsPanel.getSelectedFskPairs(); const channels = availableFskPairsPanel.getSelectedFskPairs();
const channelHeight = height / channelCount; const channelHeight = height / channelCount;
const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDuration()); const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDurationMilliseconds());
let fontHeight = Math.min(24, channelHeight, segmentWidth); let fontHeight = Math.min(24, channelHeight, segmentWidth);
ctx.font = `${fontHeight}px Arial`; ctx.font = `${fontHeight}px Arial`;
ctx.textBaseline = 'middle'; ctx.textBaseline = 'middle';
@@ -1317,11 +1318,11 @@ function getChannelAndSegment(e) {
}; };
} }
const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDuration()); const segmentWidth = width / (graphConfigurationPanel.getDurationMilliseconds() / signalPanel.getSegmentDurationMilliseconds());
const latestSegmentEnded = Math.min(latest, lastStreamEnded); const latestSegmentEnded = Math.min(latest, lastStreamEnded);
for(let time = latestSegmentEnded; time > graphEarliest; time -= signalPanel.getSegmentDuration()) { for(let time = latestSegmentEnded; time > graphEarliest; time -= signalPanel.getSegmentDurationMilliseconds()) {
// too far back? // too far back?
if(time < RECEIVED_STREAM_START_MS) { if(time < RECEIVED_STREAM_START_MS) {
return { return {
@@ -1331,11 +1332,11 @@ function getChannelAndSegment(e) {
}; };
// which segment are we looking at? // which segment are we looking at?
const segmentIndex = Math.floor(((time - RECEIVED_STREAM_START_MS) / signalPanel.getSegmentDuration())); const segmentIndex = Math.floor(((time - RECEIVED_STREAM_START_MS) / signalPanel.getSegmentDurationMilliseconds()));
// when did the segment begin/end // when did the segment begin/end
const segmentStart = RECEIVED_STREAM_START_MS + (segmentIndex * signalPanel.getSegmentDuration()); const segmentStart = RECEIVED_STREAM_START_MS + (segmentIndex * signalPanel.getSegmentDurationMilliseconds());
const segmentEnd = segmentStart + signalPanel.getSegmentDuration(); const segmentEnd = segmentStart + signalPanel.getSegmentDurationMilliseconds();
// where is the segments left x coordinate? // where is the segments left x coordinate?
const leftX = ((latest - segmentEnd) / graphDuration) * width; const leftX = ((latest - segmentEnd) / graphDuration) * width;