Path: blob/master/src/java.desktop/share/classes/javax/sound/sampled/FloatControl.java
41159 views
/*1* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.sound.sampled;2627/**28* A {@code FloatControl} object provides control over a range of floating-point29* values. Float controls are often represented in graphical user interfaces by30* continuously adjustable objects such as sliders or rotary knobs. Concrete31* subclasses of {@code FloatControl} implement controls, such as gain and pan,32* that affect a line's audio signal in some way that an application can33* manipulate. The {@link FloatControl.Type} inner class provides static34* instances of types that are used to identify some common kinds of float35* control.36* <p>37* The {@code FloatControl} abstract class provides methods to set and get the38* control's current floating-point value. Other methods obtain the possible39* range of values and the control's resolution (the smallest increment between40* returned values). Some float controls allow ramping to a new value over a41* specified period of time. {@code FloatControl} also includes methods that42* return string labels for the minimum, maximum, and midpoint positions of the43* control.44*45* @author David Rivas46* @author Kara Kytle47* @see Line#getControls48* @see Line#isControlSupported49* @since 1.350*/51public abstract class FloatControl extends Control {5253/**54* The minimum supported value.55*/56private final float minimum;5758/**59* The maximum supported value.60*/61private final float maximum;6263/**64* The control's precision.65*/66private final float precision;6768/**69* The smallest time increment in which a value change can be effected70* during a value shift, in microseconds.71*/72private final int updatePeriod;7374/**75* A label for the units in which the control values are expressed, such as76* "dB" for decibels.77*/78private final String units;7980/**81* A label for the minimum value, such as "Left".82*/83private final String minLabel;8485/**86* A label for the maximum value, such as "Right".87*/88private final String maxLabel;8990/**91* A label for the mid-point value, such as "Center".92*/93private final String midLabel;9495/**96* The current value.97*/98private float value;99100/**101* Constructs a new float control object with the given parameters.102*103* @param type the kind of control represented by this float control object104* @param minimum the smallest value permitted for the control105* @param maximum the largest value permitted for the control106* @param precision the resolution or granularity of the control. This is107* the size of the increment between discrete valid values.108* @param updatePeriod the smallest time interval, in microseconds, over109* which the control can change from one discrete value to the next110* during a {@link #shift(float,float,int) shift}111* @param initialValue the value that the control starts with when112* constructed113* @param units the label for the units in which the control's values are114* expressed, such as "dB" or "frames per second"115* @param minLabel the label for the minimum value, such as "Left" or "Off"116* @param midLabel the label for the midpoint value, such as "Center" or117* "Default"118* @param maxLabel the label for the maximum value, such as "Right" or119* "Full"120* @throws IllegalArgumentException if {@code minimum} is greater than121* {@code maximum} or {@code initialValue} does not fall within the122* allowable range123*/124protected FloatControl(Type type, float minimum, float maximum,125float precision, int updatePeriod, float initialValue,126String units, String minLabel, String midLabel, String maxLabel) {127128super(type);129130if (minimum > maximum) {131throw new IllegalArgumentException("Minimum value " + minimum132+ " exceeds maximum value " + maximum + ".");133}134if (initialValue < minimum) {135throw new IllegalArgumentException("Initial value " + initialValue136+ " smaller than allowable minimum value " + minimum + ".");137}138if (initialValue > maximum) {139throw new IllegalArgumentException("Initial value " + initialValue140+ " exceeds allowable maximum value " + maximum + ".");141}142143144this.minimum = minimum;145this.maximum = maximum;146147this.precision = precision;148this.updatePeriod = updatePeriod;149this.value = initialValue;150151this.units = units;152this.minLabel = ( (minLabel == null) ? "" : minLabel);153this.midLabel = ( (midLabel == null) ? "" : midLabel);154this.maxLabel = ( (maxLabel == null) ? "" : maxLabel);155}156157/**158* Constructs a new float control object with the given parameters. The159* labels for the minimum, maximum, and mid-point values are set to160* zero-length strings.161*162* @param type the kind of control represented by this float control object163* @param minimum the smallest value permitted for the control164* @param maximum the largest value permitted for the control165* @param precision the resolution or granularity of the control. This is166* the size of the increment between discrete valid values.167* @param updatePeriod the smallest time interval, in microseconds, over168* which the control can change from one discrete value to the next169* during a {@link #shift(float,float,int) shift}170* @param initialValue the value that the control starts with when171* constructed172* @param units the label for the units in which the control's values are173* expressed, such as "dB" or "frames per second"174* @throws IllegalArgumentException if {@code minimum} is greater than175* {@code maximum} or {@code initialValue} does not fall within the176* allowable range177*/178protected FloatControl(Type type, float minimum, float maximum,179float precision, int updatePeriod, float initialValue, String units) {180this(type, minimum, maximum, precision, updatePeriod,181initialValue, units, "", "", "");182}183184/**185* Sets the current value for the control. The default implementation simply186* sets the value as indicated. If the value indicated is greater than the187* maximum value, or smaller than the minimum value, an188* {@code IllegalArgumentException} is thrown. Some controls require that189* their line be open before they can be affected by setting a value.190*191* @param newValue desired new value192* @throws IllegalArgumentException if the value indicated does not fall193* within the allowable range194*/195public void setValue(float newValue) {196197if (newValue > maximum) {198throw new IllegalArgumentException("Requested value " + newValue + " exceeds allowable maximum value " + maximum + ".");199}200201if (newValue < minimum) {202throw new IllegalArgumentException("Requested value " + newValue + " smaller than allowable minimum value " + minimum + ".");203}204205value = newValue;206}207208/**209* Obtains this control's current value.210*211* @return the current value212*/213public float getValue() {214return value;215}216217/**218* Obtains the maximum value permitted.219*220* @return the maximum allowable value221*/222public float getMaximum() {223return maximum;224}225226/**227* Obtains the minimum value permitted.228*229* @return the minimum allowable value230*/231public float getMinimum() {232return minimum;233}234235/**236* Obtains the label for the units in which the control's values are237* expressed, such as "dB" or "frames per second."238*239* @return the units label, or a zero-length string if no label240*/241public String getUnits() {242return units;243}244245/**246* Obtains the label for the minimum value, such as "Left" or "Off".247*248* @return the minimum value label, or a zero-length string if no label has249* been set250*/251public String getMinLabel() {252return minLabel;253}254255/**256* Obtains the label for the mid-point value, such as "Center" or "Default".257*258* @return the mid-point value label, or a zero-length string if no label259* has been set260*/261public String getMidLabel() {262return midLabel;263}264265/**266* Obtains the label for the maximum value, such as "Right" or "Full".267*268* @return the maximum value label, or a zero-length string if no label has269* been set270*/271public String getMaxLabel() {272return maxLabel;273}274275/**276* Obtains the resolution or granularity of the control, in the units that277* the control measures. The precision is the size of the increment between278* discrete valid values for this control, over the set of supported279* floating-point values.280*281* @return the control's precision282*/283public float getPrecision() {284return precision;285}286287/**288* Obtains the smallest time interval, in microseconds, over which the289* control's value can change during a shift. The update period is the290* inverse of the frequency with which the control updates its value during291* a shift. If the implementation does not support value shifting over time,292* it should set the control's value to the final value immediately and293* return -1 from this method.294*295* @return update period in microseconds, or -1 if shifting over time is296* unsupported297* @see #shift298*/299public int getUpdatePeriod() {300return updatePeriod;301}302303/**304* Changes the control value from the initial value to the final value305* linearly over the specified time period, specified in microseconds. This306* method returns without blocking; it does not wait for the shift to307* complete. An implementation should complete the operation within the time308* specified. The default implementation simply changes the value to the309* final value immediately.310*311* @param from initial value at the beginning of the shift312* @param to final value after the shift313* @param microseconds maximum duration of the shift in microseconds314* @throws IllegalArgumentException if either {@code from} or {@code to}315* value does not fall within the allowable range316* @see #getUpdatePeriod317*/318public void shift(float from, float to, int microseconds) {319// test "from" value, "to" value will be tested by setValue()320if (from < minimum) {321throw new IllegalArgumentException("Requested value " + from322+ " smaller than allowable minimum value " + minimum + ".");323}324if (from > maximum) {325throw new IllegalArgumentException("Requested value " + from326+ " exceeds allowable maximum value " + maximum + ".");327}328setValue(to);329}330331/**332* Returns a string representation of the float control.333*334* @return a string representation of the float control335*/336@Override337public String toString() {338return String.format("%s with current value: %s %s (range: %s - %s)",339super.toString(), getValue(), getUnits(),340getMinimum(), getMaximum());341}342343/**344* An instance of the {@code FloatControl.Type} inner class identifies one345* kind of float control. Static instances are provided for the common346* types.347*348* @author Kara Kytle349* @since 1.3350*/351public static class Type extends Control.Type {352353/**354* Represents a control for the overall gain on a line.355* <p>356* Gain is a quantity in decibels (dB) that is added to the intrinsic357* decibel level of the audio signal--that is, the level of the signal358* before it is altered by the gain control. A positive gain amplifies359* (boosts) the signal's volume, and a negative gain attenuates(cuts)it.360* The gain setting defaults to a value of 0.0 dB, meaning the signal's361* loudness is unaffected. Note that gain measures dB, not amplitude.362* The relationship between a gain in decibels and the corresponding363* linear amplitude multiplier is:364* <p style="text-align:center">365* {@code linearScalar = pow(10.0, gainDB/20.0)}366* <p>367* The {@code FloatControl} class has methods to impose a maximum and368* minimum allowable value for gain. However, because an audio signal369* might already be at a high amplitude, the maximum setting does not370* guarantee that the signal will be undistorted when the gain is371* applied to it (unless the maximum is zero or negative). To avoid372* numeric overflow from excessively large gain settings, a gain control373* can implement clipping, meaning that the signal's amplitude will be374* limited to the maximum value representable by its audio format,375* instead of wrapping around.376* <p>377* These comments apply to gain controls in general, not just master378* gain controls. A line can have more than one gain control. For379* example, a mixer (which is itself a line) might have a master gain380* control, an auxiliary return control, a reverb return control, and,381* on each of its source lines, an individual aux send and reverb send.382*383* @see #AUX_SEND384* @see #AUX_RETURN385* @see #REVERB_SEND386* @see #REVERB_RETURN387* @see #VOLUME388*/389public static final Type MASTER_GAIN = new Type("Master Gain");390391/**392* Represents a control for the auxiliary send gain on a line.393*394* @see #MASTER_GAIN395* @see #AUX_RETURN396*/397public static final Type AUX_SEND = new Type("AUX Send");398399/**400* Represents a control for the auxiliary return gain on a line.401*402* @see #MASTER_GAIN403* @see #AUX_SEND404*/405public static final Type AUX_RETURN = new Type("AUX Return");406407/**408* Represents a control for the pre-reverb gain on a line. This control409* may be used to affect how much of a line's signal is directed to a410* mixer's internal reverberation unit.411*412* @see #MASTER_GAIN413* @see #REVERB_RETURN414* @see EnumControl.Type#REVERB415*/416public static final Type REVERB_SEND = new Type("Reverb Send");417418/**419* Represents a control for the post-reverb gain on a line. This control420* may be used to control the relative amplitude of the signal returned421* from an internal reverberation unit.422*423* @see #MASTER_GAIN424* @see #REVERB_SEND425*/426public static final Type REVERB_RETURN = new Type("Reverb Return");427428/**429* Represents a control for the volume on a line.430*/431/*432* $$kk: 08.30.99: ISSUE: what units? linear or dB?433*/434public static final Type VOLUME = new Type("Volume");435436/**437* Represents a control for the relative pan (left-right positioning) of438* the signal. The signal may be mono; the pan setting affects how it is439* distributed by the mixer in a stereo mix. The valid range of values440* is -1.0 (left channel only) to 1.0 (right channel only). The default441* is 0.0 (centered).442*443* @see #BALANCE444*/445public static final Type PAN = new Type("Pan");446447/**448* Represents a control for the relative balance of a stereo signal449* between two stereo speakers. The valid range of values is -1.0 (left450* channel only) to 1.0 (right channel only). The default is 0.0451* (centered).452*453* @see #PAN454*/455public static final Type BALANCE = new Type("Balance");456457/**458* Represents a control that changes the sample rate of audio playback.459* The net effect of changing the sample rate depends on the460* relationship between the media's natural rate and the rate that is461* set via this control. The natural rate is the sample rate that is462* specified in the data line's {@code AudioFormat} object. For example,463* if the natural rate of the media is 11025 samples per second and the464* sample rate is set to 22050 samples per second, the media will play465* back at twice the normal speed.466* <p>467* Changing the sample rate with this control does not affect the data468* line's audio format. Also note that whenever you change a sound's469* sample rate, a change in the sound's pitch results. For example,470* doubling the sample rate has the effect of doubling the frequencies471* in the sound's spectrum, which raises the pitch by an octave.472*/473public static final Type SAMPLE_RATE = new Type("Sample Rate");474475/**476* Constructs a new float control type.477*478* @param name the name of the new float control type479*/480protected Type(final String name) {481super(name);482}483}484}485486487