Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/javax/sound/sampled/FloatControl.java
41159 views
1
/*
2
* Copyright (c) 1999, 2020, 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 javax.sound.sampled;
27
28
/**
29
* A {@code FloatControl} object provides control over a range of floating-point
30
* values. Float controls are often represented in graphical user interfaces by
31
* continuously adjustable objects such as sliders or rotary knobs. Concrete
32
* subclasses of {@code FloatControl} implement controls, such as gain and pan,
33
* that affect a line's audio signal in some way that an application can
34
* manipulate. The {@link FloatControl.Type} inner class provides static
35
* instances of types that are used to identify some common kinds of float
36
* control.
37
* <p>
38
* The {@code FloatControl} abstract class provides methods to set and get the
39
* control's current floating-point value. Other methods obtain the possible
40
* range of values and the control's resolution (the smallest increment between
41
* returned values). Some float controls allow ramping to a new value over a
42
* specified period of time. {@code FloatControl} also includes methods that
43
* return string labels for the minimum, maximum, and midpoint positions of the
44
* control.
45
*
46
* @author David Rivas
47
* @author Kara Kytle
48
* @see Line#getControls
49
* @see Line#isControlSupported
50
* @since 1.3
51
*/
52
public abstract class FloatControl extends Control {
53
54
/**
55
* The minimum supported value.
56
*/
57
private final float minimum;
58
59
/**
60
* The maximum supported value.
61
*/
62
private final float maximum;
63
64
/**
65
* The control's precision.
66
*/
67
private final float precision;
68
69
/**
70
* The smallest time increment in which a value change can be effected
71
* during a value shift, in microseconds.
72
*/
73
private final int updatePeriod;
74
75
/**
76
* A label for the units in which the control values are expressed, such as
77
* "dB" for decibels.
78
*/
79
private final String units;
80
81
/**
82
* A label for the minimum value, such as "Left".
83
*/
84
private final String minLabel;
85
86
/**
87
* A label for the maximum value, such as "Right".
88
*/
89
private final String maxLabel;
90
91
/**
92
* A label for the mid-point value, such as "Center".
93
*/
94
private final String midLabel;
95
96
/**
97
* The current value.
98
*/
99
private float value;
100
101
/**
102
* Constructs a new float control object with the given parameters.
103
*
104
* @param type the kind of control represented by this float control object
105
* @param minimum the smallest value permitted for the control
106
* @param maximum the largest value permitted for the control
107
* @param precision the resolution or granularity of the control. This is
108
* the size of the increment between discrete valid values.
109
* @param updatePeriod the smallest time interval, in microseconds, over
110
* which the control can change from one discrete value to the next
111
* during a {@link #shift(float,float,int) shift}
112
* @param initialValue the value that the control starts with when
113
* constructed
114
* @param units the label for the units in which the control's values are
115
* expressed, such as "dB" or "frames per second"
116
* @param minLabel the label for the minimum value, such as "Left" or "Off"
117
* @param midLabel the label for the midpoint value, such as "Center" or
118
* "Default"
119
* @param maxLabel the label for the maximum value, such as "Right" or
120
* "Full"
121
* @throws IllegalArgumentException if {@code minimum} is greater than
122
* {@code maximum} or {@code initialValue} does not fall within the
123
* allowable range
124
*/
125
protected FloatControl(Type type, float minimum, float maximum,
126
float precision, int updatePeriod, float initialValue,
127
String units, String minLabel, String midLabel, String maxLabel) {
128
129
super(type);
130
131
if (minimum > maximum) {
132
throw new IllegalArgumentException("Minimum value " + minimum
133
+ " exceeds maximum value " + maximum + ".");
134
}
135
if (initialValue < minimum) {
136
throw new IllegalArgumentException("Initial value " + initialValue
137
+ " smaller than allowable minimum value " + minimum + ".");
138
}
139
if (initialValue > maximum) {
140
throw new IllegalArgumentException("Initial value " + initialValue
141
+ " exceeds allowable maximum value " + maximum + ".");
142
}
143
144
145
this.minimum = minimum;
146
this.maximum = maximum;
147
148
this.precision = precision;
149
this.updatePeriod = updatePeriod;
150
this.value = initialValue;
151
152
this.units = units;
153
this.minLabel = ( (minLabel == null) ? "" : minLabel);
154
this.midLabel = ( (midLabel == null) ? "" : midLabel);
155
this.maxLabel = ( (maxLabel == null) ? "" : maxLabel);
156
}
157
158
/**
159
* Constructs a new float control object with the given parameters. The
160
* labels for the minimum, maximum, and mid-point values are set to
161
* zero-length strings.
162
*
163
* @param type the kind of control represented by this float control object
164
* @param minimum the smallest value permitted for the control
165
* @param maximum the largest value permitted for the control
166
* @param precision the resolution or granularity of the control. This is
167
* the size of the increment between discrete valid values.
168
* @param updatePeriod the smallest time interval, in microseconds, over
169
* which the control can change from one discrete value to the next
170
* during a {@link #shift(float,float,int) shift}
171
* @param initialValue the value that the control starts with when
172
* constructed
173
* @param units the label for the units in which the control's values are
174
* expressed, such as "dB" or "frames per second"
175
* @throws IllegalArgumentException if {@code minimum} is greater than
176
* {@code maximum} or {@code initialValue} does not fall within the
177
* allowable range
178
*/
179
protected FloatControl(Type type, float minimum, float maximum,
180
float precision, int updatePeriod, float initialValue, String units) {
181
this(type, minimum, maximum, precision, updatePeriod,
182
initialValue, units, "", "", "");
183
}
184
185
/**
186
* Sets the current value for the control. The default implementation simply
187
* sets the value as indicated. If the value indicated is greater than the
188
* maximum value, or smaller than the minimum value, an
189
* {@code IllegalArgumentException} is thrown. Some controls require that
190
* their line be open before they can be affected by setting a value.
191
*
192
* @param newValue desired new value
193
* @throws IllegalArgumentException if the value indicated does not fall
194
* within the allowable range
195
*/
196
public void setValue(float newValue) {
197
198
if (newValue > maximum) {
199
throw new IllegalArgumentException("Requested value " + newValue + " exceeds allowable maximum value " + maximum + ".");
200
}
201
202
if (newValue < minimum) {
203
throw new IllegalArgumentException("Requested value " + newValue + " smaller than allowable minimum value " + minimum + ".");
204
}
205
206
value = newValue;
207
}
208
209
/**
210
* Obtains this control's current value.
211
*
212
* @return the current value
213
*/
214
public float getValue() {
215
return value;
216
}
217
218
/**
219
* Obtains the maximum value permitted.
220
*
221
* @return the maximum allowable value
222
*/
223
public float getMaximum() {
224
return maximum;
225
}
226
227
/**
228
* Obtains the minimum value permitted.
229
*
230
* @return the minimum allowable value
231
*/
232
public float getMinimum() {
233
return minimum;
234
}
235
236
/**
237
* Obtains the label for the units in which the control's values are
238
* expressed, such as "dB" or "frames per second."
239
*
240
* @return the units label, or a zero-length string if no label
241
*/
242
public String getUnits() {
243
return units;
244
}
245
246
/**
247
* Obtains the label for the minimum value, such as "Left" or "Off".
248
*
249
* @return the minimum value label, or a zero-length string if no label has
250
* been set
251
*/
252
public String getMinLabel() {
253
return minLabel;
254
}
255
256
/**
257
* Obtains the label for the mid-point value, such as "Center" or "Default".
258
*
259
* @return the mid-point value label, or a zero-length string if no label
260
* has been set
261
*/
262
public String getMidLabel() {
263
return midLabel;
264
}
265
266
/**
267
* Obtains the label for the maximum value, such as "Right" or "Full".
268
*
269
* @return the maximum value label, or a zero-length string if no label has
270
* been set
271
*/
272
public String getMaxLabel() {
273
return maxLabel;
274
}
275
276
/**
277
* Obtains the resolution or granularity of the control, in the units that
278
* the control measures. The precision is the size of the increment between
279
* discrete valid values for this control, over the set of supported
280
* floating-point values.
281
*
282
* @return the control's precision
283
*/
284
public float getPrecision() {
285
return precision;
286
}
287
288
/**
289
* Obtains the smallest time interval, in microseconds, over which the
290
* control's value can change during a shift. The update period is the
291
* inverse of the frequency with which the control updates its value during
292
* a shift. If the implementation does not support value shifting over time,
293
* it should set the control's value to the final value immediately and
294
* return -1 from this method.
295
*
296
* @return update period in microseconds, or -1 if shifting over time is
297
* unsupported
298
* @see #shift
299
*/
300
public int getUpdatePeriod() {
301
return updatePeriod;
302
}
303
304
/**
305
* Changes the control value from the initial value to the final value
306
* linearly over the specified time period, specified in microseconds. This
307
* method returns without blocking; it does not wait for the shift to
308
* complete. An implementation should complete the operation within the time
309
* specified. The default implementation simply changes the value to the
310
* final value immediately.
311
*
312
* @param from initial value at the beginning of the shift
313
* @param to final value after the shift
314
* @param microseconds maximum duration of the shift in microseconds
315
* @throws IllegalArgumentException if either {@code from} or {@code to}
316
* value does not fall within the allowable range
317
* @see #getUpdatePeriod
318
*/
319
public void shift(float from, float to, int microseconds) {
320
// test "from" value, "to" value will be tested by setValue()
321
if (from < minimum) {
322
throw new IllegalArgumentException("Requested value " + from
323
+ " smaller than allowable minimum value " + minimum + ".");
324
}
325
if (from > maximum) {
326
throw new IllegalArgumentException("Requested value " + from
327
+ " exceeds allowable maximum value " + maximum + ".");
328
}
329
setValue(to);
330
}
331
332
/**
333
* Returns a string representation of the float control.
334
*
335
* @return a string representation of the float control
336
*/
337
@Override
338
public String toString() {
339
return String.format("%s with current value: %s %s (range: %s - %s)",
340
super.toString(), getValue(), getUnits(),
341
getMinimum(), getMaximum());
342
}
343
344
/**
345
* An instance of the {@code FloatControl.Type} inner class identifies one
346
* kind of float control. Static instances are provided for the common
347
* types.
348
*
349
* @author Kara Kytle
350
* @since 1.3
351
*/
352
public static class Type extends Control.Type {
353
354
/**
355
* Represents a control for the overall gain on a line.
356
* <p>
357
* Gain is a quantity in decibels (dB) that is added to the intrinsic
358
* decibel level of the audio signal--that is, the level of the signal
359
* before it is altered by the gain control. A positive gain amplifies
360
* (boosts) the signal's volume, and a negative gain attenuates(cuts)it.
361
* The gain setting defaults to a value of 0.0 dB, meaning the signal's
362
* loudness is unaffected. Note that gain measures dB, not amplitude.
363
* The relationship between a gain in decibels and the corresponding
364
* linear amplitude multiplier is:
365
* <p style="text-align:center">
366
* {@code linearScalar = pow(10.0, gainDB/20.0)}
367
* <p>
368
* The {@code FloatControl} class has methods to impose a maximum and
369
* minimum allowable value for gain. However, because an audio signal
370
* might already be at a high amplitude, the maximum setting does not
371
* guarantee that the signal will be undistorted when the gain is
372
* applied to it (unless the maximum is zero or negative). To avoid
373
* numeric overflow from excessively large gain settings, a gain control
374
* can implement clipping, meaning that the signal's amplitude will be
375
* limited to the maximum value representable by its audio format,
376
* instead of wrapping around.
377
* <p>
378
* These comments apply to gain controls in general, not just master
379
* gain controls. A line can have more than one gain control. For
380
* example, a mixer (which is itself a line) might have a master gain
381
* control, an auxiliary return control, a reverb return control, and,
382
* on each of its source lines, an individual aux send and reverb send.
383
*
384
* @see #AUX_SEND
385
* @see #AUX_RETURN
386
* @see #REVERB_SEND
387
* @see #REVERB_RETURN
388
* @see #VOLUME
389
*/
390
public static final Type MASTER_GAIN = new Type("Master Gain");
391
392
/**
393
* Represents a control for the auxiliary send gain on a line.
394
*
395
* @see #MASTER_GAIN
396
* @see #AUX_RETURN
397
*/
398
public static final Type AUX_SEND = new Type("AUX Send");
399
400
/**
401
* Represents a control for the auxiliary return gain on a line.
402
*
403
* @see #MASTER_GAIN
404
* @see #AUX_SEND
405
*/
406
public static final Type AUX_RETURN = new Type("AUX Return");
407
408
/**
409
* Represents a control for the pre-reverb gain on a line. This control
410
* may be used to affect how much of a line's signal is directed to a
411
* mixer's internal reverberation unit.
412
*
413
* @see #MASTER_GAIN
414
* @see #REVERB_RETURN
415
* @see EnumControl.Type#REVERB
416
*/
417
public static final Type REVERB_SEND = new Type("Reverb Send");
418
419
/**
420
* Represents a control for the post-reverb gain on a line. This control
421
* may be used to control the relative amplitude of the signal returned
422
* from an internal reverberation unit.
423
*
424
* @see #MASTER_GAIN
425
* @see #REVERB_SEND
426
*/
427
public static final Type REVERB_RETURN = new Type("Reverb Return");
428
429
/**
430
* Represents a control for the volume on a line.
431
*/
432
/*
433
* $$kk: 08.30.99: ISSUE: what units? linear or dB?
434
*/
435
public static final Type VOLUME = new Type("Volume");
436
437
/**
438
* Represents a control for the relative pan (left-right positioning) of
439
* the signal. The signal may be mono; the pan setting affects how it is
440
* distributed by the mixer in a stereo mix. The valid range of values
441
* is -1.0 (left channel only) to 1.0 (right channel only). The default
442
* is 0.0 (centered).
443
*
444
* @see #BALANCE
445
*/
446
public static final Type PAN = new Type("Pan");
447
448
/**
449
* Represents a control for the relative balance of a stereo signal
450
* between two stereo speakers. The valid range of values is -1.0 (left
451
* channel only) to 1.0 (right channel only). The default is 0.0
452
* (centered).
453
*
454
* @see #PAN
455
*/
456
public static final Type BALANCE = new Type("Balance");
457
458
/**
459
* Represents a control that changes the sample rate of audio playback.
460
* The net effect of changing the sample rate depends on the
461
* relationship between the media's natural rate and the rate that is
462
* set via this control. The natural rate is the sample rate that is
463
* specified in the data line's {@code AudioFormat} object. For example,
464
* if the natural rate of the media is 11025 samples per second and the
465
* sample rate is set to 22050 samples per second, the media will play
466
* back at twice the normal speed.
467
* <p>
468
* Changing the sample rate with this control does not affect the data
469
* line's audio format. Also note that whenever you change a sound's
470
* sample rate, a change in the sound's pitch results. For example,
471
* doubling the sample rate has the effect of doubling the frequencies
472
* in the sound's spectrum, which raises the pitch by an octave.
473
*/
474
public static final Type SAMPLE_RATE = new Type("Sample Rate");
475
476
/**
477
* Constructs a new float control type.
478
*
479
* @param name the name of the new float control type
480
*/
481
protected Type(final String name) {
482
super(name);
483
}
484
}
485
}
486
487