1 /** 2 * Copyright 2017 Cut Through Recordings 3 * License: MIT License 4 * Author(s): Ethan Reker 5 */ 6 module ddsp.util.scale; 7 8 import std.math; 9 10 struct RealRange 11 { 12 float x1; 13 float x2; 14 } 15 16 class Scale 17 { 18 public: 19 20 /++Calculates the coefficient a and b based on the ranges given. +/ 21 abstract void initialize(RealRange inputRange, RealRange outputRange) nothrow @nogc; 22 23 /++input value is converted and returned. +/ 24 abstract float convert(float x) nothrow @nogc; 25 26 float getA(){ return _a;} 27 28 float getB(){ return _b;} 29 30 protected: 31 32 //Coefficients which will shape the output funtion. 33 float _a; 34 float _b; 35 float _minVal; 36 float _maxVal; 37 } 38 39 /** 40 Takes an input range which is logarithmic and converts it to a linear scale. 41 */ 42 class LogToLinearScale : Scale 43 { 44 public: 45 46 this() nothrow @nogc 47 { 48 } 49 50 override void initialize(RealRange inputRange, RealRange outputRange) nothrow @nogc 51 { 52 _minVal = inputRange.x1; 53 _maxVal = inputRange.x2; 54 _b = log(outputRange.x1/outputRange.x2)/(inputRange.x1 - inputRange.x2); 55 _a = outputRange.x1 / exp(_b * inputRange.x1); 56 } 57 58 override float convert(float x) nothrow @nogc 59 { 60 x < _minVal ? x = _minVal : x = x; 61 x > _maxVal ? x = _maxVal : x = x; 62 return log(x / _a) / _b; 63 } 64 65 private: 66 67 } 68 69 /** 70 Takes an input range which is linear and converts it to a logarithmic scale. 71 */ 72 class LinearToLogScale : Scale 73 { 74 public: 75 76 this() nothrow @nogc 77 { 78 } 79 80 override void initialize(RealRange inputRange, RealRange outputRange) nothrow @nogc 81 { 82 _minVal = inputRange.x1; 83 _maxVal = inputRange.x2; 84 _b = log(outputRange.x1/outputRange.x2)/(inputRange.x1 - inputRange.x2); 85 _a = outputRange.x1 / exp(_b * inputRange.x1); 86 } 87 88 override float convert(float x) nothrow @nogc 89 { 90 x < _minVal ? x = _minVal : x = x; 91 x > _maxVal ? x = _maxVal : x = x; 92 return _a * exp(_b * x); 93 } 94 95 private: 96 97 } 98 99 unittest 100 { 101 LinearToLogScale scale1 = new LinearToLogScale(); 102 scale1.initialize(RealRange(0.1f, 1.0f), RealRange(0.1f, 1.0f)); 103 LogToLinearScale scale2 = new LogToLinearScale(); 104 scale2.initialize(RealRange(0.1f, 1.0f), RealRange(0.1f, 1.0f)); 105 }