A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 159 lines 4.6 kB view raw
1--[[ Lua Missing Math functions 2/*************************************************************************** 3 * __________ __ ___. 4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 8 * \/ \/ \/ \/ \/ 9 * $Id$ 10 * 11 * Copyright (C) 2017 William Wilgus 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License 15 * as published by the Free Software Foundation; either version 2 16 * of the License, or (at your option) any later version. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ****************************************************************************/ 22]] 23 24--[[ Exposed Functions 25 26 _math.clamp 27 _math.clamp_roll 28 _math.d_sin 29 _math.d_cos 30 _math.d_tan 31 _math.i_sqrt 32 33]] 34 35local _math = {} do 36 37 -- internal constants 38 local _NIL = nil -- _NIL placeholder 39 40 -- clamps value to >= min and <= max 41 local function clamp(iVal, iMin, iMax) 42 if iMin > iMax then 43 local swap = iMin 44 iMin, iMax = iMax, swap 45 end 46 47 if iVal < iMin then 48 return iMin 49 elseif iVal < iMax then 50 return iVal 51 end 52 53 return iMax 54 end 55 56 -- clamps value to >= min and <= max rolls over to opposite 57 local function clamp_roll(iVal, iMin, iMax) 58 if iMin > iMax then 59 local swap = iMin 60 iMin, iMax = iMax, swap 61 end 62 63 if iVal < iMin then 64 iVal = iMax 65 elseif iVal > iMax then 66 iVal = iMin 67 end 68 69 return iVal 70 end 71 72 local function i_sqrt(n) 73 -- Newtons square root approximation 74 if n < 2 then return n end 75 local g = n / 2 76 local l = 1 77 78 for c = 1, 25 do -- if l,g haven't converged after 25 iterations quit 79 80 l = (n / g + g)/ 2 81 g = (n / l + l)/ 2 82 83 if g == l then return g end 84 end 85 86 -- check for period-two cycle between g and l 87 if g - l == 1 then 88 return l 89 elseif l - g == 1 then 90 return g 91 end 92 93 return _NIL 94 end 95 96 local function d_sin(iDeg, bExtraPrecision) 97 --[[ values are returned multiplied by 10000 98 II | I 180-90 | 90-0 99 ---(--)--- -------(--)------- 100 III | IV 180-270 | 270-360 101 102 sine is only positive in quadrants I , II => 0 - 180 degrees 103 sine 180-360 degrees is a reflection of sine 0-180 104 Bhaskara I's sine approximation formula isn't overly accurate 105 but it is close enough for rough image work. 106 ]] 107 local sign, x 108 -- no negative angles -10 degrees = 350 degrees 109 if iDeg < 0 then 110 x = 360 + (iDeg % 360) 111 else --keep rotation in 0-360 range 112 x = iDeg % 360 113 end 114 115 -- reflect II & I onto III & IV 116 if x > 180 then 117 sign = -1 118 x = x % 180 119 else 120 sign = 1 121 end 122 123 local x1 = x * (180 - x) 124 125 if bExtraPrecision then -- ~halves the largest errors 126 if x <= 22 or x >= 158 then 127 return sign * 39818 * x1 / (40497 - x1) 128 elseif (x >= 40 and x <= 56) or (x > 124 and x < 140) then 129 return sign * 40002 * x1 / (40450 - x1) 130 elseif (x > 31 and x < 71) or (x > 109 and x < 150) then 131 return sign * 40009 * x1 / (40470 - x1) 132 end 133 end 134 135 --multiplied by 10000 so no decimal in results (RB LUA is integer only) 136 return sign * 40000 * x1 / (40497 - x1) 137 end 138 139 local function d_cos(iDeg, bExtraPrecision) 140 --cos is just sine shifed by 90 degrees CCW 141 return d_sin(90 - iDeg, bExtraPrecision) 142 end 143 144 local function d_tan(iDeg, bExtraPrecision) 145 --tan = sin0 / cos0 146 return (d_sin(iDeg, bExtraPrecision) * 10000 / d_sin(90 - iDeg, bExtraPrecision)) 147 end 148 149 --expose functions to the outside through _math table 150 _math.clamp = clamp 151 _math.clamp_roll = clamp_roll 152 _math.i_sqrt = i_sqrt 153 _math.d_sin = d_sin 154 _math.d_cos = d_cos 155 _math.d_tan = d_tan 156end -- missing math functions 157 158return _math 159