import React, { useState, useEffect } from 'react' const SCALE_MIN = -60 const SCALE_MAX = 0 function toPx (val) { return value2px(val, SCALE_MIN, SCALE_MAX, 0, 100) } function toY (val) { return 100 - value2px(val) } function MeterDefs (props) { const { width } = props let green = [0, toPx(-8)] let yellow = [toPx(-8), toPx(-5)] let red = [toPx(-5), toPx(0)] const common = { x: 0, width } return ( ) } let max = 0 let last = 0 function getMax (time, val) { // let newmax = Math.max(val, max) if (val > max) { max = val last = time } else if (time - last > 3) { max = val } else if (time - last > 1) { max = max - 1 // max = val } return max } export function EbuMeter (props) { const { value } = props const val = value // let [max, setMax] = useState(0) const width = 40 const gutter = 1 let min = SCALE_MIN // let min = -30 // mic // let peakMax = -2 // let ebuMax = -5 let peakMax = SCALE_MAX let ebuMax = SCALE_MAX // Momentary peak // let peakM = value2px(val.M, min, ebuMax, 0, 100) // Short-term peak let peakS = value2px(val.S, min, ebuMax, 0, 100) let peakL = 0 let peakR = 0 if (val.FTPK) { peakL = value2px(val.FTPK[0], min, peakMax, 0, 100) peakR = value2px(val.FTPK[1], min, peakMax, 0, 100) } if (peakL > 100) peakL = 0 if (peakR > 100) peakR = 0 if (peakS > 100) peakS = 0 let max = getMax(val.t, Math.max(peakL, peakR)) const meterWidth = width / 2 - gutter / 2 const peakMeterL = { id: 'peakL', peak: peakL, x: 0, width: meterWidth } const peakMeterR = { id: 'peakR', peak: peakR, x: meterWidth + gutter, width: meterWidth } return ( {/* */} ) } function PeakMeter (props = {}) { const { peak, width, x, id } = props const mask = { y: 100 - peak, height: peak, x, width } // const range = -60 // const gutter = 0.5 // const steps = 24 // const dbPerStep = range / steps // const scale = new Array(steps).fill(null).map((_, i) => { // const bottom = toPx(dbPerStep * (i)) - gutter // const top = toPx(dbPerStep * (i + 1)) // let fill = '#fff' // // if (bottom > peak) fill = '#444' // return { // fill, // x, // width, // y: 100 - top, // height: top - bottom // } // }) const height = 100 const gutter = 0.8 const steps = 24 const heightPerStep = height / steps // const filledSteps = Math.ceil(peak / steps) const scale = new Array(steps).fill(null).map((_, i) => { const bottom = heightPerStep * i const top = bottom + heightPerStep - gutter let fill = 'white' if (((top + bottom) / 2) > peak) fill = '#444' // if ((steps * i) > peak) return // const y = 100 - heightPerStep * i return { fill, x, width, y: 100 - top, height: top - bottom } }).filter(x => x) return ( <> {scale.map((rect, i) => )} ) } function sigLog (n) { return Math.log(Math.abs(n) + 1) / Math.log(10) * sig(n) } function sig (n) { return n === 0 ? 0 : Math.abs(n) / n } function sigExp (n) { return (Math.pow(10, Math.abs(n)) - 1) * sig(n) } function value2px (value, valueMin, valueMax, pxMin, pxMax) { if (value < valueMin) value = valueMin if (value > valueMax) value = valueMax if (isNaN(value) || value === null) value = valueMin const valueWidth = valueMax - valueMin const pixelWidth = pxMax - pxMin const ratio = pixelWidth / valueWidth return ratio * (value - valueMin) + pxMin // const ratio = value / (valueMax - valueMin) // const scaled = ratio * (pxMax - pxMin) // return pxMin + scaled } // This is the original function that display the meter in a log scale. function value2pxLog (value, valueMin, valueMax, pxMin, pxMax) { var valueWidth = sigLog(valueMax) - sigLog(valueMin) var pixelWidth = pxMax - pxMin var ratio = pixelWidth / valueWidth return ratio * (sigLog(value) - sigLog(valueMin)) + pxMin } function px2value (px, valueMin, valueMax, pxMin, pxMax) { var valueWidth = sigLog(valueMax) - sigLog(valueMin) var pixelWidth = pxMax - pxMin var ratio = pixelWidth / valueWidth return sigExp((px - pxMin) / ratio + sigLog(valueMin)) } function prettify (n) { var exp = Math.round(Math.pow(10, Math.log(Math.abs(n)) / Math.log(10))) return exp === 0 ? 0 : Math.round(n / exp) * exp } function style (color) { return { style: { fill: color } } }