Merged Mathbox 3D support (gl3)
This commit is contained in:
		| @@ -129,9 +129,9 @@ To use a HackRF, compile the HackRF host tools from its "stdout" branch: | ||||
| #format_conversion="csdr convert_s16_f | csdr gain_ff 30" | ||||
|  | ||||
| # >> /dev/urandom test signal source | ||||
| #samp_rate = 2400000 | ||||
| #start_rtl_command="cat /dev/urandom | (pv -qL `python -c 'print int({samp_rate} * 2.2)'` 2>&1)".format(rf_gain=rf_gain, center_freq=center_freq, samp_rate=samp_rate) | ||||
| #format_conversion="csdr convert_u8_f" | ||||
| samp_rate = 2400000 | ||||
| start_rtl_command="cat /dev/urandom | (pv -qL `python -c 'print int({samp_rate} * 2.2)'` 2>&1)".format(rf_gain=rf_gain, center_freq=center_freq, samp_rate=samp_rate) | ||||
| format_conversion="csdr convert_u8_f" | ||||
|  | ||||
| # >> Pre-recorded raw I/Q file as signal source | ||||
| # You will have to correctly specify: samp_rate, center_freq, format_conversion in order to correctly play an I/Q file. | ||||
| @@ -190,9 +190,14 @@ waterfall_auto_level_margin = (5, 40) | ||||
| #   ___|____________________________________|____________________________________|____________________________________|___> signal power | ||||
| #        \_waterfall_auto_level_margin[0]_/ |__ current_min_power_level          | \_waterfall_auto_level_margin[1]_/ | ||||
| #                                                      current_max_power_level __| | ||||
| # ==== Experimental settings === | ||||
|  | ||||
| #Warning! These are very experimental. | ||||
| # 3D view settings | ||||
| mathbox_waterfall_frequency_resolution = 128 #bins | ||||
| mathbox_waterfall_history_length = 10 #seconds | ||||
| mathbox_waterfall_colors = "[0x000000ff,0x2e6893ff, 0x69a5d0ff, 0x214b69ff, 0x9dc4e0ff,  0xfff775ff, 0xff8a8aff, 0xb20000ff]" | ||||
|  | ||||
| # === Experimental settings === | ||||
| #Warning! The settings below are very experimental. | ||||
| csdr_dynamic_bufsize = False # This allows you to change the buffering mode of csdr. | ||||
| csdr_print_bufsizes = False  # This prints the buffer sizes used for csdr processes. | ||||
| csdr_through = False # Setting this True will print out how much data is going into the DSP chains. | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								htdocs/gfx/openwebrx-3d-spectrum.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								htdocs/gfx/openwebrx-3d-spectrum.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 9.9 KiB | 
| @@ -28,15 +28,19 @@ | ||||
|             var ws_url="%[WS_URL]"; | ||||
|             var rx_photo_height=%[RX_PHOTO_HEIGHT]; | ||||
|             var audio_buffering_fill_to=%[AUDIO_BUFSIZE]; | ||||
|             var starting_mod = "%[START_MOD]"; | ||||
| 			var starting_mod="%[START_MOD]"; | ||||
|             var starting_offset_frequency = %[START_OFFSET_FREQ]; | ||||
|             var waterfall_colors=%[WATERFALL_COLORS]; | ||||
|             var waterfall_min_level_default=%[WATERFALL_MIN_LEVEL]; | ||||
|             var waterfall_max_level_default=%[WATERFALL_MAX_LEVEL]; | ||||
|             var waterfall_auto_level_margin=%[WATERFALL_AUTO_LEVEL_MARGIN]; | ||||
|             var server_enable_digimodes=%[DIGIMODES_ENABLE]; | ||||
| 			var mathbox_waterfall_frequency_resolution=%[MATHBOX_WATERFALL_FRES]; | ||||
| 			var mathbox_waterfall_history_length=%[MATHBOX_WATERFALL_THIST]; | ||||
| 			var mathbox_waterfall_colors=%[MATHBOX_WATERFALL_COLORS]; | ||||
|         </script> | ||||
|         <script src="sdr.js"></script> | ||||
| 		<script src="mathbox-bundle.min.js"></script> | ||||
|         <script src="openwebrx.js"></script> | ||||
|         <script src="jquery-3.2.1.min.js"></script> | ||||
|         <script src="jquery.nanoscroller.js"></script> | ||||
| @@ -77,8 +81,8 @@ | ||||
|             <div id="openwebrx-scale-container"> | ||||
|                 <canvas id="openwebrx-scale-canvas" width="0" height="0"></canvas> | ||||
|             </div> | ||||
| 			<div id="openwebrx-mathbox-container"> </div> | ||||
|             <div id="webrx-canvas-container"> | ||||
|  | ||||
|                 <div id="openwebrx-phantom-canvas"></div> | ||||
|                 <!-- add canvas here by javascript --> | ||||
|             </div> | ||||
| @@ -122,6 +126,8 @@ | ||||
|                         <div class="openwebrx-button openwebrx-square-button" onclick="zoomOutOneStep();" title="Zoom out one step"> <img src="gfx/openwebrx-zoom-out.png" /></div> | ||||
|                         <div class="openwebrx-button openwebrx-square-button" onclick="zoomInTotal();"  title="Zoom in totally"><img src="gfx/openwebrx-zoom-in-total.png" /></div> | ||||
|                         <div class="openwebrx-button openwebrx-square-button" onclick="zoomOutTotal();" title="Zoom out totally"><img src="gfx/openwebrx-zoom-out-total.png" /></div> | ||||
| 						<div class="openwebrx-button openwebrx-square-button" onclick="mathbox_toggle();" title="Zoom out totally"><img src="gfx/openwebrx-3d-spectrum.png" /></div> | ||||
| 						<div class="openwebrx-button openwebrx-square-button" onclick="mathbox_toggle();" title="Zoom out totally"><img src="gfx/openwebrx-3d-spectrum.png" /></div> | ||||
|                         <div id="openwebrx-smeter-db">0 dB</div> | ||||
|                     </div> | ||||
|                     <div class="openwebrx-panel-line"> | ||||
|   | ||||
							
								
								
									
										33
									
								
								htdocs/mathbox-bundle.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								htdocs/mathbox-bundle.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										461
									
								
								htdocs/mathbox.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										461
									
								
								htdocs/mathbox.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,461 @@ | ||||
| .shadergraph-graph { | ||||
|   font: 12px sans-serif; | ||||
|   line-height: 25px; | ||||
|   position: relative; | ||||
| } | ||||
| .shadergraph-graph:after { | ||||
|   content: ' '; | ||||
|   display: block; | ||||
|   height: 0; | ||||
|   font-size: 0; | ||||
|   clear: both; | ||||
| } | ||||
| .shadergraph-graph svg { | ||||
|   pointer-events: none; | ||||
| } | ||||
| .shadergraph-clear { | ||||
|   clear: both; | ||||
| } | ||||
| .shadergraph-graph svg { | ||||
|   position: absolute; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   top: 0; | ||||
|   bottom: 0; | ||||
|   width: auto; | ||||
|   height: auto; | ||||
| } | ||||
| .shadergraph-column { | ||||
|   float: left; | ||||
| } | ||||
| .shadergraph-node .shadergraph-graph { | ||||
|   float: left; | ||||
|   clear: both; | ||||
|   overflow: visible; | ||||
| } | ||||
| .shadergraph-node .shadergraph-graph .shadergraph-node { | ||||
|   margin: 5px 15px 15px;  | ||||
| } | ||||
| .shadergraph-node { | ||||
|   margin: 5px 15px 25px;  | ||||
|   background: rgba(0, 0, 0, .1); | ||||
|   border-radius: 5px; | ||||
|   box-shadow: 0 1px  2px rgba(0, 0, 0, .2), | ||||
|               0 1px  10px rgba(0, 0, 0, .2); | ||||
|   min-height: 35px; | ||||
|   float: left; | ||||
|   clear: left; | ||||
|   position: relative; | ||||
| } | ||||
| .shadergraph-type { | ||||
|   font-weight: bold; | ||||
| } | ||||
| .shadergraph-header { | ||||
|   font-weight: bold; | ||||
|   text-align: center; | ||||
|   height: 25px; | ||||
|   background: rgba(0, 0, 0, .3); | ||||
|   text-shadow: 0 1px 2px rgba(0, 0, 0, .25); | ||||
|   color: #fff; | ||||
|   border-top-left-radius: 5px; | ||||
|   border-top-right-radius: 5px; | ||||
|   margin-bottom: 5px; | ||||
|   padding: 0 10px; | ||||
| } | ||||
| .shadergraph-outlet div { | ||||
| } | ||||
| .shadergraph-outlet-in .shadergraph-name { | ||||
|   margin-right: 7px; | ||||
| } | ||||
| .shadergraph-outlet-out .shadergraph-name { | ||||
|   margin-left: 7px; | ||||
| } | ||||
|  | ||||
| .shadergraph-name { | ||||
|   margin: 0 4px; | ||||
| } | ||||
| .shadergraph-point { | ||||
|   margin: 6px; | ||||
|   width:  11px; | ||||
|   height: 11px; | ||||
|   border-radius: 7.5px; | ||||
|   background: rgba(255, 255, 255, 1); | ||||
| } | ||||
| .shadergraph-outlet-in { | ||||
|   float: left; | ||||
|   clear: left; | ||||
| } | ||||
| .shadergraph-outlet-in div { | ||||
|   float: left; | ||||
| } | ||||
| .shadergraph-outlet-out { | ||||
|   float: right; | ||||
|   clear: right; | ||||
| } | ||||
| .shadergraph-outlet-out div { | ||||
|   float: right; | ||||
| } | ||||
|  | ||||
| .shadergraph-node-callback { | ||||
|   background: rgba(205, 209, 221, .5); | ||||
|   box-shadow: 0 1px  2px rgba(0, 10, 40, .2), | ||||
|               0 1px  10px rgba(0, 10, 40, .2); | ||||
| } | ||||
| .shadergraph-node-callback > .shadergraph-header { | ||||
|   background: rgba(0, 20, 80, .3); | ||||
| } | ||||
| .shadergraph-graph .shadergraph-graph .shadergraph-node-callback { | ||||
|   background: rgba(0, 20, 80, .1); | ||||
| } | ||||
|  | ||||
| .shadergraph-node-call { | ||||
|   background: rgba(209, 221, 205, .5); | ||||
|   box-shadow: 0 1px  2px rgba(10, 40, 0, .2), | ||||
|               0 1px  10px rgba(10, 40, 0, .2); | ||||
| } | ||||
| .shadergraph-node-call > .shadergraph-header { | ||||
|   background: rgba(20, 80, 0, .3); | ||||
| } | ||||
| .shadergraph-graph .shadergraph-graph .shadergraph-node-call { | ||||
|   background: rgba(20, 80, 0, .1); | ||||
| } | ||||
|  | ||||
| .shadergraph-node-isolate { | ||||
|   background: rgba(221, 205, 209, .5); | ||||
|   box-shadow: 0 1px  2px rgba(40, 0, 10, .2), | ||||
|               0 1px  10px rgba(40, 0, 10, .2); | ||||
| } | ||||
| .shadergraph-node-isolate > .shadergraph-header { | ||||
|   background: rgba(80, 0, 20, .3); | ||||
| } | ||||
| .shadergraph-graph .shadergraph-graph .shadergraph-node-isolate { | ||||
|   background: rgba(80, 0, 20, .1); | ||||
| } | ||||
|  | ||||
| .shadergraph-node.shadergraph-has-code { | ||||
|   cursor: pointer; | ||||
| } | ||||
| .shadergraph-node.shadergraph-has-code::before { | ||||
|   position: absolute; | ||||
|   content: ' '; | ||||
|   top: 0; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   bottom: 0; | ||||
|   display: none; | ||||
|   border: 2px solid rgba(0, 0, 0, .25); | ||||
|   border-radius: 5px; | ||||
| } | ||||
| .shadergraph-node.shadergraph-has-code:hover::before { | ||||
|   display: block; | ||||
| } | ||||
| .shadergraph-code { | ||||
|   z-index: 10000; | ||||
|   display: none; | ||||
|   position: absolute; | ||||
|   background: #fff; | ||||
|   color: #000; | ||||
|   white-space: pre; | ||||
|   padding: 10px; | ||||
|   border-radius: 5px; | ||||
|   box-shadow: 0 1px  2px rgba(0, 0, 0, .2), | ||||
|               0 1px  10px rgba(0, 0, 0, .2); | ||||
|   font-family: monospace; | ||||
|   font-size: 10px; | ||||
|   line-height: 12px; | ||||
| } | ||||
|  | ||||
| .shadergraph-overlay { | ||||
|   position: fixed; | ||||
|   top: 50%; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   bottom: 0; | ||||
|   background: #fff; | ||||
|   border-top: 1px solid #CCC; | ||||
| } | ||||
| .shadergraph-overlay .shadergraph-view { | ||||
|   position: absolute; | ||||
|   left: 0; | ||||
|   top: 0; | ||||
|   right: 0; | ||||
|   bottom: 0; | ||||
|   overflow: auto; | ||||
| } | ||||
| .shadergraph-overlay .shadergraph-inside { | ||||
|   width: 4000px; | ||||
|   min-height: 100%; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| .shadergraph-overlay .shadergraph-close { | ||||
|   position: absolute; | ||||
|   top: 5px; | ||||
|   right: 5px; | ||||
|   padding: 4px; | ||||
|   border-radius: 16px; | ||||
|   background: rgba(255,255,255,.3); | ||||
|   color: rgba(0, 0, 0, .3); | ||||
|   cursor: pointer; | ||||
|   font-size: 24px; | ||||
|   line-height: 24px; | ||||
|   width: 24px; | ||||
|   text-align: center; | ||||
|   vertical-align: middle; | ||||
| } | ||||
| .shadergraph-overlay .shadergraph-close:hover { | ||||
|   background: rgba(255,255,255,1); | ||||
|   color: rgba(0, 0, 0, 1); | ||||
| } | ||||
| .shadergraph-overlay .shadergraph-graph { | ||||
|   padding-top: 10px; | ||||
|   overflow: visible; | ||||
|   min-height: 100%; | ||||
| } | ||||
| .shadergraph-overlay span { | ||||
|   display: block; | ||||
|   padding: 5px 15px; | ||||
|   margin: 0; | ||||
|   background: rgba(0, 0, 0, .1); | ||||
|   font-weight: bold; | ||||
|   font-family: sans-serif; | ||||
| } | ||||
| .mathbox-loader { | ||||
|   position: absolute; | ||||
|   top: 50%; | ||||
|   left: 50%; | ||||
|   -webkit-transform: translate(-50%, -50%); | ||||
|   transform: translate(-50%, -50%); | ||||
|   padding: 10px; | ||||
|   border-radius: 50%; | ||||
|   background: #fff; | ||||
| } | ||||
|  | ||||
| .mathbox-loader.mathbox-exit { | ||||
|   opacity: 0; | ||||
|   -webkit-transition: | ||||
|     opacity .15s ease-in-out; | ||||
|   transition: | ||||
|     opacity .15s ease-in-out; | ||||
| } | ||||
|  | ||||
| .mathbox-progress { | ||||
|   height: 10px; | ||||
|   border-radius: 5px; | ||||
|   width: 80px; | ||||
|   margin: 0 auto 20px; | ||||
|   box-shadow: | ||||
|      1px  1px 1px rgba(255, 255, 255, .2), | ||||
|      1px -1px 1px rgba(255, 255, 255, .2), | ||||
|     -1px  1px 1px rgba(255, 255, 255, .2), | ||||
|     -1px -1px 1px rgba(255, 255, 255, .2); | ||||
|   background: #ccc; | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .mathbox-progress > div { | ||||
|   display: block; | ||||
|   width: 0px; | ||||
|   height: 10px; | ||||
|   background: #888; | ||||
| } | ||||
|  | ||||
| .mathbox-logo { | ||||
|   position: relative; | ||||
|   width: 140px; | ||||
|   height: 100px; | ||||
|   margin: 0 auto 10px; | ||||
|   -webkit-perspective: 200px; | ||||
|   perspective: 200px; | ||||
| } | ||||
|  | ||||
| .mathbox-logo > div { | ||||
|   position: absolute; | ||||
|   left: 0; | ||||
|   top: 0; | ||||
|   bottom: 0; | ||||
|   right: 0; | ||||
|   -webkit-transform-style: preserve-3d; | ||||
|   transform-style:         preserve-3d; | ||||
| } | ||||
|  | ||||
| .mathbox-logo > :nth-child(1) { | ||||
|   -webkit-transform: rotateZ(22deg) rotateX(24deg) rotateY(30deg); | ||||
|   transform:         rotateZ(22deg) rotateX(24deg) rotateY(30deg); | ||||
| } | ||||
|  | ||||
| .mathbox-logo > :nth-child(2) { | ||||
|   -webkit-transform: rotateZ(11deg) rotateX(12deg) rotateY(15deg) scale3d(.6, .6, .6); | ||||
|   transform:         rotateZ(11deg) rotateX(12deg) rotateY(15deg) scale3d(.6, .6, .6); | ||||
| } | ||||
|  | ||||
| .mathbox-logo > div > div { | ||||
|   position: absolute; | ||||
|   top: 50%; | ||||
|   left: 50%; | ||||
|   margin-left: -100px; | ||||
|   margin-top: -100px; | ||||
|   width: 200px; | ||||
|   height: 200px; | ||||
|   box-sizing: border-box; | ||||
|   border-radius: 50%; | ||||
| } | ||||
|  | ||||
| .mathbox-logo > div > :nth-child(1) { | ||||
|   -webkit-transform: scale(0.5, 0.5); | ||||
|   transform:         rotateX(30deg) scale(0.5, 0.5); | ||||
| } | ||||
|  | ||||
| .mathbox-logo > div > :nth-child(2) { | ||||
|   -webkit-transform: rotateX(90deg) scale(0.42, 0.42); | ||||
|   transform:         rotateX(90deg) scale(0.42, 0.42); | ||||
| } | ||||
|  | ||||
| .mathbox-logo > div > :nth-child(3) { | ||||
|   -webkit-transform: rotateY(90deg) scale(0.35, 0.35); | ||||
|   transform:         rotateY(90deg) scale(0.35, 0.35); | ||||
| } | ||||
|  | ||||
| .mathbox-logo > :nth-child(1) > :nth-child(1) { | ||||
|   border: 16px solid #808080; | ||||
| } | ||||
| .mathbox-logo > :nth-child(1) > :nth-child(2) { | ||||
|   border: 19px solid #A0A0A0; | ||||
| } | ||||
| .mathbox-logo > :nth-child(1) > :nth-child(3) { | ||||
|   border: 23px solid #C0C0C0; | ||||
| } | ||||
| .mathbox-logo > :nth-child(2) > :nth-child(1) { | ||||
|   border: 27px solid #808080; | ||||
| } | ||||
| .mathbox-logo > :nth-child(2) > :nth-child(2) { | ||||
|   border: 32px solid #A0A0A0; | ||||
| } | ||||
| .mathbox-logo > :nth-child(2) > :nth-child(3) { | ||||
|   border: 38px solid #C0C0C0; | ||||
| } | ||||
|  | ||||
| .mathbox-splash-blue .mathbox-progress { | ||||
|   background: #def; | ||||
| } | ||||
| .mathbox-splash-blue .mathbox-progress > div { | ||||
|   background: #1979e7; | ||||
| } | ||||
| .mathbox-splash-blue .mathbox-logo > :nth-child(1) > :nth-child(1) { | ||||
|   border-color: #1979e7; | ||||
| } | ||||
| .mathbox-splash-blue .mathbox-logo > :nth-child(1) > :nth-child(2) { | ||||
|   border-color: #33b0ff; | ||||
| } | ||||
| .mathbox-splash-blue .mathbox-logo > :nth-child(1) > :nth-child(3) { | ||||
|   border-color: #75eaff; | ||||
| } | ||||
| .mathbox-splash-blue .mathbox-logo > :nth-child(2) > :nth-child(1) { | ||||
|   border-color: #18487F; | ||||
| } | ||||
| .mathbox-splash-blue .mathbox-logo > :nth-child(2) > :nth-child(2) { | ||||
|   border-color: #33b0ff; | ||||
| } | ||||
| .mathbox-splash-blue .mathbox-logo > :nth-child(2) > :nth-child(3) { | ||||
|   border-color: #75eaff; | ||||
| }   | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| .mathbox-overlays { | ||||
|   position: absolute; | ||||
|   left:   0; | ||||
|   top:    0; | ||||
|   right:  0; | ||||
|   bottom: 0; | ||||
|   pointer-events: none; | ||||
|   transform-style: preserve-3d; | ||||
|   overflow: hidden; | ||||
| } | ||||
| .mathbox-overlays > div { | ||||
|   transform-style: preserve-3d; | ||||
| } | ||||
| .mathbox-overlay > div { | ||||
|   position: absolute; | ||||
|   will-change: transform, opacity; | ||||
| } | ||||
| .mathbox-label { | ||||
|   font-family: sans-serif; | ||||
| } | ||||
| .mathbox-outline-1 { | ||||
|   text-shadow: | ||||
|     -1px -1px 0px rgb(255, 255, 255), | ||||
|      1px  1px 0px rgb(255, 255, 255), | ||||
|     -1px  1px 0px rgb(255, 255, 255), | ||||
|      1px -1px 0px rgb(255, 255, 255), | ||||
|      1px  0px 1px rgb(255, 255, 255), | ||||
|     -1px  0px 1px rgb(255, 255, 255), | ||||
|      0px -1px 1px rgb(255, 255, 255), | ||||
|      0px  1px 1px rgb(255, 255, 255); | ||||
| } | ||||
| .mathbox-outline-2 { | ||||
|   text-shadow: | ||||
|      0px -2px 0px rgb(255, 255, 255), | ||||
|      0px  2px 0px rgb(255, 255, 255), | ||||
|     -2px  0px 0px rgb(255, 255, 255), | ||||
|      2px  0px 0px rgb(255, 255, 255), | ||||
|     -1px -2px 0px rgb(255, 255, 255), | ||||
|     -2px -1px 0px rgb(255, 255, 255), | ||||
|     -1px  2px 0px rgb(255, 255, 255), | ||||
|     -2px  1px 0px rgb(255, 255, 255), | ||||
|      1px  2px 0px rgb(255, 255, 255), | ||||
|      2px  1px 0px rgb(255, 255, 255), | ||||
|      1px -2px 0px rgb(255, 255, 255), | ||||
|      2px -1px 0px rgb(255, 255, 255); | ||||
| } | ||||
| .mathbox-outline-3 { | ||||
|   text-shadow: | ||||
|      3px  0px 0px rgb(255, 255, 255), | ||||
|     -3px  0px 0px rgb(255, 255, 255), | ||||
|      0px  3px 0px rgb(255, 255, 255), | ||||
|      0px -3px 0px rgb(255, 255, 255), | ||||
|  | ||||
|     -2px -2px 0px rgb(255, 255, 255), | ||||
|     -2px  2px 0px rgb(255, 255, 255), | ||||
|      2px  2px 0px rgb(255, 255, 255), | ||||
|      2px -2px 0px rgb(255, 255, 255), | ||||
|  | ||||
|     -1px -2px 1px rgb(255, 255, 255), | ||||
|     -2px -1px 1px rgb(255, 255, 255), | ||||
|     -1px  2px 1px rgb(255, 255, 255), | ||||
|     -2px  1px 1px rgb(255, 255, 255), | ||||
|      1px  2px 1px rgb(255, 255, 255), | ||||
|      2px  1px 1px rgb(255, 255, 255), | ||||
|      1px -2px 1px rgb(255, 255, 255), | ||||
|      2px -1px 1px rgb(255, 255, 255); | ||||
| } | ||||
| .mathbox-outline-4 { | ||||
|   text-shadow: | ||||
|      4px  0px 0px rgb(255, 255, 255), | ||||
|     -4px  0px 0px rgb(255, 255, 255), | ||||
|      0px  4px 0px rgb(255, 255, 255), | ||||
|      0px -4px 0px rgb(255, 255, 255), | ||||
|     | ||||
|     -3px -2px 0px rgb(255, 255, 255), | ||||
|     -3px  2px 0px rgb(255, 255, 255), | ||||
|      3px  2px 0px rgb(255, 255, 255), | ||||
|      3px -2px 0px rgb(255, 255, 255), | ||||
|     | ||||
|     -2px -3px 0px rgb(255, 255, 255), | ||||
|     -2px  3px 0px rgb(255, 255, 255), | ||||
|      2px  3px 0px rgb(255, 255, 255), | ||||
|      2px -3px 0px rgb(255, 255, 255), | ||||
|     | ||||
|     -1px -2px 1px rgb(255, 255, 255), | ||||
|     -2px -1px 1px rgb(255, 255, 255), | ||||
|     -1px  2px 1px rgb(255, 255, 255), | ||||
|     -2px  1px 1px rgb(255, 255, 255), | ||||
|      1px  2px 1px rgb(255, 255, 255), | ||||
|      2px  1px 1px rgb(255, 255, 255), | ||||
|      1px -2px 1px rgb(255, 255, 255), | ||||
|      2px -1px 1px rgb(255, 255, 255); | ||||
|  | ||||
| } | ||||
| .mathbox-outline-fill, .mathbox-outline-fill * { | ||||
|   color: #fff !important; | ||||
| } | ||||
| @@ -402,6 +402,12 @@ input[type=range]:focus::-ms-fill-upper | ||||
|     /*transition: left 200ms, width 200ms;*/ | ||||
| } | ||||
|  | ||||
| #openwebrx-mathbox-container | ||||
| { | ||||
| 	overflow: none; | ||||
| 	display: none; | ||||
| } | ||||
|  | ||||
| #openwebrx-phantom-canvas | ||||
| { | ||||
| 	position: absolute; | ||||
| @@ -536,7 +542,7 @@ input[type=range]:focus::-ms-fill-upper | ||||
| .openwebrx-button | ||||
| { | ||||
| 	background-color: #373737; | ||||
| 	padding: 5px; | ||||
| 	padding: 4.2px; | ||||
| 	border-radius: 5px; | ||||
| 	-moz-border-radius: 5px; | ||||
| 	color: White; | ||||
|   | ||||
| @@ -1100,9 +1100,17 @@ function zoom_calc() | ||||
| function resize_waterfall_container(check_init) | ||||
| { | ||||
| 	if(check_init&&!waterfall_setup_done) return; | ||||
| 	canvas_container.style.height=(window.innerHeight-e("webrx-top-container").clientHeight-e("openwebrx-scale-container").clientHeight).toString()+"px"; | ||||
| } | ||||
| 	var numHeight; | ||||
| 	mathbox_container.style.height=canvas_container.style.height=(numHeight=window.innerHeight-e("webrx-top-container").clientHeight-e("openwebrx-scale-container").clientHeight).toString()+"px"; | ||||
| 	if(mathbox) | ||||
| 	{ | ||||
| 		//mathbox.three.camera.aspect = document.body.offsetWidth / numHeight; | ||||
|   		//mathbox.three.camera.updateProjectionMatrix(); | ||||
| 		mathbox.three.renderer.setSize(document.body.offsetWidth, numHeight); | ||||
| 		console.log(document.body.offsetWidth, numHeight); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| audio_server_output_rate=11025; | ||||
| audio_client_resampling_factor=4; | ||||
| @@ -1553,6 +1561,8 @@ function webrx_set_param(what, value) | ||||
| 	ws.send("SET "+what+"="+value.toString()); | ||||
| } | ||||
|  | ||||
| var starting_mute = false; | ||||
|  | ||||
| function parsehash() | ||||
| { | ||||
| 	if(h=window.location.hash) | ||||
| @@ -1612,6 +1622,8 @@ function audio_preinit() | ||||
|  | ||||
| function audio_init() | ||||
| { | ||||
| 	if(starting_mute) toggleMute(); | ||||
|  | ||||
| 	if(audio_client_resampling_factor==0) return; //if failed to find a valid resampling factor... | ||||
|  | ||||
| 	audio_debug_time_start=(new Date()).getTime(); | ||||
| @@ -1656,6 +1668,7 @@ function audio_init() | ||||
| 			//window.setTimeout(function(){toggle_panel("openwebrx-panel-log");e("openwebrx-panel-log").style.opacity="1";},1200) | ||||
| 		} | ||||
| 	},2000); | ||||
|  | ||||
| } | ||||
|  | ||||
| function on_ws_closed() | ||||
| @@ -1696,17 +1709,18 @@ function open_websocket() | ||||
| 	ws.onerror = on_ws_error; | ||||
| } | ||||
|  | ||||
| function waterfall_mkcolor(db_value) | ||||
| function waterfall_mkcolor(db_value, waterfall_colors_arg) | ||||
| { | ||||
| 	if(typeof waterfall_colors_arg === 'undefined') waterfall_colors_arg = waterfall_colors; | ||||
| 	if(db_value<waterfall_min_level) db_value=waterfall_min_level; | ||||
| 	if(db_value>waterfall_max_level) db_value=waterfall_max_level; | ||||
| 	full_scale=waterfall_max_level-waterfall_min_level; | ||||
| 	relative_value=db_value-waterfall_min_level; | ||||
| 	value_percent=relative_value/full_scale; | ||||
| 	percent_for_one_color=1/(waterfall_colors.length-1); | ||||
| 	percent_for_one_color=1/(waterfall_colors_arg.length-1); | ||||
| 	index=Math.floor(value_percent/percent_for_one_color); | ||||
| 	remain=(value_percent-percent_for_one_color*index)/percent_for_one_color; | ||||
| 	return color_between(waterfall_colors[index+1],waterfall_colors[index],remain); | ||||
| 	return color_between(waterfall_colors_arg[index+1],waterfall_colors_arg[index],remain); | ||||
| } | ||||
|  | ||||
| function color_between(first, second, percent) | ||||
| @@ -1749,9 +1763,11 @@ function add_canvas() | ||||
| 	canvases.push(new_canvas); | ||||
| } | ||||
|  | ||||
|  | ||||
| function init_canvas_container() | ||||
| { | ||||
| 	canvas_container=e("webrx-canvas-container"); | ||||
| 	mathbox_container=e("openwebrx-mathbox-container"); | ||||
| 	canvas_container.addEventListener("mouseout",canvas_container_mouseout, false); | ||||
| 	//window.addEventListener("mouseout",window_mouseout,false); | ||||
| 	//document.body.addEventListener("mouseup",body_mouseup,false); | ||||
| @@ -1817,6 +1833,42 @@ function waterfall_init() | ||||
|  | ||||
| var waterfall_dont_scale=0; | ||||
|  | ||||
| var mathbox_shift = function() | ||||
| { | ||||
| 	if(mathbox_data_current_depth < mathbox_data_max_depth) mathbox_data_current_depth++; | ||||
| 	if(mathbox_data_index+1>=mathbox_data_max_depth) mathbox_data_index = 0; | ||||
| 	else mathbox_data_index++; | ||||
| 	mathbox_data_global_index++; | ||||
| } | ||||
|  | ||||
| var mathbox_clear_data = function() | ||||
| { | ||||
| 	mathbox_data_index = 50; | ||||
| 	mathbox_data_current_depth = 0; | ||||
| } | ||||
|  | ||||
| //var mathbox_get_data_line = function(x) //x counts from 0 to mathbox_data_current_depth | ||||
| //{ | ||||
| //	return (mathbox_data_max_depth + mathbox_data_index - mathbox_data_current_depth + x - 1) % mathbox_data_max_depth; | ||||
| //} | ||||
| // | ||||
| //var mathbox_data_index_valid = function(x) //x counts from 0 to mathbox_data_current_depth | ||||
| //{ | ||||
| //	return x<mathbox_data_current_depth; | ||||
| //} | ||||
|  | ||||
| var mathbox_get_data_line = function(x) | ||||
| { | ||||
| 	return (mathbox_data_max_depth + mathbox_data_index + x - 1) % mathbox_data_max_depth; | ||||
| } | ||||
|  | ||||
| var mathbox_data_index_valid = function(x) | ||||
| { | ||||
| 	return x>mathbox_data_max_depth-mathbox_data_current_depth; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| function waterfall_add(data) | ||||
| { | ||||
| 	if(!waterfall_setup_done) return; | ||||
| @@ -1893,6 +1945,14 @@ function waterfall_add(data) | ||||
| 			waterfall_image.data[base+x*4+i] = ((color>>>0)>>((3-i)*8))&0xff; | ||||
| 	}*/ | ||||
|  | ||||
| 	if(mathbox_mode==MATHBOX_MODES.WATERFALL) | ||||
| 	{ | ||||
| 		//Handle mathbox | ||||
| 		for(var i=0;i<fft_size;i++) mathbox_data[i+mathbox_data_index*fft_size]=data[i]; | ||||
| 		mathbox_shift(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	//Add line to waterfall image | ||||
| 	oneline_image = canvas_context.createImageData(w,1); | ||||
| 	for(x=0;x<w;x++) | ||||
| @@ -1902,13 +1962,13 @@ function waterfall_add(data) | ||||
| 			oneline_image.data[x*4+i] = ((color>>>0)>>((3-i)*8))&0xff; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	//Draw image | ||||
| 	canvas_context.putImageData(oneline_image, 0, canvas_actual_line--); | ||||
| 	shift_canvases(); | ||||
| 	if(canvas_actual_line<0) add_canvas(); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	//divlog("Drawn FFT"); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -1938,6 +1998,179 @@ function check_top_bar_congestion() | ||||
|  | ||||
| } | ||||
|  | ||||
| var MATHBOX_MODES = | ||||
| { | ||||
| 	UNINITIALIZED: 0, | ||||
| 	NONE: 1, | ||||
| 	WATERFALL: 2, | ||||
| 	CONSTELLATION: 3 | ||||
| }; | ||||
| var mathbox_mode = MATHBOX_MODES.UNINITIALIZED; | ||||
| var mathbox; | ||||
| var mathbox_element; | ||||
|  | ||||
| function mathbox_init() | ||||
| { | ||||
| 	//mathbox_waterfall_history_length is defined in the config | ||||
| 	mathbox_data_max_depth = fft_fps * mathbox_waterfall_history_length; //how many lines can the buffer store | ||||
| 	mathbox_data_current_depth = 0; //how many lines are in the buffer currently | ||||
| 	mathbox_data_index = 0; //the index of the last empty line / the line to be overwritten | ||||
| 	mathbox_data = new Float32Array(fft_size * mathbox_data_max_depth); | ||||
| 	mathbox_data_global_index = 0; | ||||
| 	mathbox_correction_for_z = 0; | ||||
|  | ||||
| 	mathbox = mathBox({ | ||||
|       plugins: ['core', 'controls', 'cursor', 'stats'], | ||||
|       controls: { klass: THREE.OrbitControls }, | ||||
|     }); | ||||
|     three = mathbox.three; | ||||
|  | ||||
|     three.renderer.setClearColor(new THREE.Color(0x808080), 1.0); | ||||
| 	mathbox_container.appendChild((mathbox_element=three.renderer.domElement)); | ||||
|     view = mathbox | ||||
|     .set({ | ||||
|       scale: 1080, | ||||
|       focus: 3, | ||||
|     }) | ||||
|     .camera({ | ||||
|       proxy: true, | ||||
|       position: [-2, 1, 3], | ||||
|     }) | ||||
|     .cartesian({ | ||||
|       range: [[-1, 1], [0, 1], [0, 1]], | ||||
|       scale: [2, 2/3, 1], | ||||
|     }); | ||||
|  | ||||
|     view.axis({ | ||||
|       axis: 1, | ||||
|       width: 3, | ||||
| 	  color: "#fff", | ||||
|   }); | ||||
|     view.axis({ | ||||
|       axis: 2, | ||||
|       width: 3, | ||||
| 	  color: "#fff", | ||||
| 	  //offset: [0, 0, 0], | ||||
|   }); | ||||
|     view.axis({ | ||||
|       axis: 3, | ||||
|       width: 3, | ||||
| 	  color: "#fff", | ||||
|   }); | ||||
|  | ||||
|     view.grid({ | ||||
|       width: 2, | ||||
|       opacity: 0.5, | ||||
|       axes: [1, 3], | ||||
|       zOrder: 1, | ||||
| 	  color: "#fff", | ||||
|     }); | ||||
|  | ||||
|     //var remap = function (v) { return Math.sqrt(.5 + .5 * v); }; | ||||
|  | ||||
|  | ||||
| 	var remap = function(x,z,t) | ||||
| 	{ | ||||
| 		var currentTimePos = mathbox_data_global_index/(fft_fps*1.0); | ||||
| 		var realZAdd = (-(t-currentTimePos)/mathbox_waterfall_history_length); | ||||
| 		var zAdd = realZAdd - mathbox_correction_for_z; | ||||
| 		if(zAdd<-0.2 || zAdd>0.2) { mathbox_correction_for_z = realZAdd; } | ||||
|  | ||||
| 		var xIndex = Math.trunc(((x+1)/2.0)*fft_size); //x: frequency | ||||
| 		var zIndex = Math.trunc(z*(mathbox_data_max_depth-1)); //z: time | ||||
| 		var realZIndex = mathbox_get_data_line(zIndex); | ||||
| 		if(!mathbox_data_index_valid(zIndex)) return {y: undefined, dBValue: undefined, zAdd: 0 }; | ||||
| 		//if(realZIndex>=(mathbox_data_max_depth-1)) console.log("realZIndexundef", realZIndex, zIndex); | ||||
| 		var index = Math.trunc(xIndex + realZIndex * fft_size); | ||||
| 		/*if(mathbox_data[index]==undefined) console.log("Undef", index, mathbox_data.length, zIndex, | ||||
| 				realZIndex, mathbox_data_max_depth, | ||||
| 				mathbox_data_current_depth, mathbox_data_index);*/ | ||||
| 		var dBValue = mathbox_data[index]; | ||||
| 		//y=1; | ||||
| 		if(dBValue>waterfall_max_level) y = 1; | ||||
| 		else if(dBValue<waterfall_min_level) y = 0; | ||||
| 		else y = (dBValue-waterfall_min_level)/(waterfall_max_level-waterfall_min_level); | ||||
| 		mathbox_dbg = { dbv: dBValue, indexval: index, mbd: mathbox_data.length, yval: y }; | ||||
| 		if(!y) y=0; | ||||
| 		return {y: y, dBValue: dBValue, zAdd: zAdd}; | ||||
| 	} | ||||
|  | ||||
|     var points = view.area({ | ||||
|       expr: function (emit, x, z, i, j, t) { | ||||
| 		var y; | ||||
| 		remapResult=remap(x,z,t); | ||||
| 		if((y=remapResult.y)==undefined) return; | ||||
|         emit(x, y, z+remapResult.zAdd); | ||||
|       }, | ||||
|       width:  mathbox_waterfall_frequency_resolution, | ||||
|       height: mathbox_data_max_depth - 1, | ||||
|       channels: 3, | ||||
|       axes: [1, 3], | ||||
|     }); | ||||
|  | ||||
|     var colors = view.area({ | ||||
|       expr: function (emit, x, z, i, j, t) { | ||||
| 		var dBValue; | ||||
| 		if((dBValue=remap(x,z,t).dBValue)==undefined) return; | ||||
| 		var color=waterfall_mkcolor(dBValue, mathbox_waterfall_colors); | ||||
|         var b = (color&0xff)/255.0; | ||||
|         var g = ((color&0xff00)>>8)/255.0; | ||||
|         var r = ((color&0xff0000)>>16)/255.0; | ||||
|         emit(r, g, b, 1.0); | ||||
|       }, | ||||
|       width:  mathbox_waterfall_frequency_resolution, | ||||
|       height: mathbox_data_max_depth - 1, | ||||
|       channels: 4, | ||||
|       axes: [1, 3], | ||||
|     }); | ||||
|  | ||||
|     view.surface({ | ||||
|       shaded: true, | ||||
|       points: '<<', | ||||
|       colors: '<', | ||||
|       color: 0xFFFFFF, | ||||
|     }); | ||||
|  | ||||
|     view.surface({ | ||||
|       fill: false, | ||||
|       lineX: false, | ||||
|       lineY: false, | ||||
|       points: '<<', | ||||
|       colors: '<', | ||||
|       color: 0xFFFFFF, | ||||
|       width: 2, | ||||
|       blending: 'add', | ||||
|       opacity: .25, | ||||
|       zBias: 5, | ||||
|     }); | ||||
| 	mathbox_mode = MATHBOX_MODES.NONE; | ||||
|  | ||||
| 	//mathbox_element.style.width="100%"; | ||||
| 	//mathbox_element.style.height="100%"; | ||||
|  | ||||
| } | ||||
|  | ||||
| function mathbox_toggle() | ||||
| { | ||||
|  | ||||
| 	if(mathbox_mode == MATHBOX_MODES.UNINITIALIZED) mathbox_init(); | ||||
| 	mathbox_mode = (mathbox_mode == MATHBOX_MODES.NONE) ? MATHBOX_MODES.WATERFALL : MATHBOX_MODES.NONE; | ||||
| 	mathbox_container.style.display = (mathbox_mode == MATHBOX_MODES.WATERFALL) ? "block" : "none"; | ||||
| 	mathbox_clear_data(); | ||||
| 	waterfall_clear(); | ||||
| } | ||||
|  | ||||
| function waterfall_clear() | ||||
| { | ||||
| 	while(canvases.length) //delete all canvases | ||||
| 	{ | ||||
| 		var x=canvases.shift(); | ||||
| 		x.parentNode.removeChild(x); | ||||
| 		delete x; | ||||
| 	} | ||||
| 	add_canvas(); | ||||
| } | ||||
|  | ||||
| function openwebrx_resize() | ||||
| { | ||||
| 	resize_canvases(); | ||||
|   | ||||
| @@ -427,6 +427,7 @@ class WebRXHandler(BaseHTTPRequestHandler): | ||||
|             # there's even another cool tip at http://stackoverflow.com/questions/4419650/how-to-implement-timeout-in-basehttpserver-basehttprequesthandler-python | ||||
|             #if self.path[:5]=="/lock": cma("do_GET /lock/") # to test mutex_watchdog_thread. Do not uncomment in production environment! | ||||
|             if self.path[:4]=="/ws/": | ||||
|                 print "[openwebrx-ws] Client requested WebSocket connection" | ||||
|                 if receiver_failed: self.send_error(500,"Internal server error") | ||||
|                 try: | ||||
|                     # ========= WebSocket handshake  ========= | ||||
| @@ -686,7 +687,10 @@ class WebRXHandler(BaseHTTPRequestHandler): | ||||
|                         ("%[WATERFALL_MIN_LEVEL]",str(cfg.waterfall_min_level)), | ||||
|                         ("%[WATERFALL_MAX_LEVEL]",str(cfg.waterfall_max_level)), | ||||
|                         ("%[WATERFALL_AUTO_LEVEL_MARGIN]","[%d,%d]"%cfg.waterfall_auto_level_margin), | ||||
|                         ("%[DIGIMODES_ENABLE]",("true" if cfg.digimodes_enable else "false")) | ||||
|                         ("%[DIGIMODES_ENABLE]",("true" if cfg.digimodes_enable else "false")), | ||||
|                         ("%[MATHBOX_WATERFALL_FRES]",str(cfg.mathbox_waterfall_frequency_resolution)), | ||||
|                         ("%[MATHBOX_WATERFALL_THIST]",str(cfg.mathbox_waterfall_history_length)), | ||||
|                         ("%[MATHBOX_WATERFALL_COLORS]",cfg.mathbox_waterfall_colors) | ||||
|                     ) | ||||
|                     for rule in replace_dictionary: | ||||
|                         while data.find(rule[0])!=-1: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ha7ilm
					ha7ilm