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