/
sonic-coder.js
61 lines (57 loc) · 2.03 KB
/
sonic-coder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* A simple sonic encoder/decoder for [a-z0-9] => frequency (and back).
* A way of representing characters with frequency.
*/
var ALPHABET = '\n abcdefghijklmnopqrstuvwxyz0123456789,.!?@*';
function SonicCoder(params) {
params = params || {};
this.freqMin = params.freqMin || 18500;
this.freqMax = params.freqMax || 19500;
this.freqError = params.freqError || 50;
this.alphabetString = params.alphabet || ALPHABET;
this.startChar = params.startChar || '^';
this.endChar = params.endChar || '$';
// Make sure that the alphabet has the start and end chars.
this.alphabet = this.startChar + this.alphabetString + this.endChar;
}
/**
* Given a character, convert to the corresponding frequency.
*/
SonicCoder.prototype.charToFreq = function(char) {
// Get the index of the character.
var index = this.alphabet.indexOf(char);
if (index == -1) {
// If this character isn't in the alphabet, error out.
console.error(char, 'is an invalid character.');
index = this.alphabet.length - 1;
}
// Convert from index to frequency.
var freqRange = this.freqMax - this.freqMin;
var percent = index / this.alphabet.length;
var freqOffset = Math.round(freqRange * percent);
return this.freqMin + freqOffset;
};
/**
* Given a frequency, convert to the corresponding character.
*/
SonicCoder.prototype.freqToChar = function(freq) {
// If the frequency is out of the range.
if (!(this.freqMin < freq && freq < this.freqMax)) {
// If it's close enough to the min, clamp it (and same for max).
if (this.freqMin - freq < this.freqError) {
freq = this.freqMin;
} else if (freq - this.freqMax < this.freqError) {
freq = this.freqMax;
} else {
// Otherwise, report error.
console.error(freq, 'is out of range.');
return null;
}
}
// Convert frequency to index to char.
var freqRange = this.freqMax - this.freqMin;
var percent = (freq - this.freqMin) / freqRange;
var index = Math.round(this.alphabet.length * percent);
return this.alphabet[index];
};
module.exports = SonicCoder;