1 /*
2  * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.media.sound;
27 
28 /**
29  * A standard transformer used in connection blocks.
30  * It expects input values to be between 0 and 1.
31  *
32  * The result of the transform is
33  *   between 0 and 1 if polarity = unipolar and
34  *   between -1 and 1 if polarity = bipolar.
35  *
36  * These constraints only applies to Concave, Convex and Switch transforms.
37  *
38  * @author Karl Helgason
39  */
40 public final class ModelStandardTransform implements ModelTransform {
41 
42     public static final boolean DIRECTION_MIN2MAX = false;
43     public static final boolean DIRECTION_MAX2MIN = true;
44     public static final boolean POLARITY_UNIPOLAR = false;
45     public static final boolean POLARITY_BIPOLAR = true;
46     public static final int TRANSFORM_LINEAR = 0;
47     // concave: output = (20*log10(127^2/value^2)) / 96
48     public static final int TRANSFORM_CONCAVE = 1;
49     // convex: same as concave except that start and end point are reversed.
50     public static final int TRANSFORM_CONVEX = 2;
51     // switch: if value > avg(max,min) then max else min
52     public static final int TRANSFORM_SWITCH = 3;
53     public static final int TRANSFORM_ABSOLUTE = 4;
54     private boolean direction = DIRECTION_MIN2MAX;
55     private boolean polarity = POLARITY_UNIPOLAR;
56     private int transform = TRANSFORM_LINEAR;
57 
ModelStandardTransform()58     public ModelStandardTransform() {
59     }
60 
ModelStandardTransform(boolean direction)61     public ModelStandardTransform(boolean direction) {
62         this.direction = direction;
63     }
64 
ModelStandardTransform(boolean direction, boolean polarity)65     public ModelStandardTransform(boolean direction, boolean polarity) {
66         this.direction = direction;
67         this.polarity = polarity;
68     }
69 
ModelStandardTransform(boolean direction, boolean polarity, int transform)70     public ModelStandardTransform(boolean direction, boolean polarity,
71             int transform) {
72         this.direction = direction;
73         this.polarity = polarity;
74         this.transform = transform;
75     }
76 
77     @Override
transform(double value)78     public double transform(double value) {
79         double s;
80         double a;
81         if (direction == DIRECTION_MAX2MIN)
82             value = 1.0 - value;
83         if (polarity == POLARITY_BIPOLAR)
84             value = value * 2.0 - 1.0;
85         switch (transform) {
86             case TRANSFORM_CONCAVE:
87                 s = Math.signum(value);
88                 a = Math.abs(value);
89                 a = -((5.0 / 12.0) / Math.log(10)) * Math.log(1.0 - a);
90                 if (a < 0)
91                     a = 0;
92                 else if (a > 1)
93                     a = 1;
94                 return s * a;
95             case TRANSFORM_CONVEX:
96                 s = Math.signum(value);
97                 a = Math.abs(value);
98                 a = 1.0 + ((5.0 / 12.0) / Math.log(10)) * Math.log(a);
99                 if (a < 0)
100                     a = 0;
101                 else if (a > 1)
102                     a = 1;
103                 return s * a;
104             case TRANSFORM_SWITCH:
105                 if (polarity == POLARITY_BIPOLAR)
106                     return (value > 0) ? 1 : -1;
107                 else
108                     return (value > 0.5) ? 1 : 0;
109             case TRANSFORM_ABSOLUTE:
110                 return Math.abs(value);
111             default:
112                 break;
113         }
114 
115         return value;
116     }
117 
getDirection()118     public boolean getDirection() {
119         return direction;
120     }
121 
setDirection(boolean direction)122     public void setDirection(boolean direction) {
123         this.direction = direction;
124     }
125 
getPolarity()126     public boolean getPolarity() {
127         return polarity;
128     }
129 
setPolarity(boolean polarity)130     public void setPolarity(boolean polarity) {
131         this.polarity = polarity;
132     }
133 
getTransform()134     public int getTransform() {
135         return transform;
136     }
137 
setTransform(int transform)138     public void setTransform(int transform) {
139         this.transform = transform;
140     }
141 }
142