move sample interleaving to audio sender/receiver
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
45
index.js
45
index.js
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user