Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/sound/sampled/AudioFormat.java
38918 views
/*1* Copyright (c) 1999, 2013, 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;2627import java.util.Collections;28import java.util.HashMap;29import java.util.Map;3031/**32* <code>AudioFormat</code> is the class that specifies a particular arrangement of data in a sound stream.33* By examining the information stored in the audio format, you can discover how to interpret the bits in the34* binary sound data.35* <p>36* Every data line has an audio format associated with its data stream. The audio format of a source (playback) data line indicates37* what kind of data the data line expects to receive for output. For a target (capture) data line, the audio format specifies the kind38* of the data that can be read from the line.39* Sound files also have audio formats, of course. The <code>{@link AudioFileFormat}</code>40* class encapsulates an <code>AudioFormat</code> in addition to other,41* file-specific information. Similarly, an <code>{@link AudioInputStream}</code> has an42* <code>AudioFormat</code>.43* <p>44* The <code>AudioFormat</code> class accommodates a number of common sound-file encoding techniques, including45* pulse-code modulation (PCM), mu-law encoding, and a-law encoding. These encoding techniques are predefined,46* but service providers can create new encoding types.47* The encoding that a specific format uses is named by its <code>encoding</code> field.48*<p>49* In addition to the encoding, the audio format includes other properties that further specify the exact50* arrangement of the data.51* These include the number of channels, sample rate, sample size, byte order, frame rate, and frame size.52* Sounds may have different numbers of audio channels: one for mono, two for stereo.53* The sample rate measures how many "snapshots" (samples) of the sound pressure are taken per second, per channel.54* (If the sound is stereo rather than mono, two samples are actually measured at each instant of time: one for the left channel,55* and another for the right channel; however, the sample rate still measures the number per channel, so the rate is the same56* regardless of the number of channels. This is the standard use of the term.)57* The sample size indicates how many bits are used to store each snapshot; 8 and 16 are typical values.58* For 16-bit samples (or any other sample size larger than a byte),59* byte order is important; the bytes in each sample are arranged in60* either the "little-endian" or "big-endian" style.61* For encodings like PCM, a frame consists of the set of samples for all channels at a given62* point in time, and so the size of a frame (in bytes) is always equal to the size of a sample (in bytes) times63* the number of channels. However, with some other sorts of encodings a frame can contain64* a bundle of compressed data for a whole series of samples, as well as additional, non-sample65* data. For such encodings, the sample rate and sample size refer to the data after it is decoded into PCM,66* and so they are completely different from the frame rate and frame size.67*68* <p>An <code>AudioFormat</code> object can include a set of69* properties. A property is a pair of key and value: the key70* is of type <code>String</code>, the associated property71* value is an arbitrary object. Properties specify72* additional format specifications, like the bit rate for73* compressed formats. Properties are mainly used as a means74* to transport additional information of the audio format75* to and from the service providers. Therefore, properties76* are ignored in the {@link #matches(AudioFormat)} method.77* However, methods which rely on the installed service78* providers, like {@link AudioSystem#isConversionSupported79* (AudioFormat, AudioFormat) isConversionSupported} may consider80* properties, depending on the respective service provider81* implementation.82*83* <p>The following table lists some common properties which84* service providers should use, if applicable:85*86* <table border=0>87* <caption>Audio Format Properties</caption>88* <tr>89* <th>Property key</th>90* <th>Value type</th>91* <th>Description</th>92* </tr>93* <tr>94* <td>"bitrate"</td>95* <td>{@link java.lang.Integer Integer}</td>96* <td>average bit rate in bits per second</td>97* </tr>98* <tr>99* <td>"vbr"</td>100* <td>{@link java.lang.Boolean Boolean}</td>101* <td><code>true</code>, if the file is encoded in variable bit102* rate (VBR)</td>103* </tr>104* <tr>105* <td>"quality"</td>106* <td>{@link java.lang.Integer Integer}</td>107* <td>encoding/conversion quality, 1..100</td>108* </tr>109* </table>110*111* <p>Vendors of service providers (plugins) are encouraged112* to seek information about other already established113* properties in third party plugins, and follow the same114* conventions.115*116* @author Kara Kytle117* @author Florian Bomers118* @see DataLine#getFormat119* @see AudioInputStream#getFormat120* @see AudioFileFormat121* @see javax.sound.sampled.spi.FormatConversionProvider122* @since 1.3123*/124public class AudioFormat {125126// INSTANCE VARIABLES127128129/**130* The audio encoding technique used by this format.131*/132protected Encoding encoding;133134/**135* The number of samples played or recorded per second, for sounds that have this format.136*/137protected float sampleRate;138139/**140* The number of bits in each sample of a sound that has this format.141*/142protected int sampleSizeInBits;143144/**145* The number of audio channels in this format (1 for mono, 2 for stereo).146*/147protected int channels;148149/**150* The number of bytes in each frame of a sound that has this format.151*/152protected int frameSize;153154/**155* The number of frames played or recorded per second, for sounds that have this format.156*/157protected float frameRate;158159/**160* Indicates whether the audio data is stored in big-endian or little-endian order.161*/162protected boolean bigEndian;163164165/** The set of properties */166private HashMap<String, Object> properties;167168169/**170* Constructs an <code>AudioFormat</code> with the given parameters.171* The encoding specifies the convention used to represent the data.172* The other parameters are further explained in the {@link AudioFormat173* class description}.174* @param encoding the audio encoding technique175* @param sampleRate the number of samples per second176* @param sampleSizeInBits the number of bits in each sample177* @param channels the number of channels (1 for mono, 2 for stereo, and so on)178* @param frameSize the number of bytes in each frame179* @param frameRate the number of frames per second180* @param bigEndian indicates whether the data for a single sample181* is stored in big-endian byte order (<code>false</code>182* means little-endian)183*/184public AudioFormat(Encoding encoding, float sampleRate, int sampleSizeInBits,185int channels, int frameSize, float frameRate, boolean bigEndian) {186187this.encoding = encoding;188this.sampleRate = sampleRate;189this.sampleSizeInBits = sampleSizeInBits;190this.channels = channels;191this.frameSize = frameSize;192this.frameRate = frameRate;193this.bigEndian = bigEndian;194this.properties = null;195}196197198/**199* Constructs an <code>AudioFormat</code> with the given parameters.200* The encoding specifies the convention used to represent the data.201* The other parameters are further explained in the {@link AudioFormat202* class description}.203* @param encoding the audio encoding technique204* @param sampleRate the number of samples per second205* @param sampleSizeInBits the number of bits in each sample206* @param channels the number of channels (1 for mono, 2 for207* stereo, and so on)208* @param frameSize the number of bytes in each frame209* @param frameRate the number of frames per second210* @param bigEndian indicates whether the data for a single sample211* is stored in big-endian byte order212* (<code>false</code> means little-endian)213* @param properties a <code>Map<String,Object></code> object214* containing format properties215*216* @since 1.5217*/218public AudioFormat(Encoding encoding, float sampleRate,219int sampleSizeInBits, int channels,220int frameSize, float frameRate,221boolean bigEndian, Map<String, Object> properties) {222this(encoding, sampleRate, sampleSizeInBits, channels,223frameSize, frameRate, bigEndian);224this.properties = new HashMap<String, Object>(properties);225}226227228/**229* Constructs an <code>AudioFormat</code> with a linear PCM encoding and230* the given parameters. The frame size is set to the number of bytes231* required to contain one sample from each channel, and the frame rate232* is set to the sample rate.233*234* @param sampleRate the number of samples per second235* @param sampleSizeInBits the number of bits in each sample236* @param channels the number of channels (1 for mono, 2 for stereo, and so on)237* @param signed indicates whether the data is signed or unsigned238* @param bigEndian indicates whether the data for a single sample239* is stored in big-endian byte order (<code>false</code>240* means little-endian)241*/242public AudioFormat(float sampleRate, int sampleSizeInBits,243int channels, boolean signed, boolean bigEndian) {244245this((signed == true ? Encoding.PCM_SIGNED : Encoding.PCM_UNSIGNED),246sampleRate,247sampleSizeInBits,248channels,249(channels == AudioSystem.NOT_SPECIFIED || sampleSizeInBits == AudioSystem.NOT_SPECIFIED)?250AudioSystem.NOT_SPECIFIED:251((sampleSizeInBits + 7) / 8) * channels,252sampleRate,253bigEndian);254}255256/**257* Obtains the type of encoding for sounds in this format.258*259* @return the encoding type260* @see Encoding#PCM_SIGNED261* @see Encoding#PCM_UNSIGNED262* @see Encoding#ULAW263* @see Encoding#ALAW264*/265public Encoding getEncoding() {266267return encoding;268}269270/**271* Obtains the sample rate.272* For compressed formats, the return value is the sample rate of the uncompressed273* audio data.274* When this AudioFormat is used for queries (e.g. {@link275* AudioSystem#isConversionSupported(AudioFormat, AudioFormat)276* AudioSystem.isConversionSupported}) or capabilities (e.g. {@link277* DataLine.Info#getFormats() DataLine.Info.getFormats}), a sample rate of278* <code>AudioSystem.NOT_SPECIFIED</code> means that any sample rate is279* acceptable. <code>AudioSystem.NOT_SPECIFIED</code> is also returned when280* the sample rate is not defined for this audio format.281* @return the number of samples per second,282* or <code>AudioSystem.NOT_SPECIFIED</code>283*284* @see #getFrameRate()285* @see AudioSystem#NOT_SPECIFIED286*/287public float getSampleRate() {288289return sampleRate;290}291292/**293* Obtains the size of a sample.294* For compressed formats, the return value is the sample size of the295* uncompressed audio data.296* When this AudioFormat is used for queries (e.g. {@link297* AudioSystem#isConversionSupported(AudioFormat, AudioFormat)298* AudioSystem.isConversionSupported}) or capabilities (e.g. {@link299* DataLine.Info#getFormats() DataLine.Info.getFormats}), a sample size of300* <code>AudioSystem.NOT_SPECIFIED</code> means that any sample size is301* acceptable. <code>AudioSystem.NOT_SPECIFIED</code> is also returned when302* the sample size is not defined for this audio format.303* @return the number of bits in each sample,304* or <code>AudioSystem.NOT_SPECIFIED</code>305*306* @see #getFrameSize()307* @see AudioSystem#NOT_SPECIFIED308*/309public int getSampleSizeInBits() {310311return sampleSizeInBits;312}313314/**315* Obtains the number of channels.316* When this AudioFormat is used for queries (e.g. {@link317* AudioSystem#isConversionSupported(AudioFormat, AudioFormat)318* AudioSystem.isConversionSupported}) or capabilities (e.g. {@link319* DataLine.Info#getFormats() DataLine.Info.getFormats}), a return value of320* <code>AudioSystem.NOT_SPECIFIED</code> means that any (positive) number of channels is321* acceptable.322* @return The number of channels (1 for mono, 2 for stereo, etc.),323* or <code>AudioSystem.NOT_SPECIFIED</code>324*325* @see AudioSystem#NOT_SPECIFIED326*/327public int getChannels() {328329return channels;330}331332/**333* Obtains the frame size in bytes.334* When this AudioFormat is used for queries (e.g. {@link335* AudioSystem#isConversionSupported(AudioFormat, AudioFormat)336* AudioSystem.isConversionSupported}) or capabilities (e.g. {@link337* DataLine.Info#getFormats() DataLine.Info.getFormats}), a frame size of338* <code>AudioSystem.NOT_SPECIFIED</code> means that any frame size is339* acceptable. <code>AudioSystem.NOT_SPECIFIED</code> is also returned when340* the frame size is not defined for this audio format.341* @return the number of bytes per frame,342* or <code>AudioSystem.NOT_SPECIFIED</code>343*344* @see #getSampleSizeInBits()345* @see AudioSystem#NOT_SPECIFIED346*/347public int getFrameSize() {348349return frameSize;350}351352/**353* Obtains the frame rate in frames per second.354* When this AudioFormat is used for queries (e.g. {@link355* AudioSystem#isConversionSupported(AudioFormat, AudioFormat)356* AudioSystem.isConversionSupported}) or capabilities (e.g. {@link357* DataLine.Info#getFormats() DataLine.Info.getFormats}), a frame rate of358* <code>AudioSystem.NOT_SPECIFIED</code> means that any frame rate is359* acceptable. <code>AudioSystem.NOT_SPECIFIED</code> is also returned when360* the frame rate is not defined for this audio format.361* @return the number of frames per second,362* or <code>AudioSystem.NOT_SPECIFIED</code>363*364* @see #getSampleRate()365* @see AudioSystem#NOT_SPECIFIED366*/367public float getFrameRate() {368369return frameRate;370}371372373/**374* Indicates whether the audio data is stored in big-endian or little-endian375* byte order. If the sample size is not more than one byte, the return value is376* irrelevant.377* @return <code>true</code> if the data is stored in big-endian byte order,378* <code>false</code> if little-endian379*/380public boolean isBigEndian() {381382return bigEndian;383}384385386/**387* Obtain an unmodifiable map of properties.388* The concept of properties is further explained in389* the {@link AudioFileFormat class description}.390*391* @return a <code>Map<String,Object></code> object containing392* all properties. If no properties are recognized, an empty map is393* returned.394*395* @see #getProperty(String)396* @since 1.5397*/398public Map<String,Object> properties() {399Map<String,Object> ret;400if (properties == null) {401ret = new HashMap<String,Object>(0);402} else {403ret = (Map<String,Object>) (properties.clone());404}405return (Map<String,Object>) Collections.unmodifiableMap(ret);406}407408409/**410* Obtain the property value specified by the key.411* The concept of properties is further explained in412* the {@link AudioFileFormat class description}.413*414* <p>If the specified property is not defined for a415* particular file format, this method returns416* <code>null</code>.417*418* @param key the key of the desired property419* @return the value of the property with the specified key,420* or <code>null</code> if the property does not exist.421*422* @see #properties()423* @since 1.5424*/425public Object getProperty(String key) {426if (properties == null) {427return null;428}429return properties.get(key);430}431432433/**434* Indicates whether this format matches the one specified.435* To match, two formats must have the same encoding,436* and consistent values of the number of channels, sample rate, sample size,437* frame rate, and frame size.438* The values of the property are consistent if they are equal439* or the specified format has the property value440* {@code AudioSystem.NOT_SPECIFIED}.441* The byte order (big-endian or little-endian) must be the same442* if the sample size is greater than one byte.443*444* @param format format to test for match445* @return {@code true} if this format matches the one specified,446* {@code false} otherwise.447*/448public boolean matches(AudioFormat format) {449if (format.getEncoding().equals(getEncoding())450&& (format.getChannels() == AudioSystem.NOT_SPECIFIED451|| format.getChannels() == getChannels())452&& (format.getSampleRate() == (float)AudioSystem.NOT_SPECIFIED453|| format.getSampleRate() == getSampleRate())454&& (format.getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED455|| format.getSampleSizeInBits() == getSampleSizeInBits())456&& (format.getFrameRate() == (float)AudioSystem.NOT_SPECIFIED457|| format.getFrameRate() == getFrameRate())458&& (format.getFrameSize() == AudioSystem.NOT_SPECIFIED459|| format.getFrameSize() == getFrameSize())460&& (getSampleSizeInBits() <= 8461|| format.isBigEndian() == isBigEndian())) {462return true;463}464return false;465}466467468/**469* Returns a string that describes the format, such as:470* "PCM SIGNED 22050 Hz 16 bit mono big-endian". The contents of the string471* may vary between implementations of Java Sound.472*473* @return a string that describes the format parameters474*/475public String toString() {476String sEncoding = "";477if (getEncoding() != null) {478sEncoding = getEncoding().toString() + " ";479}480481String sSampleRate;482if (getSampleRate() == (float) AudioSystem.NOT_SPECIFIED) {483sSampleRate = "unknown sample rate, ";484} else {485sSampleRate = "" + getSampleRate() + " Hz, ";486}487488String sSampleSizeInBits;489if (getSampleSizeInBits() == (float) AudioSystem.NOT_SPECIFIED) {490sSampleSizeInBits = "unknown bits per sample, ";491} else {492sSampleSizeInBits = "" + getSampleSizeInBits() + " bit, ";493}494495String sChannels;496if (getChannels() == 1) {497sChannels = "mono, ";498} else499if (getChannels() == 2) {500sChannels = "stereo, ";501} else {502if (getChannels() == AudioSystem.NOT_SPECIFIED) {503sChannels = " unknown number of channels, ";504} else {505sChannels = ""+getChannels()+" channels, ";506}507}508509String sFrameSize;510if (getFrameSize() == (float) AudioSystem.NOT_SPECIFIED) {511sFrameSize = "unknown frame size, ";512} else {513sFrameSize = "" + getFrameSize()+ " bytes/frame, ";514}515516String sFrameRate = "";517if (Math.abs(getSampleRate() - getFrameRate()) > 0.00001) {518if (getFrameRate() == (float) AudioSystem.NOT_SPECIFIED) {519sFrameRate = "unknown frame rate, ";520} else {521sFrameRate = getFrameRate() + " frames/second, ";522}523}524525String sEndian = "";526if ((getEncoding().equals(Encoding.PCM_SIGNED)527|| getEncoding().equals(Encoding.PCM_UNSIGNED))528&& ((getSampleSizeInBits() > 8)529|| (getSampleSizeInBits() == AudioSystem.NOT_SPECIFIED))) {530if (isBigEndian()) {531sEndian = "big-endian";532} else {533sEndian = "little-endian";534}535}536537return sEncoding538+ sSampleRate539+ sSampleSizeInBits540+ sChannels541+ sFrameSize542+ sFrameRate543+ sEndian;544545}546547/**548* The <code>Encoding</code> class names the specific type of data representation549* used for an audio stream. The encoding includes aspects of the550* sound format other than the number of channels, sample rate, sample size,551* frame rate, frame size, and byte order.552* <p>553* One ubiquitous type of audio encoding is pulse-code modulation (PCM),554* which is simply a linear (proportional) representation of the sound555* waveform. With PCM, the number stored in each sample is proportional556* to the instantaneous amplitude of the sound pressure at that point in557* time. The numbers may be signed or unsigned integers or floats.558* Besides PCM, other encodings include mu-law and a-law, which are nonlinear559* mappings of the sound amplitude that are often used for recording speech.560* <p>561* You can use a predefined encoding by referring to one of the static562* objects created by this class, such as PCM_SIGNED or563* PCM_UNSIGNED. Service providers can create new encodings, such as564* compressed audio formats, and make565* these available through the <code>{@link AudioSystem}</code> class.566* <p>567* The <code>Encoding</code> class is static, so that all568* <code>AudioFormat</code> objects that have the same encoding will refer569* to the same object (rather than different instances of the same class).570* This allows matches to be made by checking that two format's encodings571* are equal.572*573* @see AudioFormat574* @see javax.sound.sampled.spi.FormatConversionProvider575*576* @author Kara Kytle577* @since 1.3578*/579public static class Encoding {580581582// ENCODING DEFINES583584/**585* Specifies signed, linear PCM data.586*/587public static final Encoding PCM_SIGNED = new Encoding("PCM_SIGNED");588589/**590* Specifies unsigned, linear PCM data.591*/592public static final Encoding PCM_UNSIGNED = new Encoding("PCM_UNSIGNED");593594/**595* Specifies floating-point PCM data.596*597* @since 1.7598*/599public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");600601/**602* Specifies u-law encoded data.603*/604public static final Encoding ULAW = new Encoding("ULAW");605606/**607* Specifies a-law encoded data.608*/609public static final Encoding ALAW = new Encoding("ALAW");610611612// INSTANCE VARIABLES613614/**615* Encoding name.616*/617private String name;618619620// CONSTRUCTOR621622/**623* Constructs a new encoding.624* @param name the name of the new type of encoding625*/626public Encoding(String name) {627this.name = name;628}629630631// METHODS632633/**634* Finalizes the equals method635*/636public final boolean equals(Object obj) {637if (toString() == null) {638return (obj != null) && (obj.toString() == null);639}640if (obj instanceof Encoding) {641return toString().equals(obj.toString());642}643return false;644}645646/**647* Finalizes the hashCode method648*/649public final int hashCode() {650if (toString() == null) {651return 0;652}653return toString().hashCode();654}655656/**657* Provides the <code>String</code> representation of the encoding. This <code>String</code> is658* the same name that was passed to the constructor. For the predefined encodings, the name659* is similar to the encoding's variable (field) name. For example, <code>PCM_SIGNED.toString()</code> returns660* the name "pcm_signed".661*662* @return the encoding name663*/664public final String toString() {665return name;666}667668} // class Encoding669}670671672