mirror of
https://github.com/lewismoten/data-over-audio.git
synced 2026-04-03 18:26:24 +08:00
show sample rate
This commit is contained in:
@@ -20,8 +20,9 @@
|
|||||||
</label>
|
</label>
|
||||||
<h2>Received</h2>
|
<h2>Received</h2>
|
||||||
<textarea id="received-data" rows="10" cols="40"></textarea><br />
|
<textarea id="received-data" rows="10" cols="40"></textarea><br />
|
||||||
|
Samples Per Bit: <span id="samples-per-bit">0</span><br>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<canvas id="received-graph" width="1000" height="255"></canvas>
|
<canvas id="received-graph" width="800" height="100"></canvas>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
37
index.js
37
index.js
@@ -2,6 +2,7 @@ var audioContext;
|
|||||||
var sendButton;
|
var sendButton;
|
||||||
var textToSend;
|
var textToSend;
|
||||||
var isListeningCheckbox;
|
var isListeningCheckbox;
|
||||||
|
var samplesPerBitLabel;
|
||||||
var microphoneStream;
|
var microphoneStream;
|
||||||
var microphoneNode;
|
var microphoneNode;
|
||||||
var analyser;
|
var analyser;
|
||||||
@@ -15,10 +16,14 @@ var MAX_DATA_POINTS = 1024;
|
|||||||
var FREQUENCY_TONE = 18000;
|
var FREQUENCY_TONE = 18000;
|
||||||
var FREQUENCY_HIGH = 900;
|
var FREQUENCY_HIGH = 900;
|
||||||
var FREQUENCY_LOW = 1200;
|
var FREQUENCY_LOW = 1200;
|
||||||
var FREQUENCY_DURATION = 800;
|
// 190 = 11.63 samples
|
||||||
var FREQUENCY_THRESHOLD = 210;
|
// 180 = 11 samples
|
||||||
|
var FREQUENCY_DURATION = 170;
|
||||||
|
var FREQUENCY_THRESHOLD = 200;
|
||||||
var frequencyOverTime = [];
|
var frequencyOverTime = [];
|
||||||
var bitStart = [];
|
var bitStart = [];
|
||||||
|
var samplesPerBit = [];
|
||||||
|
var bitSampleCount = 0;
|
||||||
|
|
||||||
function handleWindowLoad() {
|
function handleWindowLoad() {
|
||||||
// grab dom elements
|
// grab dom elements
|
||||||
@@ -28,6 +33,7 @@ function handleWindowLoad() {
|
|||||||
receivedGraph = document.getElementById('received-graph');
|
receivedGraph = document.getElementById('received-graph');
|
||||||
textToSend = document.getElementById('text-to-send');
|
textToSend = document.getElementById('text-to-send');
|
||||||
sentDataTextArea = document.getElementById('sent-data');
|
sentDataTextArea = document.getElementById('sent-data');
|
||||||
|
samplesPerBitLabel = document.getElementById('samples-per-bit');
|
||||||
|
|
||||||
// wire up events
|
// wire up events
|
||||||
sendButton.addEventListener('click', handleSendButtonClick);
|
sendButton.addEventListener('click', handleSendButtonClick);
|
||||||
@@ -90,7 +96,7 @@ function handleListeningCheckbox(e) {
|
|||||||
microphoneNode = audioContext.createMediaStreamSource(stream);
|
microphoneNode = audioContext.createMediaStreamSource(stream);
|
||||||
analyser = audioContext.createAnalyser();
|
analyser = audioContext.createAnalyser();
|
||||||
analyser.smoothingTimeConstant = 0;
|
analyser.smoothingTimeConstant = 0;
|
||||||
analyser.fftSize = 2 ** 15;
|
analyser.fftSize = 2 ** 12;
|
||||||
microphoneNode.connect(analyser);
|
microphoneNode.connect(analyser);
|
||||||
requestAnimationFrame(analyzeAudio);
|
requestAnimationFrame(analyzeAudio);
|
||||||
}
|
}
|
||||||
@@ -172,17 +178,22 @@ function evaluateBit(highBits, lowBits) {
|
|||||||
|
|
||||||
var high = canHear(FREQUENCY_HIGH);
|
var high = canHear(FREQUENCY_HIGH);
|
||||||
var low = canHear(FREQUENCY_LOW);
|
var low = canHear(FREQUENCY_LOW);
|
||||||
|
const now = performance.now();
|
||||||
if(high || low) {
|
if(high || low) {
|
||||||
const now = performance.now();
|
|
||||||
if(bitStarted) {
|
if(bitStarted) {
|
||||||
if(now - bitStarted >= FREQUENCY_DURATION) {
|
if(now - bitStarted >= FREQUENCY_DURATION) {
|
||||||
|
samplesPerBit.unshift(bitSampleCount)
|
||||||
received(evaluateBit(bitHighStrength, bitLowStrength));
|
received(evaluateBit(bitHighStrength, bitLowStrength));
|
||||||
bitHighStrength.length = 0;
|
bitHighStrength.length = 0;
|
||||||
bitLowStrength.length = 0;
|
bitLowStrength.length = 0;
|
||||||
bitStarted = now;
|
bitStarted = now;
|
||||||
bitStart[0] = true;
|
bitStart[0] = true;
|
||||||
|
bitSampleCount = 1;
|
||||||
|
} else {
|
||||||
|
bitSampleCount++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
bitSampleCount = 1;
|
||||||
bitStarted = now;
|
bitStarted = now;
|
||||||
bitStart[0] = true;
|
bitStart[0] = true;
|
||||||
bitHighStrength.length = 0;
|
bitHighStrength.length = 0;
|
||||||
@@ -192,15 +203,31 @@ function evaluateBit(highBits, lowBits) {
|
|||||||
bitLowStrength.push(amplitude(FREQUENCY_LOW));
|
bitLowStrength.push(amplitude(FREQUENCY_LOW));
|
||||||
} else {
|
} else {
|
||||||
if(bitStarted) {
|
if(bitStarted) {
|
||||||
|
// was bit long enough?
|
||||||
|
const duration = now - bitStarted;
|
||||||
|
if(duration >= FREQUENCY_DURATION * 0.6) {
|
||||||
|
samplesPerBit.unshift(bitSampleCount)
|
||||||
|
received(evaluateBit(bitHighStrength, bitLowStrength));
|
||||||
|
}
|
||||||
bitStarted = undefined;
|
bitStarted = undefined;
|
||||||
bitStart[0] = true;
|
bitStart[0] = true;
|
||||||
received(evaluateBit(bitHighStrength, bitLowStrength));
|
|
||||||
received('\n');
|
received('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(samplesPerBit.length > 1024) {
|
||||||
|
samplesPerBit.length = 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
samplesPerBitLabel.innerText = avgLabel(samplesPerBit);
|
||||||
requestAnimationFrame(analyzeAudio);
|
requestAnimationFrame(analyzeAudio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function avgLabel(array) {
|
||||||
|
const values = array.filter(v => v > 0);
|
||||||
|
if(values.length === 0) return 'N/A';
|
||||||
|
return (values.reduce((t, v) => t + v, 0) / values.length).toFixed(2)
|
||||||
|
}
|
||||||
|
|
||||||
function drawBitStart(ctx, color) {
|
function drawBitStart(ctx, color) {
|
||||||
const { width, height } = receivedGraph;
|
const { width, height } = receivedGraph;
|
||||||
const segmentWidth = (1 / 1024) * width;
|
const segmentWidth = (1 / 1024) * width;
|
||||||
|
|||||||
Reference in New Issue
Block a user