Detailed Results Implementation

master
Glenwing 6 years ago
parent 0393fbc30a
commit 20bb45b82c

2
.gitignore vendored

@ -58,3 +58,5 @@ docs/HDMI 2.0 FAQ Archive_files/header_manufacturers.jpg
docs/HDMI 2.0 FAQ Archive_files/jquery-1.6.2.min.js.download
docs/HDMI 2.0 FAQ Archive_files/search_btn.gif
docs/HDMI 2.0 FAQ Archive_files/style.css
bandwidth/CTA861-Simplified.txt
bandwidth/test.txt

@ -7,17 +7,18 @@ function DEBUG(text) {
if ('all' in DebugSettings) {
if (!DebugSettings['all']) {
return;
} // if All == false, always skip
}
else if (DebugSettings['all']) {
//printDebug(Fn, arguments);
proceed_with_msg = true;
}
}
else if (Fn in DebugSettings) {
if (DebugSettings[Fn] == false) {
//printDebug(Fn, arguments)
proceed_with_msg = false;
}
else {
proceed_with_msg = true;
}
}
else {
proceed_with_msg = true;

@ -0,0 +1,641 @@
function SI(value, unit, options_input) {
DEBUG('Input:', value, unit, options_input);
if (isNaN(parseInt(value))) { return value; }
if (typeof(options_input) === 'number' || typeof(options_input) === 'string') { options_input = {p: options_input.toString()}; }
Default_Options = [
['mode', 'f'],
['p', '2'],
//['exclude', ['c', 'd', 'D', 'H']],
['exclude', []],
['include', []],
['grouper', ','],
['decimal', '.'],
['threshold', 0],
['separator', ' '],
['style', 'abbr'],
['output', 'single'],
['big_kilo', false],
['no_mu', false],
]
for (var i = 0; i < Default_Options.length; i++) {
if (!(Default_Options[i][0] in options_input)) {
//DEBUG('SI option "' + Default_Options[i][0] + '" defaulted to:', Default_Options[i][1])
options_input[Default_Options[i][0]] = Default_Options[i][1];
}
}
/* Valid options:
SI_options = {
mode: 'f' Precision mode (default Fixed mode). Options are:
'fixed' or 'f' Uses a fixed number of decimal places, specified by precision field
'sig' or 's' Targets a fixed number of significant figures.
'adaptive' or 'a' Uses up to a certain number of decimal points, but leaves no trailing zeroes when not needed.
p: 2 Specifies default precision (number of decimal places).
For adaptive mode, it may be specified in the format "[2, 5]" to indicate minimum and maximum precision. A single number will be interpreted as a maximum.
Also accepts individual decimal place settings for each prefix, in array format; for example:
{p: [1, G2, M0]} sets a default of 1 for all prefixes, then specifies 2 decimal places for Giga and 0 for Mega.
That can alternatively be written as powers:
{p: [1, [9, 2], [6, 0]]}
separator: ',' Character to use as thousands separator (default comma)
decimal: '.' Character to use as decimal point (default period)
unit_sep: '&nbsp;' Character to place between the value and unit symbol (default non-breaking space)
big_kilo: 'true' Use capital K for kilo instead of small k. (default false)
no_mu: 'true' Use "u" instead of "µ" on output, if necessary for compatibility reasons (default false)
threshold: 1000 Point at which to use the next
exclude: ['c', 'd'] SI prefixes to exclude, for situational use (i.e. for displaying time, one may not wish for "centiseconds").
Symbols can also be used as shortcuts, as in the following examples:
'>=G' excludes Giga and larger
'>G' excludes larger than Giga, but not Giga itself
'<G' and "<=G" same as above, but for prefixes smaller than Giga
'*' excludes all prefixes (unless protected)
'!G' protects a prefix from '*', i.e. {exclude: ['*', '!k', '!M']} excludes all prefixes except Kilo and Mega)
Multiple arguments accepted in array format
"u" is accepted as an argument for excluding "µ", and "0" is accepted for excluding the prefixless base unit
By default, the following are excluded already, and must be un-excluded (using !c, !d, etc.) to be used:
'c' (centi, 10^-2)
'd' (deci, 10^-1)
'D' (deca, 10^1)
'H' (hecto, 10^2)
include: ['k', 'm'] SI prefixes to include. Used to make exceptions to blanket exclusions (such as "exclude: ['>G']"<.
If include is used alone (exclude is left blank/default) then it will be interpreted as "exclude all except [inclusions]".
}
*/
//console.log(SI_options['precision']);
var prefixDef = {
'-24': {sym:'y', name:'yocto', p: 0, incl: false},
'-21': {sym:'z', name:'zepto', p: 0, incl: false},
'-18': {sym:'a', name:'atto', p: 0, incl: false},
'-15': {sym:'f', name:'femto', p: 0, incl: false},
'-12': {sym:'p', name:'pico', p: 0, incl: false},
'-9': {sym:'n', name:'nano', p: 0, incl: false},
'-6': {sym:'µ', name:'micro', p: 0, incl: false},
'-3': {sym:'m', name:'milli', p: 0, incl: false},
'-2': {sym:'c', name:'centi', p: 0, incl: false},
'-1': {sym:'d', name:'deci', p: 0, incl: false},
'0': {sym:'', name:'', p: 0, incl: false},
'1': {sym:'D', name:'deca', p: 0, incl: false},
'2': {sym:'H', name:'hecto', p: 0, incl: false},
'3': {sym:'k', name:'kilo', p: 0, incl: false},
'6': {sym:'M', name:'mega', p: 0, incl: false},
'9': {sym:'G', name:'giga', p: 0, incl: false},
'12': {sym:'T', name:'tera', p: 0, incl: false},
'15': {sym:'P', name:'peta', p: 0, incl: false},
'18': {sym:'E', name:'exa', p: 0, incl: false},
'21': {sym:'Z', name:'zetta', p: 0, incl: false},
'24': {sym:'Y', name:'yotta', p: 0, incl: false},
'_min': -24,
'_max': 24,
};
var pre2num = {
'y': -24,
'z': -21,
'a': -18,
'f': -15,
'p': -12,
'n': -9,
'µ': -6,
'u': -6,
'm': -3,
'c': -2,
'd': -1,
'b': 0,
'B': 0,
'0': 0,
'D': 1,
'H': 2,
'k': 3,
'K': 3,
'M': 6,
'G': 9,
'T': 12,
'P': 15,
'E': 18,
'Z': 21,
'Y': 24,
'_min': -24,
'_max': 24,
}
/*
SI_defaults = {
mode: 'f',
p: 2,
//exclude: ['c', 'd', 'D', 'H'],
exclude: [],
include: [],
grouper: ',',
decimal: '.',
threshold: 0,
separator: '&nbsp;',
style: 'abbr',
output: 'single',
big_kilo: false,
no_mu: false,
}*/
// Apply the default precision setting above
/*for (var i = prefixDef['_min']; i <= prefixDef['_max']; i++) {
if (i.toString() in prefixDef) {
//prefixDef[i.toString()]['p'] = SI_defaults['p'];
prefixDef[i.toString()]['p'] = 2;
}
}*/
var out_value;
var out_prefix;
var precision;
var SI_options = options_input;
prefixDef = SI_include_exclude(SI_options, prefixDef, pre2num);
prefixDef = SI_set_precision(SI_options, prefixDef, pre2num);
//[prefixDef, SI_options] = SI_set_options(options_input, prefixDef, pre2num);
DEBUG('prefixDef:', prefixDef)
//SI_options['p'] = options_input['p'];
if (Math.abs(value) < 0.000000000001) {
magnitude = 0;
DEBUG('Value was zero:', value);
precision = prefixDef[0]['p'];
out_value = Commas(value.toFixed(precision));
out_prefix = '';
}
else {
var magnitude = Math.floor(Math.log(Math.abs(value))/Math.log(10));
var initial_magnitude = magnitude;
DEBUG('Initial Magnitude:', initial_magnitude);
while (magnitude >= prefixDef['_min'] && magnitude <= prefixDef['_max']) {
// Change any inbetween magnitudes to one that has a prefix assigned to it
if (!(magnitude in prefixDef)) {
//DEBUG('Magnitude ' + magnitude + ' not in prefixDef')
magnitude--;
continue;
}
if (prefixDef[magnitude]['incl'] == false) {
//DEBUG('Magnitude ' + magnitude + ' excluded')
magnitude--;
continue;
}
else {
//DEBUG('Magnitude ' + magnitude + ' incl:', prefixDef[magnitude]['incl']);
// Get the precision specified for that magnitude
precision = prefixDef[magnitude]['p'];
// Divide the number by the appropriate power of 10, and return the new number and associated SI prefix
out_value = Commas(Number(value / Math.pow(10, magnitude)).toFixed(precision));
out_prefix = prefixDef[magnitude]['sym'];
break;
}
}
if (magnitude < prefixDef['_min']) {
DEBUG('Reached lower boundary; reversing search')
magnitude = initial_magnitude;
while (magnitude <= prefixDef['_max']) {
// Change any inbetween magnitudes to one that has a prefix assigned to it
if (!(magnitude in prefixDef)) {
//DEBUG('Magnitude ' + magnitude + ' not in prefixDef')
magnitude++;
continue;
}
if (prefixDef[magnitude]['incl'] == false) {
//DEBUG('Magnitude ' + magnitude + ' excluded')
magnitude++;
continue;
}
else {
//DEBUG('Magnitude ' + magnitude + ' incl:', prefixDef[magnitude]['incl']);
// Get the precision specified for that magnitude
precision = prefixDef[magnitude]['p'];
// Divide the number by the appropriate power of 10, and return the new number and associated SI prefix
out_value = Commas(Number(value / Math.pow(10, magnitude)).toFixed(precision));
out_prefix = prefixDef[magnitude]['sym'];
break;
}
}
}
if (magnitude > prefixDef['_max']) {
DEBUG('Reached upper boundary; returning in base units');
precision = prefixDef[0]['p'];
out_value = Commas(value.toFixed(precision));
out_prefix = '';
}
}
if (SI_options['output'] == 'single') {
var final_output = (out_value + '&nbsp;' + out_prefix + unit);
DEBUG('Single Output');
return final_output
}
else if (SI_options['output'] == 'split') {
var final_output = {
'full': out_value + '&nbsp;' + out_prefix + unit,
'f': out_value + '&nbsp;' + out_prefix + unit,
'value': out_value,
'val': out_value,
'v': out_value,
'unit': out_prefix + unit,
'u': out_prefix + unit,
'old_value': value,
'old_val': value,
'old_v': value,
'o': value,
'base_unit': unit,
'base_u': unit,
'b': unit,
'prefix': out_prefix,
'p': out_prefix,
}
DEBUG('Split Output', final_output);
return final_output
}
}
function SI_include_exclude(SI_options, prefixDef, pre2num) {
// Check if any exclusions are specified
DEBUG('Beginning SI IN/EX Phase 1')
var EX_empty = true;
var EX_has_blanket = false;
var IN_empty = true;
var IN_has_blanket = false;
for (var pass = 0; pass <= 1; pass++) {
if (pass == 0) { var mode = 'exclude'; }
else if (pass == 1) { var mode = 'include'; }
if (mode in SI_options) {
DEBUG(mode + ' argument detected:', SI_options[mode])
var EX = SI_options[mode];
if (EX.length > 0) {
if (pass == 0) { EX_empty = false; }
else if (pass == 1) { IN_empty = false; }
// Check if any of the exclusions are blanket statements
for (var i = 0; i < EX.length; i++) {
if (EX[i].indexOf('<') != -1 || EX[i].indexOf('>') != -1 ) {
if (pass == 0) { EX_has_blanket = true; }
else if (pass == 1) { IN_has_blanket = true; }
}
}
}
}
else {
//DEBUG('SI_options["' + mode + '"] defaulted to blank')
SI_options[mode] = [];
}
/*
if ('include' in SI_options) {
var IN = SI_options['include'];
if (IN.length > 0) {
IN_empty = false;
// Check if any of the exclusions are blanket statements
for (var i = 0; i < IN.length; i++) {
if (IN[i].indexOf('<') != -1 || IN[i].indexOf('>') != -1 ) {
IN_has_blanket = true;
}
}
}
} */
DEBUG('Current Status:', 'Mode:', mode, 'EX/IN:', SI_options[mode], 'EX_empty:', EX_empty, 'IN_empty:', IN_empty)
}
var DEFAULT = true; // Default inclusion status
if (EX_empty && !IN_empty) {
// If Include list has members, but Exclude list is empty
DEFAULT = false;
DEBUG('Default Established (EX_empty && !IN_empty):', DEFAULT);
}
else if (IN_empty && !EX_empty) {
// If Exclude list has members, but Include list is empty
DEFAULT = true;
DEBUG('Default Established (IN_empty && !EX_empty):', DEFAULT);
}
else if (!EX_empty && !IN_empty) {
// If both lists are not blank
if (IN_has_blanket && !EX_has_blanket) {
// If Include list has blanket statements and Exclude list does not
DEFAULT = false; // Exclude by default
DEBUG('Default Established (IN_blnk && !EX_blnk):', DEFAULT);
}
else if (EX_has_blanket && !IN_has_blanket) {
// If Exclude list has blanket statements and Include list does not
DEFAULT = true; // Include by default
DEBUG('Default Established (EX_blnk && !IN_blnk):', DEFAULT);
}
else {
DEBUG('Default Established ((!)IN_blnk && (!)EX_blnk):', DEFAULT);
// If both or neither have blanket statements
DEFAULT = true; // Include by default
}
}
else {
// If both lists are blank
DEBUG('Default Established (IN_empty && EX_empty):', DEFAULT, SI_options[mode], EX_empty);
DEFAULT = true;
}
// Parse Exclude input list
var ex_in_table = [{}, {}];
DEBUG('Beginning SI IN/EX Phase 2')
for (var pass = 0; pass <= 1; pass++) {
if (pass == 0) { var mode = 'exclude'; }
else if (pass == 1) { var mode = 'include'; }
if (mode in SI_options) {
for (var i = 0; i < SI_options[mode].length; i++) {
var arg = SI_options[mode][i]
// Convert numbers to strings to standardize the format
if (typeof(arg) === 'number') {
arg = arg.toString();
}
if (typeof(arg) === 'string') {
// Check for blanket statement
if (arg[0] == '<' || arg[0] == '>') {
DEBUG('Blanket statement detected for mode:', mode, arg)
var eq = false;
var start;
var end;
var step;
if (arg[1] == '=') { eq = true; }
if (arg[0] == '<') {
step = -1;
end = prefixDef['_min'];
}
else if (arg[0] == '>') {
step = 1;
end = prefixDef['_max'];
}
// To get starting point, take the string with the ">" or ">=" removed
start = arg.substring(1 + eq, arg.length);
// If it's a string (such as "K" or "G"), convert to the corresponding power number (and check for validity)
if (!isInt(start)) { if (start in pre2num) {start = pre2num[start]; } else { DEBUG(mode + ' argument not listed in SI prefix definitions', arg, start); } }
// Parse as integer to make sure it's not a string
start = parseInt(start) + (step * (1 - eq)); // If <, -1 // If <= or >=, +0 // If >, +1
if (Number.isNaN(start)) { DEBUG(mode + ' argument evaluates to NaN:', arg); }
// Make sure the start point is inside or equal to the boundaries, otherwise infinite loop.
if (start < prefixDef['_min'] || start > prefixDef['_max']) {
DEBUG(mode + ' blanket argument begins outside valid range')
}
// Loop through each power between the starting point and ending point, adding each one to the exclusion/inclusion list
for (var j = start; j != (end + step); j += step) {
ex_in_table[pass][j] = {'state': true, 'blanket': true};
}
}
// If not a blanket statement
else {
DEBUG('Non-blanket ' + mode + ' statement detected:', arg)
// If it's a string (such as "K" or "G"), convert to the corresponding power number (and check for validity)
if (!isInt(arg)) { if (arg in pre2num) {arg = pre2num[arg]; } else { DEBUG(mode + ' argument not listed in SI prefix definitions', arg); } }
ex_in_table[pass][arg] = {'state': true, 'blanket': false};
}
}
}
}
}
// Now the exclusions and inclusion arguments have been expanded, time to combine them and deal with conflicts.
DEBUG('Beginning SI IN/EX Phase 3')
for (var P = prefixDef['_min']; P <= prefixDef['_max']; P++) {
if (!(P in prefixDef)) { continue; }
if (P in ex_in_table[0]) { var EX = ex_in_table[0][P]; }
if (P in ex_in_table[1]) { var IN = ex_in_table[1][P]; }
if (P in ex_in_table[0] && !(P in ex_in_table[1])) {
// If Exclusion rule exists, and no Inclusion rule is specified, set exclusion rule
prefixDef[P]['incl'] = !EX['state'];
}
else if (P in ex_in_table[1] && !(P in ex_in_table[0])) {
// If Inclusion rule exists, and no Exclusion rule is specified, set exclusion rule
prefixDef[P]['incl'] = IN['state'];
}
else if (!(P in ex_in_table[1]) && !(P in ex_in_table[0])) {
// If no Exclusion or Inclusion rule is set for this power, then use the DEFAULT as determined previously
prefixDef[P]['incl'] = DEFAULT;
}
else {
// If both an Exclusion and an Inclusion rule are set for this power
if (EX['state'] == IN['state']) {
// Check if they are opposing rules (i.e. Exclude and Include are both true, or both false)
if (IN['blanket'] && EX['blanket']) {
// If both rules are established by blanket statements, the DEFAULT (as determined previously) takes precedence.
// This implicitly means both are set to true, because blanket statements can only set things true
prefixDef[P]['incl'] = DEFAULT;
}
else if (IN['blanket']) {
// If the Inclusion rule is established by a blanket statement, but the Exclusion rule is stated explicitly, the Exclusion rule takes precedence
// This implicitly means both are set to true, because blanket statements can only set things true
prefixDef[P]['incl'] = !EX['state'];
}
else if (EX['blanket']) {
// If the Exclusion rule is established by a blanket statement, but the Inclusion rule is stated explicityly, the Inclusion rule takes precedence
// This implicitly means both are set to true, because blanket statements can only set things true
prefixDef[P]['incl'] = IN['state'];
}
else {
// If neither of the rules are established by blanket statements
// Could be either both true or both false; DEFAULT takes precedence (as determined previously)
prefixDef[P]['incl'] = DEFAULT;
}
}
else {
// Rules are not conflicting; set to match Inclusion rule or !Exclusion rule (either works)
prefixDef[P]['incl'] = IN['state'];
}
}
if (P == -2 || P == -1 || P == 1 || P == 2) {
// These powers (centi, deci, deca, and hecto) are excluded automatically
prefixDef[P]['incl'] = false;
if (P in ex_in_table[1]) {
// Include them if and only if the user makes an explicity Inclusion rule for them
if (ex_in_table[1][P]['state'] == true && ex_in_table[1][P]['blanket'] == false) {
prefixDef[P]['incl'] = true;
}
}
}
if (P == 0) {
prefixDef[P]['incl'] = true;
if (P in ex_in_table[0]) {
if (ex_in_table[0][P]['state'] == true) {
prefixDef[P]['incl'] = false;
}
}
}
}
DEBUG('Final Result:', prefixDef);
return prefixDef;
}
function SI_set_options(options_input, prefixDef, pre2num) {
//var opt = ['p', 'output', 'separator', 'decimal', 'unit_sep', 'big_kilo', 'no_mu'];
// Loop through all options, if specified by options_input, replace the default
/*for (var i = 0; i < opt.length; i++) {
if (opt[i] in options_input) {
SI_options[opt[i]] = options_input[opt[i]];
}
}*/
//var explicit_incl = [];
//var arg;
//var offset;
prefixDef = SI_include_exclude(options_input, prefixDef, pre2num);
/*
if (!('exclude' in options_input)) {
DEBUG('options_input contained no exclusions');
}
if (typeof(options_input['exclude']) == 'string') {
DEBUG('(SI_options == string) returns true');
}
else if (typeof(options_input['exclude']) == 'object') {
DEBUG('(SI_options == object) returns true');
// First pass, loops through [exclude] list provided in the input options, to check for any prefixes declared as Explicitly Included, with '!'
for (var i = 0; i < options_input['exclude'].length; i++) {
arg = options_input['exclude'][i];
if (isNaN(parseInt(arg[0]))) {
// If arg[0] is !, add arg[1] to the list of explicitly included prefixes
if (arg[0] == '!' && pre2num[arg[1]] in prefixDef) {
explicit_incl.push(arg[1]);
}
}
}
DEBUG('Explicit inclusions:', explicit_incl);
// Second pass, loops through [exclude] list to look for '*', which excludes all prefixes except the ones on the explicit_incl list.
for (var i = 0; i < options_input['exclude'].length; i++) {
arg = options_input['exclude'][i];
if (isNaN(parseInt(arg[0]))) {
if (arg[0] == '*') {
// If arg[0] is *, then exclude all prefixes except those explicitly included
for (var j = -24; j <= 24; j++ ) {
if (j in prefixDef) {
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
SI_options['exclude'].push(prefixDef[j]['sym']);
DEBUG('Prefix "' + prefixDef[j]['sym'] + '" excluded');
DEBUG(prefixDef[j]['sym'] + ' not in explicit_incl: ' + !(prefixDef[j]['sym'] in explicit_incl));
}
}
}
break;
}
}
}
// Third pass, loops through [exclude] list again, to expand all shortcuts like ">=G" into "[G, T, P, E ... ]"
for (var i = 0; i < options_input['exclude'].length; i++) {
arg = options_input['exclude'][i];
if (isNaN(parseInt(arg[0]))) {
if (arg[0] == '>') {
if (arg[1] == '=') { offset = 0; DEBUG('Offset set to 0') } // If command is ">=", offset 0 to include starting position.
else { offset = 1; } // Otherwise, command is ">", offset 1 to not include the specified prefix
for (var j = pre2num[arg[1 + (1-offset)]] + offset; j <= 24; j++) {
DEBUG('J:', j);
if (j in prefixDef) {
// Check to make sure it hasn't been explicitly included (present in explicit_incl list) or duplicate (present in SI[exclude])
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
// Exclude prefixes at/above the prefix specified by arg[1]
SI_options['exclude'].push(prefixDef[j]['sym']);
}
}
}
}
else if (arg[0] == '<') {
if (arg[1] == '=') { offset = 0; } // If command is "<=", offset 0
else { offset = 1; } // Otherwise, command is "<", offset 1 to include the specified prefix
for (var j = pre2num[arg[1 + (1-offset)]] - offset; j >= -24; j--) {
if (j in prefixDef) {
// Check to make sure it hasn't been explicitly included (present in explicit_incl list) or duplicate (present in SI[exclude])
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
// Exclude prefixes at/below the prefix specified by arg[1]
SI_options['exclude'].push(prefixDef[j]['sym']);
}
}
}
}
else {
j = pre2num[arg[0]];
if (j in prefixDef) {
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
SI_options['exclude'].push(prefixDef[j]['sym']);
}
}
}
}
}
}
*/
return [prefixDef, options_input];
}
function SI_set_precision(SI_options, prefixDef, pre2num) {
/*
for (var i = 0; i < SI_options['exclude'].length; i++) {
//prefixDef[pre2num[SI_options['exclude'][i]]]['excl'] = true;
// Delete prefixes that have been excluded
delete prefixDef[pre2num[SI_options['exclude'][i]]];
}*/
DEBUG('Beginning Set-Precision')
var precision = SI_options['p'];
DEBUG('typeof(precision):', typeof(precision));
// If the precision argument is a string, then there is only 1 precision specified
if (typeof(precision) == 'number') {
precision = precision.toString();
}
if (typeof(precision) == 'string') {
DEBUG('Precision is a string:', precision);
// If it's a 1-character string, then it's a pure number, which means it is set as the default for all prefixes
if (precision.length == 1) {
for (var i = prefixDef['_min']; i <= prefixDef['_max']; i++) {
if (i.toString() in prefixDef) {
//DEBUG('prefixDef["' + i.toString() + '"] set to:', precision)
prefixDef[i.toString()]['p'] = precision;
}
}
}
// If it's a 2-character string, it could be a 2 digit number or a prefix-specific code
else if (precision.length == 2) {
if (isNaN(parseInt(precision[0]))) {
prefixDef[pre2num[precision[0]]]['p'] = parseInt(precision[1]);
}
}
}
else if (typeof(precision) == 'object') {
DEBUG('Precision is an object:', precision);
for (var j = 0; j < precision.length; j++) {
precision[j] = precision[j].toString();
if ((precision[j]).length == 1) {
DEBUG('Default precision rule detected:', precision[j])
for (var i = prefixDef['_min']; i <= prefixDef['_max']; i++) {
if (i.toString() in prefixDef) {
prefixDef[i.toString()]['p'] = parseInt(precision[j]);
}
}
}
// If it's a 2-character string, it could be a 2 digit number or a prefix-specific code
else if (precision[j].length == 2) {
DEBUG('Specific precision rule detected:', precision[j])
if (!isNum(precision[j][0]) && (pre2num[precision[j][0]] in prefixDef)) {
prefixDef[pre2num[precision[j][0]]]['p'] = parseInt(precision[j][1]);
}
}
}
}
DEBUG('prefixDef:', prefixDef);
return prefixDef
}

@ -0,0 +1,194 @@
/* Detailed descriptions for specifications */
/*
$('#results_container > table > tr').each(function() {
//this.classList.remove('selected');
this.on('click', selectRow(this[0].id));
})*/
var results_selectedRow = '';
function selectRow(row) {
previousRow = results_selectedRow || '';
if (previousRow != '') { deselectRow(); }
if (previousRow != row) {
row.classList.add('selected');
results_selectedRow = row;
$('#results_explanation').html(Detailed_Explanation[row.id]);
}
}
function deselectRow() {
results_selectedRow = results_selectedRow || '';
if (results_selectedRow != '') {
results_selectedRow.classList.remove('selected');
results_selectedRow = '';
}
}
document.addEventListener('click', function(event) {
if (!(document.getElementById('results_container').contains(event.target))) { deselectRow(); }
});
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape' || event.keyCode === 27) { deselectRow(); $('#results_explanation').html('Click specifications for details'); }
});
var Detailed_Explanation = {
'results_data_transmission':
'',
'results_data_rate':
'The <b>data rate</b> is the amount of data per second sent across the video interface, generally represented in bits per second.<br><br>'+
'Data rate for uncompressed RGB video is calculated as:' +
'<div class="inline_math">(bits per pixel)&nbsp;&times;&nbsp;(pixels per frame)&nbsp;&times;&nbsp;(frames per second)</div>where,' +
'<ul><li><b>Bits per pixel</b> is 3 times the color depth per channel or per component</li>' +
'<li><b>Pixels per frame</b> is the effective number of total pixels (horizontal resolution times vertical resolution), including both active and blank pixels</li>' +
'<li><b>Frames per second</b> is the vertical refresh frequency (for progressive scan) or half the vertical field rate (for interlaced scan)</li></ul>' +
'The data rate for YC<sub>B</sub>C<sub>R</sub> 4:4:4 video is the same as RGB. ' +
'For YC<sub>B</sub>C<sub>R</sub> 4:2:2 video, the data rate is divided by 1.5. For YC<sub>B</sub>C<sub>R</sub> 4:2:0 the data rate is divided by 2.<br><br>' +
'The total <b>bandwidth</b> required for video transmission is larger than the data rate, due to additional overhead involved with transmission.',
'results_bit_rate':
'The <b>bandwidth</b> is the number of physical bits per second transmitted across the video interface, generally represented in bits per second.<br><br>' +
'The bandwidth required for video transmission is larger than the data rate. In addition to the bits required to represent the data payload, there is also additional overhead (extra bits beyond just the raw data ' +
'which must be signaled across the interface.',
'results_8b10b':
'The 8b/10b encoding scheme requires 10 bits of bandwidth to represent 8 bits of data. Therefore, the bandwidth required to send data ' +
'at a certain rate is 125% of the desired data rate.',
'results_16b18b':
'The 16b/18b encoding scheme requires 18 bits of bandwidth to represent 16 bits of data. Therefore, the bandwidth required to send data ' +
'at a certain rate is 112.5% of the desired data rate.',
'results_char_rate':
'The <b>character rate</b> is a value associated with HDMI and DVI. It is the number of TMDS characters transmitted across the interface per channel per second.<br><br>' +
'A "TMDS character" is a group of 10 bits (8 bits of data, 2 bits for DC balancing). Therefore, the character rate is an alternate way of expressing total bandwidth or data rate. ' +
'HDMI has 3 channels, so the data rate (in Mbit/s) is equal to the character rate (in MHz) times 24 bits (or 3 × 8 bits).<br><br>' +
'DVI and HDMI 1.01.2 only supported 8&nbsp;bpc RGB color*. In this system, each pixel is represented by 24 bits of data, ' +
'so the TMDS character rate also happens to be equal to the number of pixels per second. ' +
'For this reason, the term "pixel clock" is often used to refer to the character rate. However, they are only the same value in certain cases. ' +
'is often informally referred to as the "Pixel Clock". However, this relationship is only true ' +
'when using 8&nbsp;bpc color depth. actual pixel clock may be a different value when not using 8&nbsp;bpc color depth.<br><br>' +
'In HDMI, the character rate is the number of TMDS characters transmitted across a single data channel per second. This is sometimes informally referred to as the "TMDS clock" or "Pixel Clock", because these values were all equal in older versions of HDMI. ' +
'However, this is no longer the case.<br><br>A TMDS character is a group of 10 bits. 8 of the bits represent data, and the remaining 2 bits are used for DC balancing. HDMI versions 1.01.4 have three data channels, and transmit one TMDS character per TMDS clock cycle on each channel. ' +
'This results in a total of 30 bits (24 bits of data) transmitted per TMDS clock cycle.<br><br>With standard 8&nbsp;bpc (24&nbsp;bit/px) color depth, this is exactly one pixel of data. Thus, the TMDS clock rate, character rate, and pixel clock all have the same value. ' +
'With the introduction of Deep Color (30&nbsp;bit/px, 36&nbsp;bit/px, and 48&nbsp;bit/px color depth) in HDMI&nbsp;1.3, this is no longer the case, and the actual pixel clock will be lower than the character rate and TMDS clock rate.<br><br>' +
'In addition, the HDMI&nbsp;2.0 specifies that character rates above 340&nbsp;MHz will use a lower TMDS clock frequency and transmit 4 TMDS characters per clock cycle per channel instead of one. In these cases, the character rate is no longer equal to the TMDS clock.<br><br>' +
'HDMI 1.01.2 support a maximum character rate of 165&nbsp;MHz<br>' +
'HDMI 1.31.4 support a maximum character rate of 340&nbsp;MHz<br>' +
'HDMI 2.0 supports a maximum character rate of 600&nbsp;MHz<br>' +
'HDMI 2.1 uses a much different system with 4 data channels, and 16 bits of data per 18 bits transmitted',
'results_pixel_rate':
'',
'results_pixel_rate_active':
'',
'results_resolution':
'',
'results_active_px':
'',
'results_blank_px':
'',
'results_total_px':
'',
'results_overhead_px':
'',
'results_format':
'',
'results_bpc':
'',
'results_bpp':
'',
'results_palette':
'',
'results_px_format':
'',
'results_scan':
'',
'results_v_refresh':
'',
'results_v_freq':
'',
'results_v_freq_actual':
'',
'results_v_freq_dev':
'',
'results_v_freq_dev_perc':
'',
'results_v_per':
'',
'results_v_per_actual':
'',
'results_v_per_dev':
'',
'results_v_per_dev_perc':
'',
'results_v_refresh_int':
'',
'results_v_field':
'',
'results_v_field_dev':
'',
'results_v_field_dev_perc':
'',
'results_v_framerate':
'',
'results_v_framerate_actual':
'',
'results_v_framerate_dev':
'',
'results_v_framerate_dev_perc':
'',
'results_v_field_per':
'',
'results_v_field_per_actual':
'',
'results_v_field_per_dev':
'',
'results_v_field_per_dev_perc':
'',
'results_h_refresh':
'',
'results_h_freq':
'',
'results_h_per':
'',
}

@ -1,10 +1,25 @@
DebugConfig({
//all: true,
calcMain: 0,
submitVar: 0,
input_ok: 0,
updateDisplay: 0,
getTiming: 0,
marginsUIChange: 0,
timingUIChange: 0,
generate_table: 0,
SI: 1,
SI_set_options: 1,
SI: 0,
SI_include_exclude: 0,
SI_set_options: 0,
SI_set_precision: 0,
timingUIChange: 1,
CTA: 0,
DMT: 0,
CVT: 0,
CVT_R: 0,
GTF: 0,
});
@ -29,6 +44,13 @@ Global_InputVars = {
'H_FP': '',
'H_BP': '',
'H_SW': '',
'V_FP_INT': '',
'V_BP_INT': '',
'V_SW_INT': '',
}
Detailed_Results = {
}
@ -214,28 +236,37 @@ function submitVar(id, val) {
DEBUG("Global_InputVars['" + GlobalVars_Key + "'] was set to", Global_InputVars[GlobalVars_Key]);
timingUIChange();
if (val != 'Custom' && val != 'None') {
if (Global_InputVars['HRES'] == '' || Global_InputVars['VRES'] == '' || Global_InputVars['FREQ'] == '') {
$('#TIMING_FORMAT_NAME').html('');
clearTiming();
}
}
}
else if (id == 'V_FP' || id == 'V_BP' || id == 'V_SW' ||
id == 'H_FP' || id == 'H_BP' || id == 'H_SW' ||
id == 'V_FP_INT' || id == 'V_SW_INT' || id == 'V_BP_INT') {
GlobalVars_Key = id;
val = parseFloat(parseNum(val));
//val = Math.abs(parseNum(val));
if (isNum(val)) {
val = Math.abs(val);
Global_InputVars[id] = val;
Global_InputVars[id] = Math.abs(val);
$('#' + id).val(val);
$('#V_BLANK').html(Global_InputVars['V_FP'] + Global_InputVars['V_BP'] + Global_InputVars['V_SW']);
$('#H_BLANK').html(Global_InputVars['H_FP'] + Global_InputVars['H_BP'] + Global_InputVars['H_SW']);
$('#V_BLANK_INT').html(Global_InputVars['V_FP_INT'] + Global_InputVars['V_BP_INT'] + Global_InputVars['V_SW_INT']);
if (Global_InputVars['V_FP'] != '' && Global_InputVars['V_BP'] != '' && Global_InputVars['V_SW'] != '') {
$('#V_BLANK').html(Global_InputVars['V_FP'] +Global_InputVars['V_BP'] + Global_InputVars['V_SW']); }
if (Global_InputVars['H_FP'] != '' && Global_InputVars['H_BP'] != '' && Global_InputVars['H_SW'] != '') {
$('#H_BLANK').html(Global_InputVars['H_FP'] + Global_InputVars['H_BP'] + Global_InputVars['H_SW']); }
if (Global_InputVars['V_FP_INT'] != '' && Global_InputVars['V_BP_INT'] != '' && Global_InputVars['V_SW_INT'] != '') {
$('#V_BLANK_INT').html(Global_InputVars['V_FP_INT'] + Global_InputVars['V_BP_INT'] + Global_InputVars['V_SW_INT']); }
}
else {
DEBUG(id + ' input is not a number:', val);
Global_InputVars[id] = '';
$('#' + id).val('');
$('#V_BLANK').html('');
$('#H_BLANK').html('');
$('#V_BLANK_INT').html('');
if (id == 'V_FP' || id == 'V_BP' || id == 'V_SW') { $('#V_BLANK').html(''); }
if (id == 'H_FP' || id == 'H_BP' || id == 'H_SW') { $('#H_BLANK').html(''); }
if (id == 'V_FP_INT' || id == 'V_SW_INT' || id == 'V_BP_INT') { $('#V_BLANK_INT').html(''); }
}
DEBUG("Global_InputVars['" + GlobalVars_Key + "'] was set to", Global_InputVars[GlobalVars_Key]);
@ -319,6 +350,11 @@ function input_ok() {
}
}
if (!isNum(Global_InputVars['COLOR_DEPTH'])) {
var abort = true;
DEBUG('Calculation aborted. Color Depth has not yet been defined.');
return false;
}
if ($('input[name=COLOR_DEPTH_SLCT]:checked').val() == 'Custom') {
val = Global_InputVars['COLOR_DEPTH'];
if (!(isPositive(val))) {
@ -327,7 +363,18 @@ function input_ok() {
}
}
if (Global_InputVars['TIMING_STD'] == 'Custom') {
if (Global_InputVars['PIXEL_FORMAT'] == '') {
var abort = true;
DEBUG('Calculation aborted. Pixel Format has not yet been defined.');
return false;
}
if (Global_InputVars['TIMING_STD'] == '') {
var abort = true;
DEBUG('Calculation aborted. Timing Standard has not yet been defined.');
return false;
}
else if (Global_InputVars['TIMING_STD'] == 'Custom') {
checklist = ['V_FP', 'V_BP', 'V_SW', 'H_FP', 'H_BP', 'H_SW'];
var abort = false;
for (var i = 0; i < checklist.length; i++) {
@ -342,6 +389,23 @@ function input_ok() {
}
}
if (!isNum(Global_InputVars['COMP'])) {
var abort = true;
DEBUG('Calculation aborted. COMPRESSION has not yet been defined.');
return false;
}
if (!isNum(Global_InputVars['SCAN'])) {
var abort = true;
DEBUG('Calculation aborted. SCAN TYPE has not yet been defined.');
return false;
}
if (!isNum(Global_InputVars['MARGINS'])) {
var abort = true;
DEBUG('Calculation aborted. Margins have not yet been defined.');
return false;
}
if ($('input[name=MARGINS_SLCT]:checked').val() == 'y') {
val = Global_InputVars['MARGINS'];
if (!(isPositiveZ(val))) {
@ -355,6 +419,28 @@ function input_ok() {
function calcMain() {
/*
if(Global_InputVars['HRES'] == '') { submitVar('INPUT_HRES') }
if(Global_InputVars['VRES'] == '') { submitVar('INPUT_VRES') }
if(Global_InputVars['FREQ'] == '') { submitVar('INPUT_F') }
if(Global_InputVars['COLOR_DEPTH'] == '') { submitVar('COLOR_DEPTH_FORM') }
if(Global_InputVars['PIXEL_FORMAT'] == '') { submitVar('PIXEL_FORMAT_FORM') }
if(Global_InputVars['COMP'] == '') { submitVar('COMPRESSION_FORM') }
if(Global_InputVars['SCAN'] == '') { submitVar('SCAN_FORM') }
if(Global_InputVars['MARGINS'] == '') { submitVar('MARGINS_FORM') }
if(Global_InputVars['TIMING_STD'] == '') { submitVar('TIMING_DROP') }
if(Global_InputVars['V_FP'] == '') { submitVar('V_FP') }
if(Global_InputVars['V_BP'] == '') { submitVar('V_BP') }
if(Global_InputVars['V_SW'] == '') { submitVar('V_SW') }
if(Global_InputVars['H_FP'] == '') { submitVar('H_FP') }
if(Global_InputVars['H_BP'] == '') { submitVar('H_BP') }
if(Global_InputVars['H_SW'] == '') { submitVar('H_SW') }
if(Global_InputVars['V_FP_INT'] == '') { submitVar('V_FP_INT') }
if(Global_InputVars['V_BP_INT'] == '') { submitVar('V_BP_INT') }
if(Global_InputVars['V_SW_INT'] == '') { submitVar('V_SW_INT') }
*/
if (!input_ok()) { clearResults(); return; }
var hres = Global_InputVars['HRES'];
@ -372,6 +458,11 @@ function calcMain() {
if (!Timing) { clearResults(); return; } // Abort if getTiming returns false, it indicates the format is not defined for that timing standard.
DEBUG('Timing:', Timing);
var h_eff = Timing['H_EFF']
var v_eff = Timing['V_EFF'] * scan
var freq_act = Timing['F_ACTUAL'];
/*
var results = {
hres: hres,
vres: vres,
@ -406,10 +497,146 @@ function calcMain() {
// Raw bit rate
bits_per_sec_eff: (Timing['H_EFF']) * (Timing['V_EFF']) * color_depth * Timing['F_ACTUAL'],
};
};*/
Detailed_Results['data_rate'] = SI(
(h_eff * v_eff * freq_act * color_depth / px_format / scan / comp),
'bit/s',
{'p':2, 'output':'split'},
);
Detailed_Results['8b10b'] = SI(
(h_eff * v_eff * freq_act * color_depth / px_format / scan / comp) * (1.25),
'bit/s',
{'p':2, 'output':'split'},
);
Detailed_Results['16b18b'] = SI(
(h_eff * v_eff * freq_act * color_depth / px_format / scan / comp) * (1.125),
'bit/s',
{'p':2, 'output':'split'},
);
Detailed_Results['pixel_rate'] = SI(
(h_eff * v_eff * freq_act / scan),
'px/s',
{'p':[3, 'b1', 'k1', 'M1'], 'output':'split'},
);
Detailed_Results['pixel_rate_active'] = SI(
(hres * vres * freq_act / scan),
'px/s',
{'p':[3, 'b1', 'k1', 'M1'], 'output':'split'},
);
Detailed_Results['active_px'] = {
'h': hres,
'v': vres,
't': SI(hres * vres, 'px', {'p':0, 'output':'split', 'include': ['b']}),
}
Detailed_Results['blank_px'] = {
'h': h_eff - hres,
'v': v_eff - vres,
't': SI((h_eff * v_eff) - (hres * vres), 'px', {'p':0, 'output':'split', 'include': ['b']}),
}
Detailed_Results['total_px'] = {
'h': h_eff,
'v': v_eff,
't': SI(h_eff * v_eff, 'px', {'p':0, 'output':'split', 'exclude': ['<B', '>B']}),
}
DEBUG('Results:', SI(results['bits_per_sec_eff'], 'bit/s', 2), results);
updateDisplay(results);
Detailed_Results['overhead_px'] = {
'h': SI(100 * ((h_eff / hres) - 1), '%', {'p':2, 'output':'split', 'exclude': ['<B', '>B']}),
'v': SI(100 * ((v_eff / vres) - 1), '%', {'p':2, 'output':'split', 'exclude': ['<B', '>B']}),
't': SI(100 * (((h_eff * v_eff) / (hres * vres)) - 1), '%', {'p':2, 'output':'split', 'exclude': ['<B', '>B']}),
}
if ($('input[name=COLOR_DEPTH_SLCT]:checked').val() == 'Custom') {
if (color_depth % 3 == 0) { Detailed_Results['bpc'] = { 'val': color_depth / 3, 'unit':'bpc' }; }
else { Detailed_Results['bpc'] = { 'val': '-', 'unit': '' }; }
}
else {
Detailed_Results['bpc'] = { 'val': color_depth / 3, 'unit':'bpc' }
}
Detailed_Results['bpp'] = { 'val': color_depth, 'unit': 'bit/px' };
Detailed_Results['palette'] = SI(Math.pow(2, color_depth), 'colors', {'p':0, 'output':'split', 'include':['b']});
if ($('input[name=PX_FORMAT_SLCT]:checked').val() == 'RGB') { Detailed_Results['px_format'] = 'RGB'; }
else if ($('input[name=PX_FORMAT_SLCT]:checked').val() == 'YCBCR 4:4:4') { Detailed_Results['px_format'] = 'YC<sub>B</sub>C<sub>R</sub> 4:4:4'; }
else if ($('input[name=PX_FORMAT_SLCT]:checked').val() == 'YCBCR 4:2:2') { Detailed_Results['px_format'] = 'YC<sub>B</sub>C<sub>R</sub> 4:2:2'; }
else if ($('input[name=PX_FORMAT_SLCT]:checked').val() == 'YCBCR 4:2:0') { Detailed_Results['px_format'] = 'YC<sub>B</sub>C<sub>R</sub> 4:2:0'; }
if (scan == 1) { Detailed_Results['scan'] = 'Progressive'; }
if (scan == 2) { Detailed_Results['scan'] = 'Interlaced'; }
Detailed_Results['v_freq'] = SI(
freq,
'Hz',
{'p':3, 'output':'split', 'include':['>=b']},
);
Detailed_Results['v_freq_actual'] = SI(
Timing['F_ACTUAL'],
'Hz',
{'p':3, 'output':'split', 'include':['>=b']},
);
DEBUG('freq:', typeof(freq), freq)
DEBUG('f_actual', typeof(Timing['F_ACTUAL']), Timing['F_ACTUAL'])
DEBUG('f - fa', freq - Timing['F_ACTUAL'])
Detailed_Results['v_freq_dev'] = SI(
Math.abs(freq - Timing['F_ACTUAL']),
'Hz',
{'p':6, 'output':'split', 'include':['>=b']},
);
Detailed_Results['v_freq_dev_perc'] = SI(
Math.abs(100 * ((freq - Timing['F_ACTUAL']) / freq)),
'%',
{'p':6, 'output':'split', 'include':['b']},
);
Detailed_Results['v_per'] = SI(
1 / freq,
's',
{'p':3, 'output':'split', 'include':['<=b']},
);
Detailed_Results['v_per_actual'] = SI(
1 / Timing['F_ACTUAL'],
's',
{'p':3, 'output':'split', 'include':['<=b']},
);
Detailed_Results['v_per_dev'] = SI(
Math.abs((1 / freq) - (1 / Timing['F_ACTUAL'])),
's',
{'p':3, 'output':'split', 'include':['<=b']},
);
Detailed_Results['v_per_dev_perc'] = SI(
Math.abs(100 * ((1 / freq) - (1 / Timing['F_ACTUAL'])) / (1 / freq)),
'%',
{'p':6, 'output':'split', 'include':['b']},
);
Detailed_Results['h_freq'] = SI(
(v_eff * Timing['F_ACTUAL']) / scan,
'Hz',
{'p':3, 'output':'split', 'include':['>=b']},
);
Detailed_Results['h_per'] = SI(
scan / (v_eff * Timing['F_ACTUAL']),
's',
{'p':3, 'output':'split', 'include':['<=b']},
);
//DEBUG('Results:', SI(results['bits_per_sec_eff'], 'bit/s', 2), results);
updateDisplay();
}
@ -438,28 +665,56 @@ function getTiming(timing_standard) {
};
}
DEBUG('Timing Standard:', timing_standard)
if (timing_standard != 'Custom') {
if (timing_standard == 'CVT-R2') {
DEBUG('Fetching CVT-R2 Timing...')
Timing = CVT_R(2);
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR'] + '-R');
if (!Timing) {
DEBUG ('CVT-R2 calculation error.');
clearTiming();
return false; }
else {
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR'] + '-R');
}
}
else if (timing_standard == 'CVT-RB') {
Timing = CVT_R(1);
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR'] + '-R');
if (!Timing) {
DEBUG ('CVT-RB calculation error.');
$('#TIMING_FORMAT_NAME').html('');
clearTiming();
return false; }
else {
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR'] + '-R');
}
}
else if (timing_standard == 'CVT') {
Timing = CVT();
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR']);
if (!Timing) {
DEBUG ('CVT calculation error.');
$('#TIMING_FORMAT_NAME').html('');
clearTiming();
return false; }
else {
$('#TIMING_FORMAT_NAME').html('<b>VESA Name:</b> ' + (Global_InputVars['HRES'] * Global_InputVars['VRES'] / 1000000).toFixed(2) + 'M' + Timing['VESA_AR']);
}
}
else if (timing_standard == 'GTF') {
Timing = GTF();
$('#TIMING_FORMAT_NAME').html('');
if (!Timing) {
DEBUG ('GTF calculation error.');
clearTiming();
return false;
}
}
else if (timing_standard == 'DMT') {
Timing = DMT();
if (!Timing) {
DEBUG ('Not a DMT Format. DMT Function returned false.');
$('#TIMING_FORMAT_NAME').html('');
$('#TIMING_FORMAT_NAME').html('Not a DMT format');
clearTiming();
return false; }
else {
$('#TIMING_FORMAT_NAME').html('<b>DMT ID:</b> ' + Timing['ID']);
@ -469,7 +724,8 @@ function getTiming(timing_standard) {
Timing = CTA();
if (!Timing) {
DEBUG ('Not a CTA Format. CTA Function returned false.');
$('#TIMING_FORMAT_NAME').html('');
$('#TIMING_FORMAT_NAME').html('Not a CTA format');
clearTiming();
return false; }
else {
$('#TIMING_FORMAT_NAME').html('<b>CTA VIC:</b> ' + Timing['VIC']);
@ -554,6 +810,20 @@ function getTiming(timing_standard) {
}
function clearTiming() {
submitVar('V_FP', '');
submitVar('V_BP', '');
submitVar('V_SW', '');
submitVar('H_FP', '');
submitVar('H_BP', '');
submitVar('H_SW', '');
submitVar('V_FP_INT', '');
submitVar('V_SW_INT', '');
submitVar('V_BP_INT', '');
return;
}
function CVT_R(R) { // Variable R is an integer representing the reduced blanking revision to use, version 1 or version 2.
var H = Global_InputVars['HRES']; // Horizontal active pixels
var V = Global_InputVars['VRES']; // Vertical active pixels
@ -618,6 +888,7 @@ function CVT_R(R) { // Variable R is an integer representing the reduced blankin
var G = 8; // Cell granularity constant defined by CVT standard
var H_RND = Math.floor(H / G) * G; // Round down horizontal resolution to be a multiple 8
if (H_RND <= 0) { return false; }
var V_MARGIN = Math.floor(M / 100) * V_LINES; // If margins percent (M) is 0, this result is 0
var H_MARGIN = Math.floor(H_RND * M / 100 / G) * G; // If margins percent (M) is 0, this result is 0
@ -750,6 +1021,7 @@ function CVT() {
var G = 8; // Cell Granularity constant
var H_RND = Math.floor(H / G) * G;
if (H_RND <= 0) { return false; }
var V_MARGIN = Math.floor(M / 100 * V_LINES); // If margins percent (M) is 0, this result is 0
var H_MARGIN = Math.floor(H_RND * M / 100 / G) * G; // If margins percent (M) is 0, this result is 0
var H_SYNC_TARGET_WIDTH = 0.08 // Nominal horizontal sync pulse duration (percent of horizontal draw period)
@ -1070,6 +1342,81 @@ function DMT() {
function updateDisplay() {
var cells;
var id;
id_list = ['data_rate', '8b10b', '16b18b', 'pixel_rate', 'pixel_rate_active'];
for (var x = 0; x < id_list.length; x++) {
id = id_list[x];
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]['val'];
cells[2].innerHTML = Detailed_Results[id]['unit'];
}
id_list = ['active_px', 'blank_px', 'total_px'];
for (var x = 0; x < id_list.length; x++) {
id = id_list[x];
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]['h'];
cells[2].innerHTML = Detailed_Results[id]['v'];
cells[3].innerHTML = Detailed_Results[id]['t']['val'];
cells[4].innerHTML = Detailed_Results[id]['t']['unit'];
}
id = 'overhead_px';
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]['h']['val'];
cells[2].innerHTML = Detailed_Results[id]['v']['val'];
cells[3].innerHTML = Detailed_Results[id]['t']['val'];
cells[4].innerHTML = Detailed_Results[id]['t']['unit'];
id_list = ['bpc', 'bpp', 'palette'];
for (var x = 0; x < id_list.length; x++) {
id = id_list[x];
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]['val'];
cells[2].innerHTML = Detailed_Results[id]['unit'];
}
id = 'px_format';
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]
id = 'scan';
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]
id_list = ['v_freq', 'v_freq_actual', 'v_freq_dev', 'v_freq_dev_perc', 'v_per', 'v_per_actual', 'v_per_dev', 'v_per_dev_perc'];
for (var x = 0; x < id_list.length; x++) {
id = id_list[x];
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]['val'];
cells[2].innerHTML = Detailed_Results[id]['unit'];
}
id_list = ['h_freq', 'h_per'];
for (var x = 0; x < id_list.length; x++) {
id = id_list[x];
cells = $('#results_' + id).children();
DEBUG('Detailed Results:', Detailed_Results[id]);
DEBUG('Cells:', cells)
cells[1].innerHTML = Detailed_Results[id]['val'];
cells[2].innerHTML = Detailed_Results[id]['unit'];
}
return;
}
@ -1087,6 +1434,9 @@ function timingUIChange() {
$('#H_FP'),
$('#H_BP'),
$('#H_SW'),
$('#V_FP_INT'),
$('#V_BP_INT'),
$('#V_SW_INT'),
];
value = $('#TIMING_DROP').val();
if (value == 'Custom') {
@ -1163,299 +1513,6 @@ function marginsUIChange() {
}
function SI(value, unit, options_input) {
DEBUG('Input:', value, unit, options_input);
if (isNaN(parseInt(value))) { return value; }
if (typeof(options_input) == 'number' || typeof(options_input) == 'string') { options_input = {p: options_input.toString()}; }
/* Valid options:
SI_options = {
p: 2 Specifies default precision (number of decimal places). Use '-1' or 'a' or 'adaptive' for adaptive mode (autodetect decimal places)
Also accepts individual decimal place settings for each prefix, in array format; for example:
{p: [1, G2, M0]} sets a default of 1 for all prefixes, then specifies 2 decimal places for Giga and 0 for Mega.
p_max: 4 Maximum number of decimal places (for adaptive precision mode)
p_min: 2 Minimum number of decimal places (for adaptive precision mode)
separator: ',' Character to use as thousands separator (default comma)
decimal: '.' Character to use as decimal point (default period)
unit_sep: '&nbsp;' Character to place between the value and unit symbol (default non-breaking space)
cap_kilo: 'true' Use capital K for kilo instead of small k. (default false)
no_mu: 'true' Use "u" instead of "µ" on output, if necessary for compatibility reasons (default false)
exclude: ['c', 'd'] SI prefixes to exclude, for situational use (i.e. for displaying time, one may not wish for "centiseconds").
Symbols can also be used as shortcuts, as in the following examples:
'>=G' excludes Giga and larger
'>G' excludes larger than Giga, but not Giga itself
'<G' and "<=G" same as above, but for prefixes smaller than Giga
'*' excludes all prefixes (unless protected)
'!G' protects a prefix from '*', i.e. {exclude: ['*', '!k', '!M']} excludes all prefixes except Kilo and Mega)
Multiple arguments accepted in array format
"u" is accepted as an argument for excluding "µ", and "0" is accepted for excluding the prefixless base unit
By default, the following are excluded already, and must be un-excluded (using !c, !d, etc.) to be used:
'c' (centi, 10^-2)
'd' (deci, 10^-1)
'D' (deca, 10^1)
'H' (hecto, 10^2)
}
*/
//console.log(SI_options['precision']);
var out_value;
var out_prefix;
var precision;
var prefixDef = {
'-24': {sym:'y', name:'yocto', p: 0, excl: false},
'-21': {sym:'z', name:'zepto', p: 0, excl: false},
'-18': {sym:'a', name:'atto', p: 0, excl: false},
'-15': {sym:'f', name:'femto', p: 0, excl: false},
'-12': {sym:'p', name:'pico', p: 0, excl: false},
'-9': {sym:'n', name:'nano', p: 0, excl: false},
'-6': {sym:'µ', name:'micro', p: 0, excl: false},
'-3': {sym:'m', name:'milli', p: 0, excl: false},
'-2': {sym:'c', name:'centi', p: 0, excl: false},
'-1': {sym:'d', name:'deci', p: 0, excl: false},
'0': {sym:'', name:'', p: 0, excl: false},
'1': {sym:'D', name:'deca', p: 0, excl: false},
'2': {sym:'H', name:'hecto', p: 0, excl: false},
'3': {sym:'k', name:'kilo', p: 0, excl: false},
'6': {sym:'M', name:'mega', p: 0, excl: false},
'9': {sym:'G', name:'giga', p: 0, excl: false},
'12': {sym:'T', name:'tera', p: 0, excl: false},
'15': {sym:'P', name:'peta', p: 0, excl: false},
'18': {sym:'E', name:'exa', p: 0, excl: false},
'21': {sym:'Z', name:'zetta', p: 0, excl: false},
'24': {sym:'Y', name:'yotta', p: 0, excl: false},
};
var pre2num = {
'y': -24,
'z': -21,
'a': -18,
'f': -15,
'p': -12,
'n': -9,
'µ': -6,
'u': -6,
'm': -3,
'c': -2,
'd': -1,
'0': 0,
'D': 1,
'H': 2,
'k': 3,
'K': 3,
'M': 6,
'G': 9,
'T': 12,
'P': 15,
'E': 18,
'Z': 21,
'Y': 24,
}
SI_defaults = {
p: 2,
p_max: 8,
p_min: 0,
separator: ',',
decimal: '.',
unit_sep: '&nbsp;',
cap_kilo: false,
no_mu: false,
exclude: ['c', 'd', 'D', 'H'],
}
// Apply the default precision setting above
for (var i = -24; i <= 24; i++) {
if (i.toString() in prefixDef) {
prefixDef[i.toString()]['p'] = SI_defaults['p'];
}
}
//SI_options = Unpack_SI_options(SI_options, options_input);
var SI_options = SI_set_options(SI_defaults, options_input, prefixDef, pre2num);
//console.log(SI_options);
//console.log(options_input);
SI_options['p'] = options_input['p'];
//console.log('SI_options: ', SI_options);
prefixDef = SI_set_precision(SI_options, prefixDef, pre2num);
var magnitude = Math.floor(Math.log(value)/Math.log(10));
if (magnitude >= -24 && magnitude <= 24) {
// Change any inbetween magnitudes to one that has a prefix assigned to it
/*
if (!(magnitude in prefixDef)) {
magnitude = 3 * Math.floor(magnitude / 3);
}*/
while (!(magnitude in prefixDef)) {
magnitude--;
}
// Get the precision specified for that magnitude
precision = prefixDef[magnitude]['p'];
// Divide the number by the appropriate power of 10, and return the new number and associated SI prefix
out_value = Commas(Number(value / Math.pow(10, magnitude)).toFixed(precision));
out_prefix = prefixDef[magnitude]['sym'];
}
else {
out_value = Commas(value);
out_prefix = '';
}
return (out_value + '&nbsp;' + out_prefix + unit);
}
function SI_set_options(SI_options, options_input, prefixDef, pre2num) {
var opt = ['p', 'p_max', 'p_min', 'separator', 'decimal', 'unit_sep', 'cap_k', 'no_mu'];
// Loop through all options, if specified by options_input, replace the default
for (var i = 0; i < opt.length; i++) {
if (opt[i] in options_input) {
SI_options[opt[i]] = options_input[opt[i]];
}
}
var explicit_incl = [];
var arg;
var offset;
if (!('exclude' in options_input)) {
DEBUG('options_input contained no exclusions');
}
if (typeof(options_input['exclude']) == 'string') {
DEBUG('(SI_options == string) returns true');
}
else if (typeof(options_input['exclude']) == 'object') {
DEBUG('(SI_options == object) returns true');
// First pass, loops through [exclude] list provided in the input options, to check for any prefixes declared as Explicitly Included, with '!'
for (var i = 0; i < options_input['exclude'].length; i++) {
arg = options_input['exclude'][i];
if (isNaN(parseInt(arg[0]))) {
// If arg[0] is !, add arg[1] to the list of explicitly included prefixes
if (arg[0] == '!' && pre2num[arg[1]] in prefixDef) {
explicit_incl.push(arg[1]);
}
}
}
DEBUG('Explicit inclusions:', explicit_incl);
// Second pass, loops through [exclude] list to look for '*', which excludes all prefixes except the ones on the explicit_incl list.
for (var i = 0; i < options_input['exclude'].length; i++) {
arg = options_input['exclude'][i];
if (isNaN(parseInt(arg[0]))) {
if (arg[0] == '*') {
// If arg[0] is *, then exclude all prefixes except those explicitly included
for (var j = -24; j <= 24; j++ ) {
if (j in prefixDef) {
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
SI_options['exclude'].push(prefixDef[j]['sym']);
DEBUG('Prefix "' + prefixDef[j]['sym'] + '" excluded');
DEBUG(prefixDef[j]['sym'] + ' not in explicit_incl: ' + !(prefixDef[j]['sym'] in explicit_incl));
}
}
}
break;
}
}
}
// Third pass, loops through [exclude] list again, to expand all shortcuts like ">=G" into "[G, T, P, E ... ]"
for (var i = 0; i < options_input['exclude'].length; i++) {
arg = options_input['exclude'][i];
if (isNaN(parseInt(arg[0]))) {
if (arg[0] == '>') {
if (arg[1] == '=') { offset = 0; DEBUG('Offset set to 0') } // If command is ">=", offset 0 to include starting position.
else { offset = 1; } // Otherwise, command is ">", offset 1 to not include the specified prefix
for (var j = pre2num[arg[1 + (1-offset)]] + offset; j <= 24; j++) {
DEBUG('J:', j);
if (j in prefixDef) {
// Check to make sure it hasn't been explicitly included (present in explicit_incl list) or duplicate (present in SI[exclude])
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
// Exclude prefixes at/above the prefix specified by arg[1]
SI_options['exclude'].push(prefixDef[j]['sym']);
}
}
}
}
else if (arg[0] == '<') {
if (arg[1] == '=') { offset = 0; } // If command is "<=", offset 0
else { offset = 1; } // Otherwise, command is "<", offset 1 to include the specified prefix
for (var j = pre2num[arg[1 + (1-offset)]] - offset; j >= -24; j--) {
if (j in prefixDef) {
// Check to make sure it hasn't been explicitly included (present in explicit_incl list) or duplicate (present in SI[exclude])
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
// Exclude prefixes at/below the prefix specified by arg[1]
SI_options['exclude'].push(prefixDef[j]['sym']);
}
}
}
}
else {
j = pre2num[arg[0]];
if (j in prefixDef) {
if (explicit_incl.indexOf(prefixDef[j]['sym']) == -1 && !(prefixDef[j]['sym'] in SI_options['exclude'])) {
SI_options['exclude'].push(prefixDef[j]['sym']);
}
}
}
}
}
}
return SI_options;
}
function SI_set_precision(SI_options, prefixDef, pre2num) {
for (var i = 0; i < SI_options['exclude'].length; i++) {
//prefixDef[pre2num[SI_options['exclude'][i]]]['excl'] = true;
// Delete prefixes that have been excluded
delete prefixDef[pre2num[SI_options['exclude'][i]]];
}
var precision = SI_options['p'];
// If the precision argument is a string, then there is only 1 precision specified
if (typeof(precision) == 'string') {
// If it's a 1-character string, then it's a pure number, which means it is set as the default for all prefixes
if (precision.length == 1) {
for (var i = -24; i <= 24; i++) {
if (i.toString() in prefixDef) {
prefixDef[i.toString()]['p'] = precision;
}
}
}
// If it's a 2-character string, it could be a 2 digit number or a prefix-specific code
else if (precision.length == 2) {
if (isNaN(parseInt(precision[0]))) {
prefixDef[pre2num[precision[0]]]['p'] = parseInt(precision[1]);
}
}
}
else if (typeof(precision) == 'object') {
for (var j = 0; j < precision.length; j++) {
if (precision[j].length == 1) {
for (var i = -24; i <= 24; i++) {
if (i.toString() in prefixDef) {
prefixDef[i.toString()]['p'] = parseInt(precision[j]);
}
}
}
// If it's a 2-character string, it could be a 2 digit number or a prefix-specific code
else if (precision[j].length == 2) {
if (isNaN(parseInt(precision[j][0])) && (pre2num[precision[j][0]] in prefixDef)) {
prefixDef[pre2num[precision[j][0]]]['p'] = parseInt(precision[j][1]);
}
}
}
}
return prefixDef
}
function LoadCTA861(){
// Loads the timing definitions for the CTA-861 standard from a txt file
//DEBUG('CTA Test 11');
@ -1466,7 +1523,7 @@ function LoadCTA861(){
DEBUG('request.status:', request.status)
if (request.readyState === 4 && (request.status === 200 || request.status === 0)) {
CTA861 = $.csv.toObjects(request.responseText);
DEBUG(CTA861);
//DEBUG(CTA861);
}
}
DEBUG('Finished');
@ -1595,6 +1652,9 @@ function parseNum(val) {
}
else if (typeof val === 'string') {
// Empty string is interpreted as 0
if (val == '') { return 0; }
// First, remove all non-numeric characters on the outsides of the string
for (var i = 0; i < val.length; i++) {
if (!(i < val.length)) { break; }
@ -1603,13 +1663,13 @@ function parseNum(val) {
if ((/[^0-9.-]/g).test(val[i]) == true) {
// If character is not a number, period, or minus sign, remove it
if (i == 0 && val.length > 1) { val = val.slice(1); }
else if (i == val.length - 1) { return NaN; } // If this is the last character in the string
else if (i == val.length - 1) { return NaN; } // If this is the last character in the string, then there are no digits in the string; return NaN
else if (i > 0) { val = (val.slice(0, i)) + (val.slice(i+1));}
i = i - 1; // Since a character has been removed, the next character is now at the same index
continue;
}
else if ((/[-]/g).test(val[i]) == true) {
// If character is a negative sign, ignore it. This is because there may still be non-number characters between the negative sign and the first digit, such as "-$1.00". The negative sign should stay but the dollar needs to be removed.
// If character is a negative sign, continue searching without deleting it. This is because there may still be non-number characters between the negative sign and the first digit, such as "-$1.00". The negative sign should stay but the dollar needs to be removed.
continue;
}
else if ((/[.]/g).test(val[i]) == true) {
@ -1635,7 +1695,7 @@ function parseNum(val) {
}
}
// Now do a similar starting from the backside, to strip any trailing characters (such as units of measurement)
// Now do a similar procedure starting from the backside, to strip any trailing characters (such as units of measurement)
for (var i = (val.length - 1); i >= 0; i--) {
if ((/[^0-9]/g).test(val[i]) == true) {
// No need to modify iterator for this direction
@ -1857,17 +1917,41 @@ function isFloat(num) {
window.onpageshow = function() {
DEBUG('On Page Show function executing...')
generate_table('Interface Support', -1);
LoadCTA861();
LoadDMT();
DEBUG('Initializing HRES')
$('#INPUT_HRES')[0].onchange();
DEBUG('Initializing VRES')
$('#INPUT_VRES')[0].onchange();
DEBUG('Initializing FREQ')
$('#INPUT_F')[0].onchange();
DEBUG('Initializing COLOR DEPTH')
$('#COLOR_DEPTH_FORM')[0].onchange();
DEBUG('Initializing PIXEL FORMAT')
$('#PIXEL_FORMAT_FORM')[0].onchange();
DEBUG('Initializing COMPRESSION')
$('#COMPRESSION_FORM')[0].onchange();
DEBUG('Initializing SCAN')
$('#SCAN_FORM')[0].onchange();
DEBUG('Initializing MARGINS')
$('#MARGINS_FORM')[0].onchange();
DEBUG('Initializing TIMING STANDARD')
$('#TIMING_DROP')[0].onchange();
calcMain();
}
$('#V_FP')[0].onchange();
$('#V_BP')[0].onchange();
$('#V_SW')[0].onchange();
$('#H_FP')[0].onchange();
$('#H_BP')[0].onchange();
$('#H_SW')[0].onchange();
$('#V_FP_INT')[0].onchange();
$('#V_BP_INT')[0].onchange();
$('#V_SW_INT')[0].onchange();
//calcMain();
}
//window.onload = window.onpageshow;

@ -23,6 +23,7 @@
<head>
<meta charset="utf-8" />
<title>Bandwidth Calculator</title>
<!--<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">-->
<link rel="stylesheet" type="text/css" href="./style.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
</head>
@ -31,7 +32,7 @@
<div class="wrapper">
<div class="main">
<div class="header">
<a href="https://glenwing.github.io"><i class="material-icons back_arrow">subdirectory_arrow_left</i>&nbsp;Video Bandwidth Calculator (CTA Test 11)</a>
<a href="https://glenwing.github.io"><i class="material-icons back_arrow">subdirectory_arrow_left</i>&nbsp;Video Bandwidth Calculator (Work In Progress)</a>
<hr />
</div>
@ -50,14 +51,14 @@
<tr>
<td>
<div align="center">
<input id="INPUT_HRES" class="res_input number" style="text-align:right;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" autofocus />
<input id="INPUT_HRES" class="res_input number" style="text-align:right;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" autofocus />
<span class="res_x">&#10005;</span>
<input id="INPUT_VRES" class="res_input number" style="text-align:left;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange()" onfocus="this.select();" />
<input id="INPUT_VRES" class="res_input number" style="text-align:left;" type="text" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" />
<span>@</span>
<input id="INPUT_F" class="freq_input number" type="text" onchange="submitVar(this.id, this.value), calcMain();" oninput="this.onchange()" onfocus="this.select();" />
<input id="INPUT_F" class="freq_input number" type="text" onchange="submitVar(this.id, this.value), calcMain();" oninput="this.onchange();" onfocus="this.select();" />
<span>Hz</span>
</div>
<div id="warning_box" style="text-align:left; width:400px; margin-top:32px; border:1px solid black; padding:16px;">
<div id="warning_box" style="text-align:left; width:400px; margin-top:32px; border:1px solid black; padding:16px;" hidden>
<b>Warning: Non-Standard Refresh Rate</b><br />
<div style="padding:8px;">
The CTA-861 standard only defines timing parameters for this resolution at the following refresh rates:<br />
@ -189,7 +190,7 @@
<input id="H_BP" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td style="text-align:right; min-width:60px;">
<span id="H_BLANK">1234</span>&nbsp;px
<span id="H_BLANK"></span>&nbsp;px
</td>
</tr>
<tr style="height:30px;">
@ -206,7 +207,7 @@
<input id="V_BP" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td style="text-align:right; width:100px;">
<span id="V_BLANK">0</span>&nbsp;px
<span id="V_BLANK"></span>&nbsp;px
</td>
</tr>
<tr id="Interlaced_Timing_Row" style="height:30px;">
@ -223,7 +224,7 @@
<input id="V_BP_INT" class="timing_param" oldvalue="" onchange="submitVar(this.id, this.value); calcMain();" oninput="this.onchange();" onfocus="this.select();" disabled />&nbsp;px
</td>
<td id="V_BLANK_INT_CONTAINER" style="text-align:right; width:100px;">
<span id="V_BLANK_INT">0</span>&nbsp;px
<span id="V_BLANK_INT"></span>&nbsp;px
</td>
</tr>
</table>
@ -248,6 +249,7 @@
<tr id="results_body" style="display:table-row;">
<td colspan="3" class="body">
<table style="border-collapse:collapse; border:0px solid transparent; padding:0px;">
<!----<tr>
<tr>
<td style="overflow-x:auto; white-space:nowrap; vertical-align:top; width:300px; padding:12px; background-color:#E0E0E0;">
<b>Video Format:</b><br />
@ -260,96 +262,132 @@
CTA-861 timing (VIC: 63)<br />
</div>
</td>
</tr>
</table>
<br />
<table class="results">
</tr>-->
<tr>
<td class="label">
Data Rate:
</td>
<td class="value"><b>37.75</b></td>
<td class="unit"><b>Gbit/s</b></td>
</tr>
<tr class="addon">
<td>
Blanking Overhead:
</td>
<td class="value">10.3</td>
<td class="unit">%</td>
</tr>
<tr>
<td class="label" colspan="3">
Bandwidth:
</td>
</tr>
<tr class="addon">
<td>
8b/10b Encoding:
</td>
<td class="value">45.30</td>
<td class="unit">Gbit/s</td>
</tr>
<tr class="addon">
<td>
16b/18b Encoding:
</td>
<td class="value">51.20</td>
<td class="unit">Gbit/s</td>
</tr>
<tr>
<td class="label">
Character Rate ("Pixel Clock"):
</td>
<td class="value">1.26</td>
<td class="unit">GHz</td>
</tr>
<tr>
<td class="label">
Pixel Rate (Actual):
</td>
<td class="value">1.26</td>
<td class="unit">Gpx/s</td>
</tr>
<tr>
<td class="label">
Pixel Rate (Incl. Blank):
</td>
<td class="value">1.58</td>
<td class="unit">Gpx/s</td>
</tr>
<tr>
<td class="label">
Vertical Refresh Frequency (Actual):
</td>
<td class="value">120.001</td>
<td class="unit">Hz</td>
</tr>
<tr class="addon">
<td>
Deviation:
</td>
<td class="value">0.001</td>
<td class="unit">%</td>
</tr>
<tr class="addon">
<td>
Period:
<td id="results_container" class="results_container">
<table style='width:100%;' onclick='deselectRow();'><tr>
<td><div>Results</div></td>
<td style='text-align:right;'><label for='moar_decimals' style='font-size:80%;'>Moar Decimal Places<input type='checkbox' id='moar_decimals' class='moar_decimals' /></label></td>
</tr></table>
<table class="results">
<!--<table class="results" style="border-top-width: 0px;">-->
<tr id='results_data_transmission'>
<th class="label">Data Transmission</th><th class="val">Value</th><th class="unit">Unit</th></tr>
<tr id='results_data_rate'>
<td class="label">Data Rate</td><td class="val">8.00</td><td class="unit">Gbit/s</td></tr>
<tr id='results_bit_rate'>
<td class="label">Bandwidth:</td><td></td><td></td></tr>
<tr id='results_8b10b'>
<td class="label depth2">8b/10b Encoding</td><td class="val">10.00</td><td class="unit">Gbit/s</td></tr>
<tr id='results_16b18b'>
<td class="label depth2">16b/18b Encoding</td><td class="val">9.00</td><td class="unit">Gbit/s</td></tr>
<!----<tr id='results_char_rate'>
<td class="label">TMDS Character Rate ("Pixel Clock")</td><td class="val">346</td><td class="unit">MHz</td></tr>-->
<tr id='results_pixel_rate'>
<td class="label">Pixel Rate (Effective)</td><td class="val">346</td><td class="unit">Mpx/s</td></tr>
<tr id='results_pixel_rate_active'>
<td class="label">Pixel Rate (Active Pixels Only)</td><td class="val">346</td><td class="unit">Mpx/s</td></tr>
</table>
<table class="results">
<tr class="triple" id='results_resolution'>
<th class="label">Resolution</th><th class="val">Hor.</th><th class="val">Ver.</th><th class="val">Total</th><th class="unit">Unit</th></tr>
<tr class="triple" id='results_active_px'>
<td class="label">Active</td><td class="val half">1920</td><td class="val half">1080</td><td class="val">2,073,600</td><td class="unit">px</td></tr>
<tr class="triple" id='results_blank_px'>
<td class="label">Blank</td><td class="val half">80</td><td class="val half">77</td><td class="val">240,400</td><td class="unit">px</td></tr>
<tr class="triple" id='results_total_px'>
<td class="label">Effective Total</td><td class="val half">2000</td><td class="val half">1157</td><td class="val">2,314,000</td><td class="unit">px</td></tr>
<tr class="triple" id='results_overhead_px'>
<td class="label">Overhead</td><td class="val half">4.17</td><td class="val half">7.13</td><td class="val">11.59</td><td class="unit">%</td></tr>
</table>
<table class="results">
<tr id='results_format'>
<th class="label">Format</th><th class="val">Value</th><th class="unit">Unit</th></tr>
<tr id='results_bpc'>
<td class="label">Color Depth (Per Channel)</td><td class="val">8</td><td class="unit">bpc</td></tr>
<tr id='results_bpp'>
<td class="label">Color Depth (Per Pixel)</td><td class="val">24</td><td class="unit">bit/px</td></tr>
<tr id='results_palette'>
<td class="label">Palette Size</td><td class="val">16,777,216</td><td class="unit">colors</td></tr>
<tr id='results_px_format'>
<td class="label">Pixel Format</td><td class="val">RGB</td><td class="unit"></td></tr>
<tr id='results_scan'>
<td class="label">Scan Type</td><td class="val">Progressive</td><td class="unit"></td></tr>
</table>
<table class="results">
<tr id='results_v_refresh'>
<th class="label">Vertical Refresh</th><th class="val">Value</th><th class="unit">Unit</th></tr>
<tr id='results_v_freq'>
<td class="label">Frequency (Target)</td><td class="val">144.000</td><td class="unit">Hz</td></tr>
<tr id='results_v_freq_actual'>
<td class="label">Frequency (Actual)</td><td class="val">143.993</td><td class="unit">Hz</td></tr>
<tr id='results_v_freq_dev'>
<td class="label depth2">Deviation</td><td class="val">0.007</td><td class="unit">Hz</td></tr>
<tr id='results_v_freq_dev_perc'>
<td class="label depth2"></td><td class="val">0.00486</td><td class="unit">%</td></tr>
<tr id='results_v_per'>
<td class="label">Period (Target)</td><td class="val">6.944</td><td class="unit">ms</td></tr>
<tr id='results_v_per_actual'>
<td class="label">Period (Actual)</td><td class="val">6.945</td><td class="unit">ms</td></tr>
<tr id='results_v_per_dev'>
<td class="label depth2">Deviation</td><td class="val">0.338</td><td class="unit">µs</td></tr>
<tr id='results_v_per_dev_perc'>
<td class="label depth2"></td><td class="val">0.00486</td><td class="unit">%</td></tr>
</table>
<table class="results" hidden>
<tr id='results_v_refresh_int'>
<th class="label">Vertical Refresh</th><th class="val">Value</th><th class="unit">Unit</th></tr>
<tr id='results_v_field'>
<td class="label">Frequency / Field Rate (Target)</td><td class="val">144.000</td><td class="unit">Hz</td></tr>
<tr id='results_v_field_actual'>
<td class="label">Frequency / Field Rate (Actual)</td><td class="val">143.993</td><td class="unit">Hz</td></tr>
<tr id='results_v_field_dev'>
<td class="label depth2">Deviation</td><td class="val">0.007</td><td class="unit">Hz</td></tr>
<tr id='results_v_field_dev_perc'>
<td class="label depth2"></td><td class="val">0.00486</td><td class="unit">%</td></tr>
<tr id='results_v_framerate'>
<td class="label">Frame Rate (Target)</td><td class="val">72.000</td><td class="unit">Hz</td></tr>
<tr id='results_v_framerate_actual'>
<td class="label">Frame Rate (Actual)</td><td class="val">71.997</td><td class="unit">Hz</td></tr>
<tr id='results_v_framerate_dev'>
<td class="label depth2">Deviation</td><td class="val">0.003</td><td class="unit">Hz</td></tr>
<tr id='results_v_framerate_dev_perc'>
<td class="label depth2"></td><td class="val">0.00486</td><td class="unit">%</td></tr>
<tr id='results_v_field_per'>
<td class="label">Field Period (Target)</td><td class="val">6.944</td><td class="unit">ms</td></tr>
<tr id='results_v_field_per_actual'>
<td class="label">Field Period (Actual)</td><td class="val">6.945</td><td class="unit">ms</td></tr>
<tr id='results_v_field_per_dev'>
<td class="label depth2">Deviation</td><td class="val">0.338</td><td class="unit">µs</td></tr>
<tr id='results_v_field_per_dev_perc'>
<td class="label depth2"></td><td class="val">0.00486</td><td class="unit">%</td></tr>
</table>
<table class="results">
<tr id='results_h_refresh'>
<th class="label">Horizontal Refresh</th><th class="val">Value</th><th class="unit">Unit</th></tr>
<tr id='results_h_freq'>
<td class="label">Frequency</td><td class="val">167.757</td><td class="unit">kHz</td></tr>
<tr id='results_h_per'>
<td class="label">Period</td><td class="val">5.961</td><td class="unit">µs</td></tr>
</table>
<script>
var tables = document.getElementById('results_container').children;
for (var i = 0; i < tables.length; i++) {
if (tables[i].className != 'results') { continue; }
else {
var rows = tables[i].children[0].children;
for (var j = 0; j < rows.length; j++) {
rows[j].setAttribute('onclick', 'selectRow(this)');
rows[j].setAttribute('onmouseover', 'if(results_selectedRow == "") { $("#results_explanation").html(Detailed_Explanation[this.id]); }');
rows[j].setAttribute('onmouseout', 'if(results_selectedRow == "") { $("#results_explanation").html("Click specifications for details"); }');
}
}
}
</script>
</td>
<td class="value">8.333</td>
<td class="unit">ms</td>
</tr>
<tr>
<td class="label">
Horizontal Refresh Frequency:
<td class="results_explanation" id="results_explanation">
Click specifications for details
</td>
<td class="value">161.25</td>
<td class="unit">kHz</td>
</tr>
<tr class="addon">
<td>Period:</td>
<td class="value">15.2</td>
<td class="unit">µs</td>
</tr>
</table>
</td>
@ -425,6 +463,8 @@
<script src="DebugControl.js"></script>
<script src="jquery.csv.js"></script>
<script src="SI.js"></script>
<script src="bandwidth-spec-details.js"></script>
<script src="bandwidth.js"></script>
<!----

@ -79,6 +79,10 @@ div.spoiler {
margin-left: auto;
margin-right: auto;
}
div.inline_math {
text-align: center;
line-height: 200%;
}
span.title {
@ -93,6 +97,11 @@ span.res_x {
line-height: 0;
}
li {
padding-top:4px;
padding-bottom:4px;
}
input {
padding: 4px;
@ -131,6 +140,11 @@ input[type="radio"] {
input[disabled] {
background-color:#EEEEEE;
}
input.moar_decimals {
margin-left: 8px;
position: relative;
bottom: -0.1em;
}
label {
cursor: pointer;
vertical-align: middle;
@ -233,54 +247,111 @@ table.timing_format td {
table.timing_format td.timing_field {
width: 80px;
}
td.results_container {
min-width: 400px;
padding: 16px;
background-color: #E8E8E8;
}
td.results_container div {
font-weight: bold;
font-size: 125%;
}
table.results {
min-width: 320px;
max-width: 320px;
padding-top: 16px;
margin-top: 8px;
padding-top: 8px;
border-collapse: collapse;
width: 100%;
margin-top: 20px;
/*border-top: 1px solid #888888;*/
}
/*
table.results tr:nth-child(even) td {
background-color: #EEEEEE;
}
table.results tr:nth-child(odd) td {
background-color: #E4E4E4;
}*/
table.results tr {
border-top: 1px solid #888888;
font-weight: normal;
cursor: pointer;
}
table.results tr:hover {
background-color: #DDDDDD;
}
table.results tr.selected {
background-color: rgb(187, 212, 235);
}
table.results th {
font-weight: bold;
text-align: center;
white-space: nowrap;
text-align: left;
padding: 8px;
border-bottom: 1px solid #999999;
/*background-color: #BBBBBB;*/
}
table.results td {
white-space: nowrap;
padding-top: 10px;
padding-bottom: 10px;
padding: 5px;
/*border: 1px solid #444444;*/
}
table.results tr:first-of-type {
border-top: 1px solid transparent;
}
table.results tr.addon {
border-top: 0px solid transparent;
}
table.results tr.addon td {
padding-top: 0px;
table.results th.val {
text-align: right;
padding-left: 8px;
padding-right: 8px;
}
table.results tr.addon td:first-of-type {
padding-left: 32px;
table.results th.unit {
padding-left: 0px;
}
table.results td.label {
font-weight: bold;
text-align: left;
width: 1px;
vertical-align: top;
padding-right:16px;
padding-left: 25px;
width: 100%;
}
table.results td.value {
padding-left: 16px;
table.results td.val {
text-align: right;
width: 1px;
width: 200px;
min-width: 200px;
padding-left: 8px;
padding-right: 8px;
}
table.results td.unit {
text-align: left;
width: 1px;
padding-right: 8px;
padding-left: 6px;
padding-left: 0px;
width: 40px;
min-width: 40px;
}
table.results td.encoding {
text-align: right;
padding-right: 24px;
table.results td.depth2 {
padding-left: 50px;
padding-top: 2px;
padding-bottom: 2px;
}
table.results tr.double td.val {
width: 80px;
min-width: 80px;
}
table.results tr.triple td.val {
width: 100px;
min-width: 100px;
}
table.results tr.triple td.half {
width: 50px;
min-width: 50px;
}
td.results_explanation {
vertical-align: top;
text-align: left;
padding: 16px;
width: 400px;
background-color: #E8E8E8;
}

Loading…
Cancel
Save