move sample interleaving to audio sender/receiver

This commit is contained in:
Lewis Moten
2024-05-14 03:09:41 -04:00
parent 398eea69b2
commit 522a925009
4 changed files with 57 additions and 32 deletions

View File

@@ -1,6 +1,11 @@
import Dispatcher from "./Dispatcher";
const dispatcher = new Dispatcher('AudioReceiver', ['begin', 'end', 'receive']);
const noEncoding = bits => bits;
let SAMPLE_ENCODING = {
encode: noEncoding,
decode: noEncoding
};
let sampleIntervalIds = [];
let SAMPLE_LAST_COLLECTED = 0;
@@ -26,6 +31,11 @@ const setTimeoutMilliseconds = (milliseconds) => {
signalTimeoutId = window.setTimeout(handleSignalLost, SIGNAL_TIMEOUT_MS, LAST_SIGNAL_BEFORE_TIMEOUT);
}
}
export const setSampleEncoding = ({ encode, decode } = {}) => {
SAMPLE_ENCODING.encode = encode ?? noEncoding;
SAMPLE_ENCODING.decode = decode ?? noEncoding;
}
const changeConfiguration = ({
fskSets,
signalIntervalMs,
@@ -154,7 +164,8 @@ function processSample({ signalStart, index }) {
const samples = SAMPLES.filter(isSegment);
if(samples.length === 0) return;
let bits = evaluateBits(samples);
let bits = SAMPLE_ENCODING.decode(evaluateBits(samples));
const { start, end } = samples[0];
dispatcher.emit('receive', {
signalStart,

View File

@@ -1,6 +1,11 @@
import Dispatcher from "./Dispatcher";
const dispatcher = new Dispatcher('AudioSender', ['begin', 'end', 'send']);
const noEncoding = bits => bits;
let SAMPLE_ENCODING = {
encode: noEncoding,
decode: noEncoding
};
let audioContext;
let CHANNELS = [];
@@ -15,6 +20,11 @@ let stopOscillatorsTimeoutId;
export const addEventListener = dispatcher.addListener;
export const removeEventListener = dispatcher.removeListener;
export const setSampleEncoding = ({ encode, decode } = {}) => {
SAMPLE_ENCODING.encode = encode ?? noEncoding;
SAMPLE_ENCODING.decode = decode ?? noEncoding;
}
export const changeConfiguration = ({
channels,
destination,
@@ -65,9 +75,17 @@ function getOscillators() {
return CHANNEL_OSCILLATORS;
}
export function send(bits, startSeconds) {
const fskPairs = getChannels();
if(bits.length < fskPairs.length) {
throw new Error(`Expected ${fskPairs.length} bits. Received ${bits.length}.`)
bits.push(...new Array(fskPairs.length - bits.length).fill(0));
} else if(bits.length > fskPairs.length) {
throw new Error(`Invalid bit length. Expected ${fskPairs.length}, but got ${bits.lengt}`);
}
bits = SAMPLE_ENCODING.encode(bits);
const oscillators = getOscillators();
const sentBits = [];
getChannels().forEach((channel, i) => {
fskPairs.forEach((fsk, i) => {
// send missing bits as zero
const isHigh = bits[i] ?? 0;
sentBits.push(isHigh);
@@ -75,7 +93,7 @@ export function send(bits, startSeconds) {
// already at correct frequency
if(oscillator.on === isHigh) return;
oscillator.on = isHigh;
const hz = channel[isHigh ? 1 : 0];
const hz = fsk[isHigh ? 1 : 0];
oscillator.frequency.setValueAtTime(hz, startSeconds);
});

View File

@@ -20,10 +20,6 @@ let BITS_PER_PACKET = 0;
let SEGMENTS_PER_PACKET = 0;
let BITS_PER_SEGMENT = 0;
let STREAM_HEADERS = [];
let SEGMENT_ENCODING = {
encode: bits => bits,
decode: bits => bits
};
let PACKET_ENCODING = {
encode: bits => bits,
decode: bits => bits
@@ -111,10 +107,6 @@ export const changeConfiguration = ({
STREAM_HEADERS = streamHeaders;
}
const noEncoding = bits => bits;
export const setSegmentEncoding = ({ encode, decode } = {}) => {
SEGMENT_ENCODING.encode = encode ?? noEncoding;
SEGMENT_ENCODING.decode = decode ?? noEncoding;
}
export const setPacketEncoding = ({ encode, decode } = {}) => {
PACKET_ENCODING.encode = encode ?? noEncoding;
PACKET_ENCODING.decode = decode ?? noEncoding;
@@ -171,7 +163,6 @@ export const getPacketBits = (packetIndex, defaultBit = 0) => {
const packet = BITS[packetIndex] ?? [];
for(let segmentIndex = 0; segmentIndex < SEGMENTS_PER_PACKET; segmentIndex++) {
let segment = packet[segmentIndex] ?? [];
segment = SEGMENT_ENCODING.decode(segment);
for(let bitIndex = 0; bitIndex < BITS_PER_SEGMENT; bitIndex++) {
const bit = segment[bitIndex];
bits.push(bit ?? defaultBit);

View File

@@ -145,8 +145,6 @@ function handleWindowLoad() {
speedPanel.setPacketizationBitsPerSecond(0);
speedPanel.setTransferDurationMilliseconds(0);
AudioReceiver.setTimeoutMilliseconds(signalPanel.getTimeoutMilliseconds());
// Events
communicationsPanel.addEventListener('sendSpeakersChange', handleChangeSendSpeakers);
@@ -184,9 +182,9 @@ function handleWindowLoad() {
packetizationPanel.addEventListener('sizePowerChange', configurationChanged);
packetizationPanel.addEventListener('interleavingChange', () => {
StreamManager.setSegmentEncoding(
packetizationPanel.getInterleaving() ? InterleaverEncoding : undefined
);
const encoding = packetizationPanel.getInterleaving() ? InterleaverEncoding : undefined;
AudioReceiver.setSampleEncoding(encoding);
AudioSender.setSampleEncoding(encoding)
configurationChanged();
});
packetizationPanel.addEventListener('errorCorrectionChange', configurationChanged);
@@ -196,6 +194,11 @@ function handleWindowLoad() {
packetizationPanel.addEventListener('packetCrcChange', configurationChanged);
packetizationPanel.addEventListener('sequenceNumberPowerChange', configurationChanged);
AudioReceiver.setTimeoutMilliseconds(signalPanel.getTimeoutMilliseconds());
const encoding = packetizationPanel.getInterleaving() ? InterleaverEncoding : undefined;
AudioReceiver.setSampleEncoding(encoding);
AudioSender.setSampleEncoding(encoding)
availableFskPairsPanel.addEventListener('change', (event) => {
frequencyGraphPanel.setFskPairs(event.selected);
configurationChanged();
@@ -477,21 +480,23 @@ function sendBytes(bytes) {
const packer = PacketUtils.pack(bits);
AudioSender.beginAt(startSeconds);
// send all packets
for(let i = 0; i < packetCount; i++) {
let packet = packer.getBits(i);
SENT_ENCODED_BITS.push(...packet);
if(packet.length > packetBitCount) {
console.error('Too many bits in the packet. tried to send %s, limited to %s', packet.length, packetBitCount);
AudioSender.stop();
return;
try {
AudioSender.beginAt(startSeconds);
// send all packets
for(let i = 0; i < packetCount; i++) {
let packet = packer.getBits(i);
if(packet.length > packetBitCount) {
throw new Error(`Too many bits in the packet. tried to send ${packet.length}, limited to ${packetBitCount}`);
}
packet.push(...new Array(packetBitCount - packet.length).fill(0));
sendPacket(packet, startSeconds + (i * packetDurationSeconds));
}
packet = padArray(packet, packetBitCount, 0);
sendPacket(packet, startSeconds + (i * packetDurationSeconds));
AudioSender.stopAt(startSeconds + totalDurationSeconds);
} catch (e) {
console.error(e);
AudioSender.stop();
return;
}
AudioSender.stopAt(startSeconds + totalDurationSeconds);
showSentBits();
// start the graph moving again
@@ -531,8 +536,8 @@ function sendPacket(bits, packetStartSeconds) {
const segmentDurationSeconds = PacketUtils.getSegmentDurationSeconds();
for(let i = 0; i < bitCount; i += channelCount) {
let segmentBits = bits.slice(i, i + channelCount);
if(packetizationPanel.getInterleaving()) {
segmentBits = InterleaverEncoding.encode(segmentBits);
if(segmentBits.length !== channelCount) {
segmentBits.push(...new Array(channelCount - segmentBits.length).fill(0))
}
const segmentIndex = Math.floor(i / channelCount);
var offsetSeconds = segmentIndex * segmentDurationSeconds;