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 }