DebugConfig ( {
//all: true,
calcMain : 1 ,
submitVar : 0 ,
input _ok : 0 ,
updateDisplay : 0 ,
getTiming : 1 ,
marginsUIChange : 0 ,
timingUIChange : 0 ,
generate _table : 0 ,
SI : 0 ,
SI _include _exclude : 0 ,
SI _set _options : 0 ,
SI _set _precision : 0 ,
CTA : 0 ,
DMT : 1 ,
CVT : 0 ,
CVT _R : 0 ,
GTF : 0 ,
} ) ;
CTA861 = { } ;
DMT _List = { } ;
// The intepreted current state of all input fields is stored here
Global _InputVars = {
'HRES' : '' , // Int
'VRES' : '' , // Int
'FREQ' : '' , // Float
'COLOR_DEPTH' : '' ,
'PIXEL_FORMAT' : '' ,
'COMP' : '' ,
'SCAN' : '' ,
'MARGINS' : '' ,
'TIMING_STD' : '' ,
'V_FP' : '' ,
'V_BP' : '' ,
'V_SW' : '' ,
'H_FP' : '' ,
'H_BP' : '' ,
'H_SW' : '' ,
'V_FP_INT' : '' ,
'V_BP_INT' : '' ,
'V_SW_INT' : '' ,
}
Detailed _Results = {
}
Encoding _Overhead = {
'8b/10b' : 1.25 ,
'16b/18b' : 1.125 ,
} ;
Interface = [
{
name : "DisplayPort 1.3–1.4" ,
encoding : "8b/10b" ,
datarate : 25.92 * ( 10 * * 9 ) ,
} , {
name : "DisplayPort 1.2" ,
encoding : "8b/10b" ,
datarate : 17.28 * ( 10 * * 9 ) ,
} , {
name : "DisplayPort 1.0–1.1" ,
encoding : "8b/10b" ,
datarate : 8.64 * ( 10 * * 9 ) ,
} , {
name : "HDMI 2.1" ,
encoding : "16b/18b" ,
datarate : 48 * ( 10 * * 9 ) * ( 16 / 18 ) ,
} , {
name : "HDMI 2.0" ,
encoding : "8b/10b" ,
datarate : 14.4 * ( 10 * * 9 ) ,
} , {
name : "HDMI 1.3–1.4" ,
encoding : "8b/10b" ,
datarate : 8.16 * ( 10 * * 9 ) ,
} , {
name : "HDMI 1.0–1.2" ,
encoding : "8b/10b" ,
datarate : 3.96 * ( 10 * * 9 ) ,
} , {
name : "Dual-Link DVI" ,
encoding : "8b/10b" ,
datarate : 7.92 * ( 10 * * 9 ) ,
} , {
name : "Single-Link DVI" ,
encoding : "8b/10b" ,
datarate : 3.96 * ( 10 * * 9 ) ,
} , {
name : "Thunderbolt 3 (Gen 2)" ,
encoding : "unknown" ,
datarate : 40 * ( 10 * * 9 ) ,
} , {
name : "Thunderbolt 3 (Gen 1)" ,
encoding : "unknown" ,
datarate : 34.56 * ( 10 * * 9 ) ,
} , {
name : "Thunderbolt 2" ,
encoding : "unknown" ,
datarate : 17.28 * ( 10 * * 9 ) ,
} , {
name : "Thunderbolt" ,
encoding : "unknown" ,
datarate : 8.64 * ( 10 * * 9 ) ,
} ,
] ;
function submitVar ( id , val ) {
DEBUG ( id , val ) ;
var len = 0 ;
var GlobalVars _Key = '' ;
if ( typeof ( val ) === 'number' ) { val = val . toString ( ) ; }
if ( id == 'INPUT_HRES' || id == 'INPUT_VRES' ) {
if ( id == 'INPUT_HRES' ) GlobalVars _Key = 'HRES' ;
else if ( id == 'INPUT_VRES' ) GlobalVars _Key = 'VRES' ;
val = parseNum ( val ) ;
if ( isNum ( val ) == true ) {
val = Math . abs ( parseInt ( val ) ) ;
Global _InputVars [ GlobalVars _Key ] = val ;
}
else {
DEBUG ( id + ' input is not a number:' , val ) ;
Global _InputVars [ GlobalVars _Key ] = '' ;
}
DEBUG ( "Global_InputVars['" + GlobalVars _Key + "'] was set to" , Global _InputVars [ GlobalVars _Key ] ) ;
}
else if ( id == 'INPUT_F' ) {
GlobalVars _Key = 'FREQ' ;
val = parseNum ( val ) ;
if ( isNum ( val ) == true ) {
Global _InputVars [ GlobalVars _Key ] = Math . abs ( val ) ;
}
else {
DEBUG ( id + ' input is not a number:' , val ) ;
Global _InputVars [ GlobalVars _Key ] = '' ;
}
DEBUG ( "Global_InputVars['" + GlobalVars _Key + "'] was set to" , Global _InputVars [ GlobalVars _Key ] ) ;
}
else if ( id == 'COLOR_DEPTH_FORM' ) {
// Value is either the color depth number (in bits per pixel), or the string 'Custom'
GlobalVars _Key = 'COLOR_DEPTH' ;
colordepthUIChange ( ) ;
if ( val != 'Custom' ) { Global _InputVars [ GlobalVars _Key ] = val ; }
else if ( val == 'Custom' ) { // Custom color depth
// If Custom, grab the number from the custom color depth input field
val = parseInt ( parseNum ( $ ( '#CUSTOM_COLOR_DEPTH' ) . val ( ) ) ) ;
if ( isNum ( val ) == true ) {
if ( $ ( 'input[name=CD_UNIT_SLCT]:checked' ) . val ( ) == 'bpc' ) {
val = val * 3 ; // If user enters values in units of bpc, then multiply by 3 to convert to bit/px (bpp)
}
Global _InputVars [ GlobalVars _Key ] = Math . abs ( val ) ;
}
else {
DEBUG ( id + ' input is not a number:' , val ) ;
Global _InputVars [ GlobalVars _Key ] = '' ;
}
}
DEBUG ( "Global_InputVars['" + GlobalVars _Key + "'] was set to" , Global _InputVars [ GlobalVars _Key ] ) ;
}
else if ( id == 'PIXEL_FORMAT_FORM' ) {
GlobalVars _Key = 'PIXEL_FORMAT' ;
if ( val == 'RGB' || val == 'YCBCR 4:4:4' ) { val = 1.0 ; }
else if ( val == 'YCBCR 4:2:2' ) { val = 1.5 ; }
else if ( val == 'YCBCR 4:2:0' ) { val = 2.0 ; }
Global _InputVars [ GlobalVars _Key ] = val ;
DEBUG ( "Global_InputVars['" + GlobalVars _Key + "'] was set to" , Global _InputVars [ GlobalVars _Key ] ) ;
}
else if ( id == 'COMPRESSION_FORM' ) {
GlobalVars _Key = 'COMP' ;
if ( val == 'Uncompressed' ) { val = 1.0 ; }
else if ( val == 'DSC 2.0x' ) { val = 2.0 ; }
else if ( val == 'DSC 2.5x' ) { val = 2.5 ; }
else if ( val == 'DSC 3.0x' ) { val = 3.0 ; }
Global _InputVars [ GlobalVars _Key ] = val ;
DEBUG ( "Global_InputVars['" + GlobalVars _Key + "'] was set to" , Global _InputVars [ GlobalVars _Key ] ) ;
}
else if ( id == 'SCAN_FORM' ) {
GlobalVars _Key = 'SCAN' ;
if ( val == 'p' ) { val = 1 ; }
else if ( val == 'i' ) { val = 2 ; }
Global _InputVars [ GlobalVars _Key ] = val ;
DEBUG ( "Global_InputVars['" + GlobalVars _Key + "'] was set to" , Global _InputVars [ GlobalVars _Key ] ) ;
timingUIChange ( ) ;
DEBUG ( 'Set interlaced timing row display to:' , $ ( '#Interlaced_Timing_Row' ) . css ( 'display' ) ) ;
}
else if ( id == 'MARGINS_FORM' ) {
// val is either 'y' or 'n'
GlobalVars _Key = 'MARGINS' ;
marginsUIChange ( ) ;
if ( val == 'n' ) {
Global _InputVars [ GlobalVars _Key ] = 0 ;
}
else if ( val == 'y' ) {
val = parseFloat ( parseNum ( $ ( '#CUSTOM_MARGINS' ) . val ( ) ) ) ;
if ( isNum ( val ) == true ) {
Global _InputVars [ GlobalVars _Key ] = Math . abs ( val ) ;
}
else {
DEBUG ( id + ' input is not a number:' , val ) ;
Global _InputVars [ GlobalVars _Key ] = '' ;
}
}
else { DEBUG ( 'invalid input combination. id/val = ' , id , val ) } // If val is not 'y' or 'n', then something somewhere has gone terribly wrong
DEBUG ( "Global_InputVars['" + GlobalVars _Key + "'] was set to" , Global _InputVars [ GlobalVars _Key ] ) ;
}
else if ( id == 'TIMING_DROP' ) {
GlobalVars _Key = 'TIMING_STD' ;
Global _InputVars [ GlobalVars _Key ] = 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 = Math.abs(parseNum(val));
if ( isNum ( val ) ) {
Global _InputVars [ id ] = Math . abs ( val ) ;
$ ( '#' + id ) . val ( val ) ;
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 ( '' ) ;
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 ] ) ;
// Update value displayed in the UI input field
// Update total Vblank and Hblank numbers on the UI
}
}
function generate _table ( type , input _datarate ) {
if ( type == "Interface Support" ) {
table = $ ( "#interface_support_table" ) ;
contents = '' ;
contents += ( '<tr><th class="title" colspan="6">Interface Support</th></tr>' ) ;
contents += ( '<tr>' ) ;
contents += ( '<th rowspan="2">% Usage</th>' ) ;
contents += ( '<th rowspan="2">Interface</th>' ) ;
contents += ( '<th rowspan="2">Encoding</th>' ) ;
contents += ( '<th colspan="3" style="border-bottom:1px solid #FFFFFF;">Maximum</th></tr>' ) ;
contents += ( '<tr><th>Pixel Clock</th><th>Datarate</th><th>Bandwidth</th></tr>' ) ;
var name ;
var encoding ;
var datarate ;
var pixel _clock ;
var bandwidth ;
var overhead ;
var saturation ;
for ( var x = 0 ; x < Interface . length ; x ++ ) {
name = Interface [ x ] [ 'name' ] ;
encoding = Interface [ x ] [ 'encoding' ] ;
if ( encoding == 'unknown' ) {
datarate = Interface [ x ] [ 'datarate' ] ;
bandwidth = '?' ;
encoding = '?' ;
}
else {
overhead = Encoding _Overhead [ encoding ] ;
datarate = Interface [ x ] [ 'datarate' ] ;
bandwidth = datarate * overhead ;
}
pixel _clock = datarate / 24 ;
saturation = input _datarate / datarate ;
if ( input _datarate == - 1 ) {
contents += ( '<tr><td></td>' ) ;
}
else {
contents += ( '<tr><td>' + saturation . toFixed ( 1 ) + '%</td>' ) ;
}
contents += ( '<td style="text-align:left; white-space:nowrap;">' + name + '</td><td>' + encoding + '</td><td>' + SI ( pixel _clock , 'Hz' , { p : [ 'M0' , 'G3' ] } ) + '</td><td>' + SI ( datarate , 'bit/s' , 2 ) + '</td><td>' + SI ( bandwidth , 'bit/s' , 2 ) + '</td></tr>' ) ;
}
table . html ( contents ) ;
return ;
}
else if ( type == "Maximum Refresh Frequency" ) {
return ;
}
return ;
}
function input _ok ( ) {
// This checks to make sure all the necessary fields are filled in, and their contents are valid, before allowing the Calculation function to proceed.
var val ;
var checklist = [ 'HRES' , 'VRES' , 'FREQ' ] ;
for ( var i = 0 ; i < checklist . length ; i ++ ) {
val = Global _InputVars [ checklist [ i ] ] ;
if ( ! ( isPositive ( val ) ) ) {
DEBUG ( 'Calculation aborted. ' + checklist [ i ] + ' contains an empty or non-numeric string.' , val ) ;
return false ;
}
}
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 ) ) ) {
DEBUG ( 'Calculation aborted. COLOR_DEPTH_SLCT is set to Custom, but CUSTOM_COLOR_DEPTH contains an empty or non-numeric string, or 0.' , val ) ;
return false ;
}
}
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 ++ ) {
val = Global _InputVars [ checklist [ i ] ] ;
if ( ! ( isPositiveZ ( val ) ) ) {
abort = true ;
}
}
if ( abort == true ) {
DEBUG ( 'Calculation aborted. TIMING_DROP is set to Custom, but one or more timing parameter fields contains an empty or non-numeric string.' , Global _InputVars ) ;
return false ;
}
}
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 ) ) ) {
DEBUG ( 'Calculation aborted. MARGINS_SLCT is set to Yes, but CUSTOM_MARGINS contains an empty or non-numeric string.' , val ) ;
return false ;
}
}
return true ;
}
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 ( ) ; $ ( '#TIMING_FORMAT_NAME' ) . html ( '' ) ; return ; }
var hres = Global _InputVars [ 'HRES' ] ;
var vres = Global _InputVars [ 'VRES' ] ;
var freq = Global _InputVars [ 'FREQ' ] ;
var color _depth = Global _InputVars [ 'COLOR_DEPTH' ] ;
var px _format = Global _InputVars [ 'PIXEL_FORMAT' ] ;
var comp = Global _InputVars [ 'COMP' ] ;
var scan = Global _InputVars [ 'SCAN' ] ;
var timing _standard = Global _InputVars [ 'TIMING_STD' ] ;
// Get timing parameters
Timing = getTiming ( timing _standard ) ;
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' ] ;
// DATA TRANSMISSION
{
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' } ,
) ;
}
// RESOLUTION
{
Detailed _Results [ 'active_px' ] = {
'h' : { 'val' : hres } ,
'v' : { 'val' : vres } ,
't' : SI ( hres * vres , 'px' , { 'p' : 0 , 'output' : 'split' , 'include' : [ 'b' ] } ) ,
} ;
Detailed _Results [ 'blank_px' ] = {
'h' : { 'val' : h _eff - hres } ,
'v' : { 'val' : v _eff - vres } ,
't' : SI ( ( h _eff * v _eff ) - ( hres * vres ) , 'px' , { 'p' : 0 , 'output' : 'split' , 'include' : [ 'b' ] } ) ,
} ;
Detailed _Results [ 'total_px' ] = {
'h' : { 'val' : h _eff } ,
'v' : { 'val' : v _eff } ,
't' : SI ( h _eff * v _eff , 'px' , { 'p' : 0 , 'output' : 'split' , 'exclude' : [ '<B' , '>B' ] } ) ,
} ;
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' ] } ) ,
} ;
}
// FORMAT
{
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' ; }
}
// VERTICAL REFRESH FOR PROGRESSIVE SCAN
{
Detailed _Results [ 'v_freq' ] = SI (
freq ,
'Hz' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '>=b' ] } ,
) ;
Detailed _Results [ 'v_freq_actual' ] = SI (
freq _act ,
'Hz' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '>=b' ] } ,
) ;
Detailed _Results [ 'v_freq_dev' ] = SI (
Math . abs ( freq - freq _act ) ,
'Hz' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ '>=b' ] } ,
) ;
Detailed _Results [ 'v_freq_dev_perc' ] = SI (
Math . abs ( 100 * ( ( freq - freq _act ) / 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 / freq _act ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_per_dev' ] = SI (
Math . abs ( ( 1 / freq ) - ( 1 / freq _act ) ) ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_per_dev_perc' ] = SI (
Math . abs ( 100 * ( ( 1 / freq ) - ( 1 / freq _act ) ) / ( 1 / freq ) ) ,
'%' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
}
// VERTICAL REFRESH FOR INTERLACED SCAN
{
Detailed _Results [ 'v_field' ] = SI (
freq ,
'Hz' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '>=b' ] } ,
) ;
Detailed _Results [ 'v_field_actual' ] = SI (
Timing [ 'F_ACTUAL' ] ,
'Hz' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '>=b' ] } ,
) ;
Detailed _Results [ 'v_field_dev' ] = SI (
Math . abs ( freq - freq _act ) ,
'Hz' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ '>=b' ] } ,
) ;
Detailed _Results [ 'v_field_dev_perc' ] = SI (
Math . abs ( 100 * ( ( freq - freq _act ) / freq ) ) ,
'%' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
Detailed _Results [ 'v_field_per' ] = SI (
1 / freq ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_field_per_actual' ] = SI (
1 / freq _act ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_field_per_dev' ] = SI (
Math . abs ( ( 1 / freq ) - ( 1 / freq _act ) ) ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_field_per_dev_perc' ] = SI (
Math . abs ( 100 * ( ( 1 / freq ) - ( 1 / freq _act ) ) / ( 1 / freq ) ) ,
'%' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
Detailed _Results [ 'v_frame' ] = SI (
freq / 2 ,
'FPS' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
Detailed _Results [ 'v_frame_actual' ] = SI (
freq _act / 2 ,
'FPS' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
Detailed _Results [ 'v_frame_dev' ] = SI (
Math . abs ( ( freq / 2 ) - ( freq _act / 2 ) ) ,
'FPS' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
Detailed _Results [ 'v_frame_dev_perc' ] = SI (
Math . abs ( 100 * ( ( freq - freq _act ) / freq ) ) ,
'%' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
Detailed _Results [ 'v_frame_per' ] = SI (
( 1 / ( freq / 2 ) ) ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_frame_per_actual' ] = SI (
1 / ( freq _act / 2 ) ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_frame_per_dev' ] = SI (
Math . abs ( ( 2 / freq ) - ( 2 / freq _act ) ) ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
Detailed _Results [ 'v_frame_per_dev_perc' ] = SI (
Math . abs ( 100 * ( ( 2 / freq ) - ( 2 / freq _act ) ) / ( 2 / freq ) ) ,
'%' ,
{ 'p' : 6 , 'output' : 'split' , 'include' : [ 'b' ] } ,
) ;
}
// HORIZONTAL REFRESH
{
Detailed _Results [ 'h_freq' ] = SI (
( v _eff * freq _act ) / scan ,
'Hz' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '>=b' ] } ,
) ;
Detailed _Results [ 'h_per' ] = SI (
scan / ( v _eff * freq _act ) ,
's' ,
{ 'p' : 3 , 'output' : 'split' , 'include' : [ '<=b' ] } ,
) ;
}
//DEBUG('Results:', SI(results['bits_per_sec_eff'], 'bit/s', 2), results);
updateDisplay ( ) ;
}
function getTiming ( timing _standard ) {
// Just a traffic control function
// Actual parameters are calculated in dedicated functions for each standard
if ( ! ( isPositiveZ ( Global _InputVars [ 'HRES' ] ) && isPositiveZ ( Global _InputVars [ 'VRES' ] ) && isPositiveZ ( Global _InputVars [ 'FREQ' ] ) ) ) {
DEBUG ( 'Timing calculation aborted, HRES, VRES, or FREQ contains invalid input.' , Global _InputVars [ 'HRES' ] , Global _InputVars [ 'VRES' ] , Global _InputVars [ 'FREQ' ] ) ;
return {
'V_FP' : '' ,
'V_BP' : '' ,
'V_SW' : '' ,
'H_FP' : '' ,
'H_BP' : '' ,
'H_SW' : '' ,
'V_FP_INT' : '' ,
'V_BP_INT' : '' ,
'V_SW_INT' : '' ,
'V_BL' : '' ,
'H_BL' : '' ,
'V_EFF' : '' ,
'H_EFF' : '' ,
'F_ACTUAL' : Global _InputVars [ 'FREQ' ] ,
} ;
}
DEBUG ( 'Timing Standard:' , timing _standard )
if ( timing _standard != 'Custom' ) {
if ( timing _standard == 'CVT-R2' ) {
DEBUG ( 'Fetching CVT-R2 Timing...' )
if ( Global _InputVars [ 'FREQ' ] >= ( 1 / 0.00046 ) ) {
$ ( '#TIMING_FORMAT_NAME' ) . html ( '≥ 2173.9 Hz not allowed' ) ;
return false ;
}
Timing = CVT _R ( 2 ) ;
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' ) {
DEBUG ( 'Fetching CVT-R2 Timing...' )
if ( Global _InputVars [ 'FREQ' ] >= ( 1 / 0.00046 ) ) {
$ ( '#TIMING_FORMAT_NAME' ) . html ( '≥ 2173.9 Hz not allowed' ) ;
return false ;
}
Timing = CVT _R ( 1 ) ;
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' ) {
if ( Global _InputVars [ 'FREQ' ] >= ( 1 / 0.00055 ) ) {
$ ( '#TIMING_FORMAT_NAME' ) . html ( '≥ 1818.<span style="text-decoration: overline">18</span> Hz not allowed' ) ;
return false ;
}
Timing = CVT ( ) ;
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' ) {
if ( Global _InputVars [ 'FREQ' ] >= ( 1 / 0.00055 ) ) {
$ ( '#TIMING_FORMAT_NAME' ) . html ( '≥ 1818.<span style="text-decoration: overline">18</span> Hz not allowed' ) ;
return false ;
}
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 ( 'Not a DMT format' ) ;
clearTiming ( ) ;
return false ; }
else {
$ ( '#TIMING_FORMAT_NAME' ) . html ( '<b>DMT ID:</b> ' + Timing [ 'ID' ] ) ;
}
}
else if ( timing _standard == 'CTA-861' ) {
Timing = CTA ( ) ;
if ( ! Timing ) {
DEBUG ( 'Not a CTA Format. CTA Function returned false.' ) ;
$ ( '#TIMING_FORMAT_NAME' ) . html ( 'Not a CTA format' ) ;
clearTiming ( ) ;
return false ; }
else {
$ ( '#TIMING_FORMAT_NAME' ) . html ( '<b>CTA VIC:</b> ' + Timing [ 'VIC' ] ) ;
}
}
else if ( timing _standard == 'None' ) {
Timing = {
'V_FP' : 0 ,
'V_BP' : 0 ,
'V_SW' : 0 ,
'H_FP' : 0 ,
'H_BP' : 0 ,
'H_SW' : 0 ,
'V_FP_INT' : 0 ,
'V_BP_INT' : 0 ,
'V_SW_INT' : 0 ,
'V_BL' : 0 ,
'H_BL' : 0 ,
'V_EFF' : Global _InputVars [ 'VRES' ] / Global _InputVars [ 'SCAN' ] ,
'H_EFF' : Global _InputVars [ 'HRES' ] ,
'F_ACTUAL' : Global _InputVars [ 'FREQ' ] ,
}
$ ( '#TIMING_FORMAT_NAME' ) . html ( '' ) ;
}
// Update UI timing parameter fields with the newly generated timings
submitVar ( 'V_FP' , Timing [ 'V_FP' ] ) ;
submitVar ( 'V_BP' , Timing [ 'V_BP' ] ) ;
submitVar ( 'V_SW' , Timing [ 'V_SW' ] ) ;
submitVar ( 'H_FP' , Timing [ 'H_FP' ] ) ;
submitVar ( 'H_BP' , Timing [ 'H_BP' ] ) ;
submitVar ( 'H_SW' , Timing [ 'H_SW' ] ) ;
submitVar ( 'V_FP_INT' , Timing [ 'V_FP_INT' ] ) ;
submitVar ( 'V_SW_INT' , Timing [ 'V_SW_INT' ] ) ;
submitVar ( 'V_BP_INT' , Timing [ 'V_BP_INT' ] ) ;
}
else if ( timing _standard == 'Custom' ) {
// Read the timing from the UI
submitVar ( 'V_FP' , $ ( '#V_FP' ) . val ( ) ) ;
submitVar ( 'V_BP' , $ ( '#V_BP' ) . val ( ) ) ;
submitVar ( 'V_SW' , $ ( '#V_SW' ) . val ( ) ) ;
submitVar ( 'H_FP' , $ ( '#H_FP' ) . val ( ) ) ;
submitVar ( 'H_BP' , $ ( '#H_BP' ) . val ( ) ) ;
submitVar ( 'H_SW' , $ ( '#H_SW' ) . val ( ) ) ;
if ( isNum ( Global _InputVars [ 'V_FP' ] ) ) { submitVar ( 'V_FP_INT' , Global _InputVars [ 'V_FP' ] + 0.5 ) ; }
if ( isNum ( Global _InputVars [ 'V_SW' ] ) ) { submitVar ( 'V_SW_INT' , Global _InputVars [ 'V_SW' ] ) ; }
if ( isNum ( Global _InputVars [ 'V_BP' ] ) ) { submitVar ( 'V_BP_INT' , Global _InputVars [ 'V_BP' ] + 0.5 ) ; }
Timing = {
'V_FP' : Global _InputVars [ 'V_FP' ] ,
'V_BP' : Global _InputVars [ 'V_BP' ] ,
'V_SW' : Global _InputVars [ 'V_SW' ] ,
'H_FP' : Global _InputVars [ 'H_FP' ] ,
'H_BP' : Global _InputVars [ 'H_BP' ] ,
'H_SW' : Global _InputVars [ 'H_SW' ] ,
'V_FP_INT' : Global _InputVars [ 'V_FP_INT' ] ,
'V_BP_INT' : Global _InputVars [ 'V_BP_INT' ] ,
'V_SW_INT' : Global _InputVars [ 'V_SW_INT' ] ,
'V_BL' : Global _InputVars [ 'V_FP' ] + Global _InputVars [ 'V_BP' ] + Global _InputVars [ 'V_SW' ] ,
'H_BL' : Global _InputVars [ 'H_FP' ] + Global _InputVars [ 'H_BP' ] + Global _InputVars [ 'H_SW' ] ,
'V_EFF' : Global _InputVars [ 'VRES' ] + Global _InputVars [ 'V_FP' ] + Global _InputVars [ 'V_BP' ] + Global _InputVars [ 'V_SW' ] ,
'H_EFF' : Global _InputVars [ 'HRES' ] + Global _InputVars [ 'H_FP' ] + Global _InputVars [ 'H_BP' ] + Global _InputVars [ 'H_SW' ] ,
'F_ACTUAL' : Global _InputVars [ 'FREQ' ] ,
}
$ ( '#TIMING_FORMAT_NAME' ) . html ( '' ) ;
}
$ ( '#V_BLANK' ) . html ( Timing [ 'V_BL' ] ) ;
$ ( '#H_BLANK' ) . html ( Timing [ 'H_BL' ] ) ;
return Timing ;
}
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
var F = Global _InputVars [ 'FREQ' ] ; // Nominal vertical refresh frequency
var S = Global _InputVars [ 'SCAN' ] ; // 1 for progressive scan, 2 for interlaced
var M = Global _InputVars [ 'MARGINS' ] ; // Margins (%)
var I = ( S - 1 ) / 2 ; // 0 for progressive, 0.5 for interlaced
// Declaring variables for all results
var V _FP ; // Vertical front porch
var V _SW ; // Vertical sync width
var V _BP ; // Vertical back porch
var H _FP ; // Horizontal front porch
var H _SW ; // Horizontal sync width
var H _BP ; // Horizontal back porch
var V _BLANK ; // Total vertical blanking (V_FP + V_SW + V_BP)
var H _BLANK ; // Total horizontal blanking (H_FP + H_SW + H_BP)
var V _EFF ; // V + V_Blank + V_Margins
var H _EFF ; // H + H_Blank + H_Margins
var F _ACTUAL ; // Actual vertical refresh frequency (after pixel clock rounding)
var F _HOR ; // Horizontal refresh frequency
// Common constants
var V _PER _MIN = 0.00046 ; /* Minimum vertical blanking period for reduced blank timing (in seconds), defined by VESA CVT 1.2 standard */
var V _LINES = Math . floor ( V / S ) // If progressive scan, S = 1 and V_LINES = V. If interlaced, V_LINES = floor(V / 2).
if ( R == 1 ) {
// CVT-RB constants
H _BLANK = 160 ;
H _FP = 48 ;
H _BP = 80 ;
H _SW = 32 ;
V _FP = 3 ;
var V _BP _MIN = 6 ;
// All H timings are defined, as well as V_FP. Only V_SW and V_BP remain (and V_BLANK, the sum of all 3 V parameters)
// Determine vertical sync width (V_SW) from table of magic numbers defined in VESA CVT standard
var V _SYNC _TABLE = [
[ 4 / 3 , 4 , '3' ] ,
[ 16 / 9 , 5 , '9' ] ,
[ 8 / 5 , 6 , 'A' ] ,
[ 5 / 3 , 7 , '9' ] ,
[ 5 / 4 , 7 , '4' ] ,
]
var AR _NAME = '' ;
V _SW = 10 ; // default value defined in standard
for ( var i = 0 ; i < V _SYNC _TABLE . length ; i ++ ) {
if ( Math . abs ( ( H / V ) - V _SYNC _TABLE [ i ] [ 0 ] ) < 0.05 ) { // Check if aspect ratio of image (H/V) matches an aspect ratio defined in table, within 0.05
V _SW = V _SYNC _TABLE [ i ] [ 1 ] ;
AR _NAME = V _SYNC _TABLE [ i ] [ 2 ] ;
DEBUG ( 'AR_NAME' , AR _NAME )
break ;
}
}
// V_BP is determined in reverse, by calculating V_BLANK first (the sum of V_FP, V_SW, and V_BP) and subtracting out V_FP and V_SW.
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
var H _PER _EST = ( ( 1 / F ) - V _PER _MIN ) / ( V _LINES + ( 2 * V _MARGIN ) ) ; // Horizontal blanking period estimate
V _BLANK = Math . floor ( ( V _PER _MIN / H _PER _EST ) + 1 ) ;
var V _BLANK _MIN = V _FP + V _SW + V _BP _MIN ;
if ( V _BLANK < V _BLANK _MIN ) { V _BLANK = V _BLANK _MIN ; } // Enforce minimum value for V_blank
V _BP = V _BLANK - ( V _FP + V _SW ) ;
V _EFF = V _LINES + V _BLANK + V _MARGIN + I ; // (S-1)/2 = 0 for progressive, 0.5 for interlaced
H _EFF = H _RND + H _BLANK + H _MARGIN ;
// Calculate pixel clock, to enforce pixel clock rounding to the nearest 250 kHz, as required by the CVT standard
var CLK = F * ( V _EFF ) * ( H _EFF ) ; // Pixel clock (Hz)
CLK = Math . floor ( CLK / 250000 ) * 250000 ; // Pixel clock (Hz) rounded down to the next multiple of 0.25 MHz (250 kHz, 250000 Hz)
F _HOR = CLK / ( H _EFF ) ; // Horizontal refresh frequency (Hz)
F _ACTUAL = F _HOR / ( V _EFF ) ; // Pixel clock rounding is enforced via lowering the vertical refresh frequency to adjust pixel clock
}
else if ( R == 2 ) {
// CVT-R2 constants defined by CVT standard
H _BLANK = 80 ;
H _FP = 8 ;
H _BP = 40 ;
H _SW = 32 ;
V _BP = 6 ;
V _SW = 8 ;
var V _FP _MIN = 1 ;
// All parameters are defined as constant except V_FP
// V_FP is determined in reverse, by calculating V_BLANK first (the sum of V_FP, V_SW, and V_BP) and subtracting V_SW and V_BP out.
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 * ( M / 100 ) ) ; // If margins percent (M) is 0, this result is 0
var H _PER _EST = ( ( 1 / F ) - V _PER _MIN ) / ( V _LINES + ( 2 * V _MARGIN ) ) ; // Horizontal blanking period estimate
V _BLANK = Math . floor ( ( V _PER _MIN / H _PER _EST ) + 1 ) ;
var V _BLANK _MIN = V _FP _MIN + V _SW + V _BP ;
if ( V _BLANK < V _BLANK _MIN ) { V _BLANK = V _BLANK _MIN ; } // Enforce minimum value for V_blank
V _FP = V _BLANK - ( V _BP + V _SW ) ;
V _EFF = V _LINES + V _BLANK + V _MARGIN + I ; // (S-1)/2 = 0 for progressive, 0.5 for interlaced
H _EFF = H + H _BLANK + H _MARGIN ;
// Calculate pixel clock, to enforce pixel clock rounding to the nearest 1 kHz, as required by the CVT standard
var CLK = F * ( V _EFF ) * ( H _EFF ) ; // Pixel clock (Hz)
CLK = Math . floor ( CLK / 1000 ) * 1000 ; // Pixel clock (Hz) rounded down to the next multiple of 0.001 MHz (1 kHz, 1000 Hz)
F _HOR = CLK / ( H _EFF ) ; // Horizontal refresh frequency (Hz)
F _ACTUAL = F _HOR / ( V _EFF ) ;
var V _SYNC _TABLE = [
[ 4 / 3 , 4 , '3' ] ,
[ 16 / 9 , 5 , '9' ] ,
[ 8 / 5 , 6 , 'A' ] ,
[ 5 / 3 , 7 , '9' ] ,
[ 5 / 4 , 7 , '4' ] ,
]
var AR _NAME = '' ;
for ( var i = 0 ; i < V _SYNC _TABLE . length ; i ++ ) {
if ( Math . abs ( ( H / V ) - V _SYNC _TABLE [ i ] [ 0 ] ) < 0.05 ) {
AR _NAME = V _SYNC _TABLE [ i ] [ 2 ] ;
}
}
}
//DEBUG('CLK', CLK);
//DEBUG('F_HOR', F_HOR);
//DEBUG('F_ACTUAL', F_ACTUAL);
//DEBUG(V_BLANK);
return {
'V_FP' : V _FP , // For interlaced, these vertical timing are used for the odd fields
'V_BP' : V _BP ,
'V_SW' : V _SW ,
'H_FP' : H _FP ,
'H_BP' : H _BP ,
'H_SW' : H _SW ,
'V_FP_INT' : V _FP + I , // For interlaced, V_FP and V_BP are 0.5 higher for even fields (V_SW is same)
'V_BP_INT' : V _BP + I ,
'V_SW_INT' : V _SW ,
'V_BL' : V _BLANK ,
'H_BL' : H _BLANK ,
'V_EFF' : V _EFF ,
'H_EFF' : H _EFF ,
'F_ACTUAL' : F _ACTUAL ,
'VESA_AR' : AR _NAME ,
} ;
}
function CVT ( ) {
var H = Global _InputVars [ 'HRES' ] ; // Horizontal active pixels
var V = Global _InputVars [ 'VRES' ] ; // Vertical active pixels
var F = Global _InputVars [ 'FREQ' ] ; // Nominal vertical refresh frequency
var S = Global _InputVars [ 'SCAN' ] ; // 1 for progressive scan, 2 for interlaced
var M = Global _InputVars [ 'MARGINS' ] ; // Margins (%)
var INTERLACE = ( S - 1 ) / 2 ;
// Declaring variables for all results
var V _FP ; // Vertical front porch
var V _SW ; // Vertical sync width
var V _BP ; // Vertical back porch
var H _FP ; // Horizontal front porch
var H _SW ; // Horizontal sync width
var H _BP ; // Horizontal back porch
var V _BLANK ; // Total vertical blanking (V_FP + V_SW + V_BP)
var H _BLANK ; // Total horizontal blanking (H_FP + H_SW + H_BP)
var V _EFF ; // V + V_Blank + V_Margins
var H _EFF ; // H + H_Blank + H_Margins
var F _ACTUAL ; // Actual vertical refresh frequency (after pixel clock rounding)
var F _HOR ; // Horizontal refresh frequency
// Constants
var V _SBP _MIN = 0.00055 ; /* Minimum duration of vertical sync + back porch (seconds) */
var V _BP _MIN = 6 ; // Minimum vertical back porch value (lines)
var V _LINES = Math . floor ( V / S ) // If progressive scan, S = 1 and V_LINES = V. If interlaced, V_LINES = floor(V / 2).
V _FP = 3 ; // Vertical front porch value (lines)
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)
// Determine V_SW from table
var V _SYNC _TABLE = [
[ 4 / 3 , 4 , '3' ] ,
[ 16 / 9 , 5 , '9' ] ,
[ 8 / 5 , 6 , 'A' ] ,
[ 5 / 3 , 7 , '9' ] ,
[ 5 / 4 , 7 , '4' ] ,
]
var AR _NAME = '' ;
V _SW = 10 ; // default value defined in standard
for ( var i = 0 ; i < V _SYNC _TABLE . length ; i ++ ) {
if ( Math . abs ( ( H / V ) - V _SYNC _TABLE [ i ] [ 0 ] ) < 0.05 ) { // Check if aspect ratio of image (H/V) matches an aspect ratio defined in table, within 0.05
V _SW = V _SYNC _TABLE [ i ] [ 1 ] ;
AR _NAME = V _SYNC _TABLE [ i ] [ 2 ] ;
}
}
// Estimate horizontal refresh period (seconds)
var H _EST = ( ( 1 / F ) - V _SBP _MIN ) / ( V _LINES + ( 2 * V _MARGIN ) + V _FP + INTERLACE )
// Estimate vertical sync + vertical back porch (lines), subtract V_SW to get V_BP
var V _BP = ( Math . floor ( V _SBP _MIN / H _EST ) + 1 ) - V _SW ;
if ( V _BP < V _BP _MIN ) { V _BP = V _BP _MIN ; } // Enforce minimum value for V_BP
// Total vertical resolution including blanking and margins
V _EFF = V _LINES + ( 2 * V _MARGIN ) + V _FP + V _SW + V _BP + INTERLACE ;
// Horizontal blanking is determined by formula from GTF standard
// Calculate Ideal Duty Cycle (%) from GTF formula
var IDC = 30 - ( 300000 * H _EST ) ;
if ( IDC < 20 ) { IDC = 20 ; } // Enforce minimum value for IDC
// Calculate horizontal blanking time (to next lowest character cell)
H _BLANK = Math . floor ( ( H _RND + ( 2 * H _MARGIN ) ) * IDC / ( 100 - IDC ) / ( 2 * G ) ) * ( 2 * G ) ;
// Total horizontal resolution including blanking and margins
H _EFF = H _RND + ( 2 * H _MARGIN ) + H _BLANK ;
// Determing horizontal timing parameters from magic formulas defined by standard
H _BP = H _BLANK / 2 ;
H _SW = Math . floor ( ( H _SYNC _TARGET _WIDTH * H _EFF ) / G ) * G ;
H _FP = H _BLANK - ( H _BP + H _SW ) ;
// Calculate Pixel Clock (Hz)
var CLK = H _EFF / H _EST ;
CLK = Math . floor ( CLK / 250000 ) * 250000 ; // Enforce pixel clock rounding to nearest 0.25 MHz (250,000 Hz)
// Calculate Horizontal Refresh Frequency (Hz)
F _HOR = CLK / H _EFF ;
// Calculate Vertical Refresh Frequency (Hz) after adjusting for pixel clock rounding
F _ACTUAL = F _HOR / V _EFF ;
return {
'V_FP' : V _FP , // For interlaced, these vertical timing are used for the odd fields
'V_BP' : V _BP ,
'V_SW' : V _SW ,
'H_FP' : H _FP ,
'H_BP' : H _BP ,
'H_SW' : H _SW ,
'V_FP_INT' : V _FP + INTERLACE , // For interlaced, V_FP and V_BP are 0.5 higher for even fields (V_SW is same)
'V_BP_INT' : V _BP + INTERLACE ,
'V_SW_INT' : V _SW ,
'V_BL' : V _BLANK ,
'H_BL' : H _BLANK ,
'V_EFF' : V _EFF ,
'H_EFF' : H _EFF ,
'F_ACTUAL' : F _ACTUAL ,
'VESA_AR' : AR _NAME ,
} ;
}
function CTA ( ) {
DEBUG ( 'Starting CTA' ) ;
var H = Global _InputVars [ 'HRES' ] ;
var V = Global _InputVars [ 'VRES' ] ;
var F = Global _InputVars [ 'FREQ' ] ;
var S = Global _InputVars [ 'SCAN' ] ;
// No CTA formats are below these points, no need to search entire list
if ( H < 640 || V < 240 || F < 23.9 ) { DEBUG ( 'Search aborted, one or more inputs is below the minimum value found in CTA.' , H , V , F ) ; return false ; }
if ( S == 1 ) { S = 'p' ; }
else if ( S == 2 ) { S = 'i' ; }
DEBUG ( 'Input:' , H , V , F , S ) ;
var CTA _H ;
var CTA _V ;
var CTA _F ;
var CTA _S ;
for ( var i = 0 ; i < CTA861 . length ; i ++ ) {
CTA _H = parseFloat ( CTA861 [ i ] [ 'H' ] ) ;
CTA _V = parseFloat ( CTA861 [ i ] [ 'V' ] ) ;
CTA _F = parseFloat ( CTA861 [ i ] [ 'V_FREQ' ] ) ;
CTA _S = CTA861 [ i ] [ 'SCAN' ] ;
DEBUG ( 'Parsing: VIC' , CTA861 [ i ] [ 'VIC' ] , '|' , CTA _H , ( H == CTA _H ) , '|' , CTA _V , ( V == CTA _V ) , '|' , ( CTA _F ) . toFixed ( 3 ) , ( Math . abs ( F - CTA _F ) < 0.01 ) , '|' , CTA _S , ( S == CTA _S ) ) ;
//DEBUG( (V == CTA_V), (Math.abs(F - CTA_F) < 0.01), (S == CTA_S))
if ( ( H == CTA _H ) && ( V == CTA _V ) && ( Math . abs ( F - CTA _F ) < 0.01 ) && ( S == CTA _S ) ) {
DEBUG ( 'Match Found' ) ;
// Special modifications to values based on whether interlacing is selected or not
if ( S == 'p' ) { S = 0 ; }
else if ( S == 'i' ) { S = 0.5 ; }
return {
'V_FP' : parseFloat ( CTA861 [ i ] [ 'V_FP' ] ) ,
'V_BP' : parseFloat ( CTA861 [ i ] [ 'V_BP' ] ) ,
'V_SW' : parseFloat ( CTA861 [ i ] [ 'V_SW' ] ) ,
'H_FP' : parseFloat ( CTA861 [ i ] [ 'H_FP' ] ) ,
'H_BP' : parseFloat ( CTA861 [ i ] [ 'H_BP' ] ) ,
'H_SW' : parseFloat ( CTA861 [ i ] [ 'H_SW' ] ) ,
'V_FP_INT' : parseFloat ( CTA861 [ i ] [ 'V_FP' ] ) + S ,
'V_BP_INT' : parseFloat ( CTA861 [ i ] [ 'V_BP' ] ) + S ,
'V_SW_INT' : parseFloat ( CTA861 [ i ] [ 'V_SW' ] ) ,
'V_BL' : parseFloat ( CTA861 [ i ] [ 'V_BLANK' ] ) - S ,
'H_BL' : parseFloat ( CTA861 [ i ] [ 'H_BLANK' ] ) ,
'V_EFF' : parseFloat ( CTA861 [ i ] [ 'V_EFF' ] ) * ( 1 - S ) ,
'H_EFF' : parseFloat ( CTA861 [ i ] [ 'H_EFF' ] ) ,
'F_ACTUAL' : parseFloat ( CTA861 [ i ] [ 'V_FREQ' ] ) ,
'VIC' : parseFloat ( CTA861 [ i ] [ 'VIC' ] ) ,
'CTA_REV' : CTA861 [ i ] [ 'CTA' ] ,
}
}
}
// Not found in CTA list
return false ;
}
function GTF ( ) {
// Input Variables
var V _FREQ _NOM = Global _InputVars [ 'FREQ' ] ;
var H = Global _InputVars [ 'HRES' ] ;
var V = Global _InputVars [ 'VRES' ] ;
var S = Global _InputVars [ 'SCAN' ] ;
var MARGINS = Global _InputVars [ 'MARGINS' ] ;
// Constants
var V _SW = 3 ; // Vertical sync pulse width (lines)
var V _FP = 1 ; // Vertical front porch (lines)
var V _MIN = 0.00055 ; // Min V_Blank period (seconds)
var G = 8 ; // Cell granularity (pixels)
var H _SYNC _WIDTH _TARGET = 0.08 ; // Nominal horizontal sync pulse duration (percent of horizontal draw period)
var INTERLACE = ( S - 1 ) / 2 ; // 0 for progressive, 0.5 for interlaced
// var m = 600 // Gradient (%/kHz)
// var c = 40 // offset (%)
// var k = 128 // blanking time scaling factor
// var j = 20 // scaling factor weighting
var M = 300 // m * (k / 256); // "M prime"
var C = 30 // (((c - j) * k) / 256) + j; // "C prime"
// Result Variables
var V _BP ;
var H _FP ;
var H _SW ;
var H _BP ;
var H _EFF
var V _EFF ;
var V _BLANK ;
var H _BLANK ;
// Calculations
var V _LINES = Math . round ( V / S ) ;
var V _MARGIN = Math . round ( ( MARGINS / 100 ) * V _LINES ) ;
var H _EST = ( ( 1 / V _FREQ _NOM ) - V _MIN ) / ( V _LINES + ( 2 * V _MARGIN ) + V _FP + INTERLACE ) ; // Horizontal refresh period estimate (seconds)
V _BP = Math . round ( V _MIN / H _EST ) - V _SW ;
V _BLANK = V _FP + V _SW + V _BP ;
V _EFF = V _LINES + V _BLANK + ( 2 * V _MARGIN ) + INTERLACE ; // Total lines
//var V_FREQ_EST = 1 / (H_EST * V_EFF); // Hz
//var H_PER = (H_EST * V_FREQ_EST) / V_FREQ_NOM
var H _PER = 1 / ( V _EFF * V _FREQ _NOM ) ; // Actual horizontal refresh period (seconds)
//var V_FREQ_ACT = 1 / (H_PER * V_EFF); // Hz
var IDC = C - ( M * H _PER * 1000 ) ;
DEBUG ( 'IDC:' , IDC ) ;
var H _MARGIN = Math . round ( ( H * ( MARGINS / 100 ) ) / G ) * G ;
H _BLANK = Math . round ( ( ( ( H + ( 2 * H _MARGIN ) ) * IDC ) / ( 100 - IDC ) ) / ( 2 * G ) ) * ( 2 * G ) ;
H _EFF = ( H + H _BLANK + ( 2 * H _MARGIN ) ) ;
H _SW = Math . round ( ( H _EFF * H _SYNC _WIDTH _TARGET ) / G ) * G ;
H _BP = ( H _BLANK / 2 ) ;
H _FP = H _BP - H _SW ;
//var CLK = H_EFF / H_PER;
//var H_FREQ = 1 / H_PER;
return {
'V_FP' : V _FP ,
'V_BP' : V _BP ,
'V_SW' : V _SW ,
'H_FP' : H _FP ,
'H_BP' : H _BP ,
'H_SW' : H _SW ,
'V_FP_INT' : V _FP + INTERLACE ,
'V_BP_INT' : V _BP + INTERLACE ,
'V_SW_INT' : V _SW ,
'H_BLANK' : H _BLANK ,
'V_BLANK' : V _BLANK ,
'H_EFF' : H _EFF ,
'V_EFF' : V _EFF ,
'F_ACTUAL' : V _FREQ _NOM ,
} ;
}
function DMT ( ) {
DEBUG ( 'Starting DMT Search' ) ;
var H = Global _InputVars [ 'HRES' ] ;
var V = Global _InputVars [ 'VRES' ] ;
var F = Global _InputVars [ 'FREQ' ] ;
var S = Global _InputVars [ 'SCAN' ] ;
// No DMT formats are below these points, no need to search entire list
if ( H < 640 || V < 350 || F < 43 ) { DEBUG ( 'Search aborted, one or more inputs is below the minimum value found in DMT.' , H , V , F ) ; return false ; }
if ( S == 1 ) { S = 'p' ; }
else if ( S == 2 ) { S = 'i' ; }
DEBUG ( 'Input:' , H , V , F , S ) ;
var DMT _H ;
var DMT _V ;
var DMT _F ;
var DMT _S ;
for ( var i = 0 ; i < DMT _List . length ; i ++ ) {
DMT _H = parseFloat ( DMT _List [ i ] [ 'H' ] ) ;
DMT _V = parseFloat ( DMT _List [ i ] [ 'V' ] ) ;
DMT _F = parseFloat ( DMT _List [ i ] [ 'NOM_FREQ' ] ) ;
DMT _F _ACTUAL = parseFloat ( DMT _List [ i ] [ 'V_FREQ' ] )
DMT _S = DMT _List [ i ] [ 'SCAN' ] ;
DEBUG ( 'Parsing: DMT ID' , DMT _List [ i ] [ 'ID' ] , '|' , DMT _H , ( H == DMT _H ) , '|' , DMT _V , ( V == DMT _V ) , '|' , ( DMT _F ) . toFixed ( 3 ) , ( Math . abs ( F - DMT _F ) < 0.01 ) , '|' , DMT _S , ( S == DMT _S ) ) ;
//DEBUG( (V == DMT_V), (Math.abs(F - DMT_F) < 0.01), (S == DMT_S))
if ( ( H == DMT _H ) && ( V == DMT _V ) && ( ( F == DMT _F ) || ( Math . abs ( F - DMT _F _ACTUAL ) < 0.01 ) ) && ( S == DMT _S ) ) {
DEBUG ( 'Match Found' ) ;
// Special modifications to values based on whether interlacing is selected or not
if ( S == 'p' ) { S = 0 ; }
else if ( S == 'i' ) { S = 0.5 ; }
var Timing ;
if ( DMT _List [ i ] [ 'STD' ] == 'CVT' ) {
Timing = CVT ( ) ;
Timing [ 'ID' ] = DMT _List [ i ] [ 'ID' ] ;
}
else if ( DMT _List [ i ] [ 'STD' ] == 'CVTRB' ) {
Timing = CVT _R ( 1 ) ;
Timing [ 'ID' ] = DMT _List [ i ] [ 'ID' ] ;
}
else if ( DMT _List [ i ] [ 'STD' ] == 'CVTR2' ) {
Timing = CVT _R ( 2 ) ;
Timing [ 'ID' ] = DMT _List [ i ] [ 'ID' ] ;
}
else if ( DMT _List [ i ] [ 'STD' ] == 'CTA' ) {
Timing = CTA ( ) ;
Timing [ 'ID' ] = DMT _List [ i ] [ 'ID' ] ;
}
else {
Timing = {
'V_FP' : parseFloat ( DMT _List [ i ] [ 'V_FP' ] ) ,
'V_BP' : parseFloat ( DMT _List [ i ] [ 'V_BP' ] ) ,
'V_SW' : parseFloat ( DMT _List [ i ] [ 'V_SW' ] ) ,
'H_FP' : parseFloat ( DMT _List [ i ] [ 'H_FP' ] ) ,
'H_BP' : parseFloat ( DMT _List [ i ] [ 'H_BP' ] ) ,
'H_SW' : parseFloat ( DMT _List [ i ] [ 'H_SW' ] ) ,
'V_FP_INT' : parseFloat ( DMT _List [ i ] [ 'V_FP' ] ) + S ,
'V_BP_INT' : parseFloat ( DMT _List [ i ] [ 'V_BP' ] ) + S ,
'V_SW_INT' : parseFloat ( DMT _List [ i ] [ 'V_SW' ] ) ,
'V_BL' : parseFloat ( DMT _List [ i ] [ 'V_BLANK' ] ) - S ,
'H_BL' : parseFloat ( DMT _List [ i ] [ 'H_BLANK' ] ) ,
'V_EFF' : parseFloat ( DMT _List [ i ] [ 'V_EFF' ] ) * ( 1 - S ) ,
'H_EFF' : parseFloat ( DMT _List [ i ] [ 'H_EFF' ] ) ,
'F_ACTUAL' : parseFloat ( DMT _List [ i ] [ 'V_FREQ' ] ) ,
'ID' : parseFloat ( DMT _List [ i ] [ 'ID' ] ) ,
}
}
return Timing ;
}
}
// Not found in DMT list
return false ;
}
function updateDisplay ( mode ) {
var clear = 'clear'
var cells ;
var id ;
id _list = [
'data_rate' , '8b10b' , '16b18b' , 'pixel_rate' , 'pixel_rate_active' ,
'bpc' , 'bpp' , 'palette' ,
'v_freq' , 'v_freq_actual' , 'v_freq_dev' , 'v_freq_dev_perc' ,
'v_per' , 'v_per_actual' , 'v_per_dev' , 'v_per_dev_perc' ,
'h_freq' , 'h_per' ,
'v_field' , 'v_field_actual' , 'v_field_dev' , 'v_field_dev_perc' ,
'v_field_per' , 'v_field_per_actual' , 'v_field_per_dev' , 'v_field_per_dev_perc' ,
'v_frame' , 'v_frame_actual' , 'v_frame_dev' , 'v_frame_dev_perc' ,
'v_frame_per' , 'v_frame_per_actual' , 'v_frame_per_dev' , 'v_frame_per_dev_perc' ,
] ;
for ( var x = 0 ; x < id _list . length ; x ++ ) {
id = id _list [ x ] ;
cells = $ ( '#results_' + id ) . children ( ) ;
if ( mode != clear ) {
DEBUG ( 'Detailed Results:' , Detailed _Results [ id ] ) ;
DEBUG ( 'Cells:' , cells )
cells [ 1 ] . innerHTML = Detailed _Results [ id ] [ 'val' ] ;
cells [ 2 ] . innerHTML = Detailed _Results [ id ] [ 'unit' ] ;
} else {
cells [ 1 ] . innerHTML = '' ;
cells [ 2 ] . innerHTML = '' ;
}
}
id _list = [ 'active_px' , 'blank_px' , 'total_px' , 'overhead_px' ] ;
for ( var x = 0 ; x < id _list . length ; x ++ ) {
id = id _list [ x ] ;
cells = $ ( '#results_' + id ) . children ( ) ;
if ( mode != clear ) {
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' ] ;
} else {
cells [ 1 ] . innerHTML = '' ;
cells [ 2 ] . innerHTML = '' ;
cells [ 3 ] . innerHTML = '' ;
cells [ 4 ] . innerHTML = '' ;
}
}
id _list = [ 'px_format' , 'scan' ] ;
for ( var x = 0 ; x < id _list . length ; x ++ ) {
id = id _list [ x ] ;
cells = $ ( '#results_' + id ) . children ( ) ;
if ( mode != clear ) {
DEBUG ( 'Detailed Results:' , Detailed _Results [ id ] ) ;
DEBUG ( 'Cells:' , cells )
cells [ 1 ] . innerHTML = Detailed _Results [ id ]
} else {
cells [ 1 ] . innerHTML = '' ;
}
}
return ;
}
function clearResults ( ) {
updateDisplay ( 'clear' ) ;
if ( $ ( '#TIMING_DROP' ) . val ( ) != 'Custom' ) {
clearTiming ( ) ;
}
return ;
}
function timingUIChange ( ) {
// Controls the enabled/disabled state of the custom timing format input fields
var timing _params = [
$ ( '#V_FP' ) ,
$ ( '#V_BP' ) ,
$ ( '#V_SW' ) ,
$ ( '#H_FP' ) ,
$ ( '#H_BP' ) ,
$ ( '#H_SW' ) ,
$ ( '#V_FP_INT' ) ,
$ ( '#V_BP_INT' ) ,
$ ( '#V_SW_INT' ) ,
] ;
value = $ ( '#TIMING_DROP' ) . val ( ) ;
if ( value == 'Custom' ) {
for ( var i = 0 ; i < timing _params . length ; i ++ ) {
param = timing _params [ i ] ;
param . prop ( 'disabled' , false ) ;
//if (field.prop('oldvalue') != '') {
// field.val(field.prop('oldvalue'));
//}
}
}
else {
for ( var i = 0 ; i < timing _params . length ; i ++ ) {
param = timing _params [ i ] ;
param . prop ( 'disabled' , true ) ;
//field.prop('oldvalue', field.val());
//field.val('');
}
}
value = $ ( 'input[name=SCAN_SLCT]:checked' ) . val ( ) ;
if ( value == 'i' ) {
$ ( '#V_BLANK_INT_LABEL' ) . css ( 'display' , 'table-cell' ) ;
$ ( '#V_FP_INT_CONTAINER' ) . css ( 'display' , 'table-cell' ) ;
$ ( '#V_BP_INT_CONTAINER' ) . css ( 'display' , 'table-cell' ) ;
$ ( '#V_SW_INT_CONTAINER' ) . css ( 'display' , 'table-cell' ) ;
$ ( '#V_BLANK_INT_CONTAINER' ) . css ( 'display' , 'table-cell' ) ;
$ ( '#V_BLANK_EVEN_LABEL' ) . html ( '(Even) V<sub>blank</sub>' ) ;
$ ( '#results_v_progressive' ) . css ( 'display' , 'none' ) ;
$ ( '#results_v_interlaced' ) . css ( 'display' , 'table' ) ;
}
else if ( value == 'p' ) {
$ ( '#V_BLANK_INT_LABEL' ) . css ( 'display' , 'none' ) ;
$ ( '#V_FP_INT_CONTAINER' ) . css ( 'display' , 'none' ) ;
$ ( '#V_BP_INT_CONTAINER' ) . css ( 'display' , 'none' ) ;
$ ( '#V_SW_INT_CONTAINER' ) . css ( 'display' , 'none' ) ;
$ ( '#V_BLANK_INT_CONTAINER' ) . css ( 'display' , 'none' ) ;
$ ( '#V_BLANK_EVEN_LABEL' ) . html ( 'V<sub>blank</sub>' ) ;
$ ( '#results_v_progressive' ) . css ( 'display' , 'table' ) ;
$ ( '#results_v_interlaced' ) . css ( 'display' , 'none' ) ;
}
else {
DEBUG ( 'Something somewhere has gone terribly wrong. Attemped to grab SCAN_SLCT value, and it was neither "p" nor "i"!' ) ;
}
}
function colordepthUIChange ( ) {
// Controls the enabled/disabled state of the custom timing format input fields
var field = $ ( '#CUSTOM_COLOR_DEPTH' ) ;
value = $ ( 'input[name=COLOR_DEPTH_SLCT]:checked' ) . val ( ) ;
if ( value == 'Custom' ) {
field . prop ( 'disabled' , false ) ;
$ ( 'input[name=CD_UNIT_SLCT]' ) . prop ( 'disabled' , false ) ;
}
else {
field . prop ( 'disabled' , true ) ;
$ ( 'input[name=CD_UNIT_SLCT]' ) . prop ( 'disabled' , true ) ;
}
}
function marginsUIChange ( ) {
// Controls the enabled/disabled state of the custom timing format input fields
var field = $ ( '#CUSTOM_MARGINS' ) ;
value = $ ( 'input[name=MARGINS_SLCT]:checked' ) . val ( ) ;
if ( value == 'y' ) {
field . prop ( 'disabled' , false ) ;
if ( field . val ( ) == '' ) {
field . val ( '1.8' ) ;
}
}
else {
field . prop ( 'disabled' , true ) ;
}
}
function LoadCTA861 ( ) {
// Loads the timing definitions for the CTA-861 standard from a txt file
//DEBUG('CTA Test 11');
var request = new XMLHttpRequest ( ) ;
request . open ( 'GET' , 'CTA861.txt' , true ) ;
request . send ( null ) ;
request . onreadystatechange = function ( ) {
DEBUG ( 'request.status:' , request . status )
if ( request . readyState === 4 && ( request . status === 200 || request . status === 0 ) ) {
CTA861 = $ . csv . toObjects ( request . responseText ) ;
//DEBUG(CTA861);
}
}
DEBUG ( 'Finished' ) ;
}
function LoadDMT ( ) {
// Loads the timing definitions for the DMT standard from a txt file
DEBUG ( 'DMT Test 1' ) ;
var request = new XMLHttpRequest ( ) ;
request . open ( 'GET' , 'DMT.txt' , true ) ;
request . send ( null ) ;
request . onreadystatechange = function ( ) {
DEBUG ( 'request.status:' , request . status )
if ( request . readyState === 4 && ( request . status === 200 || request . status === 0 ) ) {
DMT _List = $ . csv . toObjects ( request . responseText ) ;
//DEBUG(CTA861);
}
}
DEBUG ( 'Finished' ) ;
}
//Small functions
{
function Commas ( num ) {
var parts = num . toString ( ) . split ( "." ) ;
parts [ 0 ] = parts [ 0 ] . replace ( /\B(?=(\d{3})+(?!\d))/g , "," ) ;
return parts . join ( "." ) ;
}
function getPrecision ( x , watchdog ) {
// https://stackoverflow.com/questions/27082377/get-number-of-decimal-places-with-javascript
x = Math . abs ( x ) ;
watchdog = watchdog || 32 ;
var i = 0 ;
while ( x % 1 > 0 && i < watchdog ) {
i ++ ;
x = x * 10 ;
}
return i ;
}
function GCD ( a , b ) {
a = Math . abs ( a ) ;
b = Math . abs ( b ) ;
if ( b > a ) { var temp = a ; a = b ; b = temp ; }
while ( true ) {
if ( b == 0 ) return a ;
a %= b ;
if ( a == 0 ) return b ;
b %= a ;
}
}
function SameRatio ( H , V , A ) {
/* Checks if the ratio H/V is equal to the given ratio A (within a defined margin of error E) */
/* Negative signs on H, V, and A are ignored */
var E = 0.001 ; /* E is a percent error written as a decimal (i.e. E = 0.001 would give an acceptable error margin of 0.1%) */
if ( Math . abs ( ( Math . abs ( H / V ) / Math . abs ( A ) ) - 1 ) <= E ) { return true ; }
else { return false ; }
}
function long _division ( A , B , options ) {
if ( isNaN ( A / B ) || ! isFinite ( A / B ) ) { DEBUG ( 'Answer is NaN or Infinity. Function aborted.' ) ; return '' ; }
var OL _open = '<span style="text-decoration:overline;">' ; // Overline markup opening tag
var OL _close = '</span>' ; // Overline markup closing tag. Used in conjunction with OL_open to surround the repeating numbers. May be set to control markup, separate it with parentheses, or simply left blank, etc.
var p _max = 8 ; // Maximum number of decimal places
var p _min = 3 ; // Minimum number of decimal places
var Approx = '≈' ; // Symbol to be used for "approximately equal to". Can be set to '~' or blank if desired, etc.
var Radix _Point = '.' ; // Character to use for the radix point ("decimal point")
var Base = 10 ; // Number base system to use
var Minus _Sign = '−' ; // Character to preceed negative numbers
var Plus _Sign = '' ; // Character to preceed positive numbers
var RepeatSinglesFlag = true ; // Display single-digit repeating patterns as 1.(33) instead of 1.(3)
if ( typeof ( options ) === 'number' ) { // If 3rd argument is a number rather than a dictionary, use it as the p_max value
p _max = options ;
}
else if ( options ) {
if ( 'OL_open' in options ) { OL _open = options [ 'OL_open' ] ; }
if ( 'OL_close' in options ) { OL _close = options [ 'OL_close' ] ; }
if ( 'p_max' in options ) { p _max = options [ 'p_max' ] ; }
if ( 'p_min' in options ) { p _min = options [ 'p_min' ] ; }
if ( 'radix' in options ) { Radix _Point = options [ 'radix' ] ; }
if ( 'approx' in options ) { Approx = options [ 'approx' ] ; }
if ( 'minus' in options ) { Minus _Sign = options [ 'minus' ] ; }
if ( 'plus' in options ) { Plus _Sign = options [ 'plus' ] ; }
if ( 'base' in options ) { Base = options [ 'base' ] ; }
if ( 'repeat_singles' in options ) { RepeatSinglesFlag = options [ 'repeat_singles' ] ; }
}
p _max = parseInt ( p _max ) ;
p _min = parseInt ( p _min ) ;
Base = parseInt ( Base ) ;
if ( p _max < 0 || p _min < 0 || p _max < p _min || isNaN ( p _max ) || isNaN ( p _min ) || ! isFinite ( p _max ) || ! isFinite ( p _min ) ) {
DEBUG ( 'Invalid p_max and p_min values. Both values must be non-negative numbers, and p_min cannot be greater than p_max. p_max:' , p _max , 'p_min' , p _min )
return '' ;
}
if ( isNaN ( Base ) ) {
DEBUG ( 'Invalid Base value. Must be an integer number. Base:' , Base ) ;
return '' ;
}
if ( p _max == 0 ) {
var Result = Math . round ( A / B ) . toFixed ( 0 ) ;
if ( Result != ( A / B ) ) { Result = '≈' . concat ( Result ) ; }
return Result ;
}
var Max _Depth = 32 ; // Depth of internal calculations, regardless of p_max or p_min settings
var Decimal _Digits = '' ;
var Previous _Dividends = { } ;
var Prefix = '' ;
var Repetend = '' ;
var RepeatFlag = false ;
var ApproxFlag = true ;
var Sign = Plus _Sign ;
// Determine if answer will be negative, then use the absolute value of inputs for the rest of the calculations.
if ( ( A < 0 ) ? ! ( B < 0 ) : ( B < 0 ) ) { Sign = Minus _Sign ; } // If (A is negative) XOR (B is negative) then final result will be negative.
var Dividend = Math . abs ( parseFloat ( A ) ) ;
var Divisor = Math . abs ( parseFloat ( B ) ) ;
var Quotient = Dividend / Divisor ;
var Remainder = Dividend % Divisor ;
var Result = Math . floor ( Quotient ) . toString ( ) + Radix _Point ; // Use floor division to determine the front part of the number immediately
Dividend = Remainder * Base ;
// Use long division for the decimal places, so that repeating decimals can be detected
var i = 0 ;
while ( i < p _max + 2 ) {
if ( ! ( Dividend in Previous _Dividends ) ) {
Previous _Dividends [ Dividend ] = i ;
Quotient = Dividend / Divisor ;
Remainder = Dividend % Divisor ;
Dividend = Remainder * Base ;
//if (i < p_max) {
Decimal _Digits += Math . floor ( Quotient ) . toString ( ) ;
//}
//DEBUG('i:', i, 'Quotient:', Quotient, 'Remainder:', Remainder, 'Dividend:', Dividend, 'Result:', Result, 'Decimal_Digits:', Decimal_Digits);
}
else {
RepeatFlag = true ;
ApproxFlag = false ;
Prefix = Decimal _Digits . substring ( 0 , Previous _Dividends [ Dividend ] ) ;
Repetend = Decimal _Digits . substring ( Previous _Dividends [ Dividend ] , Decimal _Digits . length ) ;
if ( Repetend == '0' ) { // A "repeating" dividend of 0 signals a non-repeating result
Repetend = '' ;
RepeatFlag = false ;
Decimal _Digits = Prefix ;
}
//Decimal_Digits = Prefix + Repetend;
break ;
}
i += 1 ;
}
if ( RepeatFlag == false ) {
if ( Decimal _Digits . length > p _max ) {
//Decimal_Digits = Decimal_Digits.substr(0, p_max);
Decimal _Digits = Math . round ( parseFloat ( Decimal _Digits . substr ( 0 , p _max ) + '.' + Decimal _Digits . substr ( p _max ) ) ) . toString ( ) ;
if ( p _max - Decimal _Digits . length >= 0 ) {
Decimal _Digits = '0' . repeat ( p _max - Decimal _Digits . length ) + Decimal _Digits ;
}
ApproxFlag = true ;
}
if ( Decimal _Digits . length < p _min ) {
if ( p _min - Decimal _Digits . length >= 0 ) {
Decimal _Digits += '0' . repeat ( p _min - Decimal _Digits . length ) ;
}
}
}
if ( RepeatFlag == true ) {
if ( Prefix . length + Repetend . length > p _max ) {
if ( Prefix . length > p _max ) {
Prefix = Math . round ( parseFloat ( Prefix . substr ( 0 , p _max ) + '.' + Prefix . substr ( p _max ) ) ) . toString ( ) ;
if ( p _max - Prefix . length >= 0 ) {
Prefix = '0' . repeat ( p _max - Prefix . length ) + Prefix ;
}
}
else {
Prefix = Prefix + Repetend . substr ( 0 , p _max - Prefix . length ) ;
}
Decimal _Digits = Prefix ;
RepeatFlag = false ;
ApproxFlag = true ;
}
if ( Prefix . length + Repetend . length < p _min ) {
if ( ( p _min - ( Prefix . length + Repetend . length ) ) >= Repetend . length ) {
Repetend += Repetend . repeat ( Math . floor ( ( p _min - ( Prefix . length + Repetend . length ) ) / Repetend . length ) ) ;
}
while ( Prefix . length + Repetend . length < p _min ) {
Prefix = Prefix . concat ( Repetend [ 0 ] ) ;
Repetend = Repetend . slice ( 1 ) . concat ( Repetend [ 0 ] ) ;
}
}
}
if ( RepeatFlag == true ) {
if ( Repetend . length == 1 && ( Prefix . length + Repetend . length < p _max ) && RepeatSinglesFlag == true ) { Repetend = Repetend . repeat ( 2 ) ; } // Single-digit repetitions will be displayed twice, i.e. 4/3 will result in 1.(33) rather than 1.(3)
Result += Prefix + OL _open + Repetend + OL _close ;
}
else {
Result += Decimal _Digits ;
}
Result = Sign . concat ( Result ) ;
if ( ApproxFlag == true ) {
Result = Approx . concat ( Result ) ;
}
if ( Result [ Result . length - 1 ] == Radix _Point ) { Result = Result . replace ( Radix _Point , '' ) ; }
return Result ;
//return Result * Sign;
}
/ *
function parseNum ( val ) {
// Converts string to floating point if it has a decimal point, or integer if there is no decimal point. Also strips commas and spaces, and optionally applies absolute value.
if ( typeof val === "string" ) {
// val = val.replace(/[^0-9\. ]/g, ''); // Apply absolute value and ignore non-numeric characters
// val = val.replace(/[^0-9\. -]/g, ''); // Allow negative numbers and ignore non-numeric characters
//val = val.replace(/-/g, ''); // Remove minus signs
// Return NaN if...
if ( val == '' // input is blank
|| val . indexOf ( '.' ) != val . lastIndexOf ( '.' ) // input contains multiple decimal places
|| val . indexOf ( '-' ) != val . lastIndexOf ( '-' ) // input contains multiple minus signs
|| ( val . indexOf ( '-' ) != - 1 && val . indexOf ( '-' ) != 0 ) // input contains a minus sign in a position other than the first character
|| val . match ( /[^0-9.-]/g ) ) // input contains any character other than a number, decimal, minus, or space
{
return NaN ;
}
else {
// Once we have checked that the input contains no characters other than numerals, periods, and minus signs
// And that there are at most one period and one minus sign, and both are in valid positions, we can evaluate the number as either float or string.
// If for some reason either of them fail, it will still return NaN anyway
if ( val . indexOf ( '.' ) == - 1 )
return parseInt ( val ) ;
else {
return parseFloat ( val ) ;
}
}
}
else if ( Number . isNaN ( val ) ) {
return NaN ; // Check if val is literally 'NaN'
}
else if ( typeof val === "number" ) {
return val ; // NaN is recognized as a number, so this line must be after NaN is handled
}
else {
return NaN ;
}
} * /
function parseNum ( val ) {
// This function is designed to interpret strings with formatted numbers (which may contain currencies, digit grouping commas, units, etc.)
// It will return NaN if it cannot be interpreted as a valid number (i.e. no numeric characters, multiple periods or minus signs, etc.)
if ( typeof ( val ) === 'number' ) {
// If the input argument is already a number, then nothing needs to be done, simply return the input value
if ( Number . isNaN ( val ) == true ) {
// However, we do need to check that it isn't NaN, because that is identified as a number.
return NaN ;
}
else {
return 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 ++ ) {
// Loop through each character starting from the front
if ( ! ( i < val . length ) ) { break ; }
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, 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, so the loop counter must be adjusted to compensate
continue ;
}
else if ( ( /[-]/g ) . test ( val [ i ] ) == true ) {
// 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 ) {
// If character is a period, then following character MUST be a digit, unless it's the end of the number. Otherwise the input is not a valid number.
if ( i + 1 < val . length ) {
if ( ( /[0-9]/g ) . test ( val [ i + 1 ] ) == true ) {
// If the character after the period is a digit, then the "number" part of the number has definitely been reached and the code can proceed with the next section.
break ;
}
else {
// If the string contained a period followed by a non-numeric character, it cannot be interpreted as a valid number. Return NaN.
return NaN ;
}
}
else {
// If i+1 was not < val.length, then the period is the last character in the string, which implicitly means the string contains no numeric characters.
return NaN ;
}
}
else if ( ( /[0-9]/g ) . test ( val [ i ] ) == true ) {
// If character was a numeric character, we have successfully stripped any leading characters and reached the start of the number.
break ;
}
}
// 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
// Since we are dealing with the end of the number, minus signs are no longer part of the number. Periods at the end are valid, but superfluous
// Since we are only checking the characters after the digits have ended, minus signs are not invalid, as they may be part of a unit of measurement. Therefore, they are simply removed, rather than returning NaN.
if ( val . length == 1 ) { return NaN ; }
else { val = val . slice ( 0 , i ) ; }
continue ;
}
else if ( ( /[0-9]/g ) . test ( val [ i ] ) == true ) {
// If character is a numeric character, we have reached the back end of the number and successfully stripped any trailing characters.
break ;
}
}
// We now strip any commas and whitespace throughout the string
val = val . replace ( /[, ]/g , '' ) ;
// If, after removing leading and trailing units, whitespace, and commas, there are any non-numeric characters (i.e. in the middle of the string after the numbers start), it is not a valid number
if ( ( /[^0-9.-]/g ) . test ( val ) == true ) {
return NaN ;
}
// Now that the string only contains numeric characters, minus signs, and periods, we must check if there are any invalid usages of the periods and signs, such as multiple periods/signs, or a minus sign anywhere other than the first character.
if ( val == '' // string is empty
|| val . indexOf ( '.' ) != val . lastIndexOf ( '.' ) // string contains multiple periods
|| val . indexOf ( '-' ) != val . lastIndexOf ( '-' ) // string contains multiple minus signs
|| ( val . indexOf ( '-' ) != - 1 && val . indexOf ( '-' ) != 0 ) ) // input contains a minus sign and it isn't the first character
{
return NaN ;
}
// Finished; string now only contains numbers, up to one period, and up to one minus sign as the first character of the string.
// If for some reason the parseFloat fails, the function will return NaN, so the output is still consistent with any other failed condition.
return parseFloat ( val ) ;
}
}
function isNum ( num ) {
// Returns false if input is not a number, including a blank string or NaN
// Can accept arrays, and returns true only if all elements would return true individually
if ( Array . isArray ( num ) == true ) {
for ( a = 0 ; a < num . length ; a ++ ) {
if ( Number . isNaN ( parseFloat ( num [ a ] ) ) == true ) {
return false ;
}
return true ;
}
}
else {
return ! Number . isNaN ( parseFloat ( num ) ) ;
}
}
function isPositive ( num ) {
if ( Array . isArray ( num ) == true ) {
for ( a = 0 ; a < num . length ; a ++ ) {
if ( Number . isNaN ( parseNum ( num [ a ] ) ) == true )
return false ;
else if ( num [ a ] <= 0 )
return false ;
}
return true ;
}
else {
if ( Number . isNaN ( parseNum ( num ) ) == true )
return false ;
else if ( num > 0 )
return true ;
else {
return false ;
}
}
}
function isPositiveZ ( num ) {
// Returns true if input is positive or zero. Can recognize formatted numbers (i.e. "1,234,567 Gbit/s" or "-$1,234 USD") as allowed by parseNum
// Combine with isNum() to allow only true (non-formatted) numbers and strings (i.e. if (isNum(x) && isPositiveZ(x))
/ *
True :
isPositiveZ ( 1 )
isPositiveZ ( '1' )
isPositiveZ ( 1.1 )
isPositiveZ ( '1.1' )
isPositiveZ ( '1.' ) Number string with stray decimal
isPositiveZ ( 0 ) or ( '0' )
isPositiveZ ( Infinity )
isPositiveZ ( [ 1 , '2' , 3.3 ] ) true iff all elements are non - negative
False :
isPositiveZ ( - 1 )
isPositiveZ ( '-1' )
isPositiveZ ( - 1.1 )
isPositiveZ ( '-1.1' )
isPositiveZ ( '1 ' ) Number with whitespace
isPositiveZ ( '' ) Empty String
isPositiveZ ( 'abc' )
isPositiveZ ( NaN )
isPositiveZ ( [ - 1 , '2' , 3.3 ] ) If any element is negative
* /
if ( Array . isArray ( num ) == true ) {
for ( a = 0 ; a < num . length ; a ++ ) {
if ( Number . isNaN ( parseNum ( num [ a ] ) ) == true )
return false ;
else if ( num [ a ] < 0 )
return false ;
}
return true ;
}
else {
if ( Number . isNaN ( parseNum ( num ) ) == true )
return false ;
else if ( num >= 0 )
return true ;
else {
return false ;
}
}
}
function isInt ( num ) {
/ *
True :
isInt ( 1 )
isInt ( '1' )
isInt ( - 1 )
isInt ( '-1' )
isInt ( 0 )
isInt ( [ 1 , - 2 , '3' ] )
isInt ( 1 , 'a' ) - > true ( be careful to enter multiple arguments as an array , otherwise it will only evaluate the first argument , as seen here )
False :
isInt ( 1.1 )
isInt ( '1 ' )
isInt ( '1 2' )
isInt ( 'abc' )
isInt ( 'abc123' )
isInt ( '' )
isInt ( NaN )
isInt ( Infinity )
isInt ( [ 1 , 2 , 3.3 ] ) Returns false if any of the array elements are not an integer
* /
if ( Array . isArray ( num ) == true ) {
for ( a = 0 ; a < num . length ; a ++ ) {
if ( Number . isInteger ( parseNum ( num [ a ] ) ) == false ) {
return false ;
}
}
return true ;
}
else {
num = parseNum ( num ) ;
return Number . isInteger ( num ) ;
}
}
function isFloat ( num ) {
/ *
True :
isFloat ( 1.1 )
isFloat ( '1.1' )
isFloat ( - 1.1 )
isFloat ( '-1.1' )
isFloat ( '.1' )
isFloat ( '-.1' )
isFloat ( [ 1.1 , - 1.2 , '1.3' ] )
isFloat ( Infinity )
isFloat ( [ 1.1 , 'a' ] ) - > true ( be careful to enter multiple arguments as an array , otherwise it will only evaluate the first argument , as seen here )
False :
isFloat ( 1.0 )
isFloat ( '1.0' )
isFloat ( 0 )
isFloat ( 1 )
isFloat ( '1.1.1' )
isFloat ( '' )
isFloat ( 'a' )
isFloat ( '1.1a' )
isFloat ( [ 1.1 , 1.2 , 3 ] )
isFloat ( NaN )
* /
if ( Array . isArray ( num ) == true ) {
for ( a = 0 ; a < num . length ; a ++ ) {
num [ a ] = parseNum ( num [ a ] ) ;
if ( Number . isInteger ( num [ a ] ) == true || Number . isNaN ( num [ a ] ) == true ) {
return false ;
}
}
return true ;
}
else {
num = parseNum ( num ) ;
return ! ( Number . isInteger ( num ) || Number . isNaN ( 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 ( ) ;
$ ( '#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 = function ( ) {
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 ( ) ;
$ ( '#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 ( ) ;
}