Source for javax.sound.sampled.AudioFormat

   1: /* An audio format
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.sound.sampled;
  40: 
  41: import java.util.Collections;
  42: import java.util.HashMap;
  43: import java.util.Map;
  44: 
  45: /**
  46:  * This class describes an audio format, including its encoding,
  47:  * the number of channels, its frame rate, etc.
  48:  * @since 1.3
  49:  */
  50: public class AudioFormat
  51: {
  52:   /**
  53:    * This describes a given audio format encoding.
  54:    * @since 1.3
  55:    */
  56:   public static class Encoding
  57:   {
  58:     /** The ALAW encoding.  */
  59:     public static final Encoding ALAW = new Encoding("alaw");
  60: 
  61:     /** The signed PCM encoding.  */
  62:     public static final Encoding PCM_SIGNED = new Encoding("pcm_signed");
  63: 
  64:     /** The unsigned PCM encoding.  */
  65:     public static final Encoding PCM_UNSIGNED = new Encoding("pcm_unsigned");
  66: 
  67:     /** The ULAW encoding.  */
  68:     public static final Encoding ULAW = new Encoding("ulaw");
  69: 
  70:     private String name;
  71: 
  72:     /**
  73:      * Create a new encoding descriptor, given its name.
  74:      * @param name the name
  75:      */
  76:     public Encoding(String name)
  77:     {
  78:       this.name = name;
  79:     }
  80: 
  81:     public final boolean equals(Object o)
  82:     {
  83:       return super.equals(o);
  84:     }
  85: 
  86:     public final int hashCode()
  87:     {
  88:       return super.hashCode();
  89:     }
  90: 
  91:     /**
  92:      * Return the name of this encoding.
  93:      */
  94:     public final String toString()
  95:     {
  96:       return name;
  97:     }
  98:   }
  99: 
 100:   /**
 101:    * True if the audio data is stored big-endian.
 102:    */
 103:   protected boolean bigEndian;
 104: 
 105:   /**
 106:    * The number of channels of data in this format.
 107:    */
 108:   protected int channels;
 109: 
 110:   /**
 111:    * The encoding of this format.
 112:    */
 113:   protected Encoding encoding;
 114: 
 115:   /**
 116:    * The frame rate of this format.  This is the number of frames
 117:    * per second.
 118:    */
 119:   protected float frameRate;
 120: 
 121:   /**
 122:    * The number of bytes per frame in this format.
 123:    */
 124:   protected int frameSize;
 125: 
 126:   /**
 127:    * The number of samples per second.
 128:    */
 129:   protected float sampleRate;
 130: 
 131:   /**
 132:    * The number of bits in each sample.
 133:    */
 134:   protected int sampleSizeInBits;
 135: 
 136:   private Map<String, Object> properties;
 137: 
 138:   /**
 139:    * Create a new audio format, given various attributes of it.
 140:    * The properties map for this format will be empty.
 141:    * 
 142:    * @param encoding the encoding for this format
 143:    * @param sampleRate the sample rate
 144:    * @param sampleSizeInBits the sample size, in bits
 145:    * @param channels the number of channels
 146:    * @param frameSize the frame size, in bytes
 147:    * @param frameRate the frame rate, in frames per second
 148:    * @param bigEndian true if the data is stored big-endian
 149:    */
 150:   public AudioFormat(Encoding encoding, float sampleRate, int sampleSizeInBits,
 151:              int channels, int frameSize, float frameRate,
 152:              boolean bigEndian)
 153:   {
 154:     this.encoding = encoding;
 155:     this.sampleRate = sampleRate;
 156:     this.sampleSizeInBits = sampleSizeInBits;
 157:     this.channels = channels;
 158:     this.frameSize = frameSize;
 159:     this.frameRate = frameRate;
 160:     this.bigEndian = bigEndian;
 161:     this.properties = Collections.<String, Object> emptyMap();
 162:   }
 163: 
 164:   /**
 165:    * Create a new audio format, given various attributes of it.
 166:    * The properties map is copied by this constructor, so changes
 167:    * to the argument Map will not affect the new object.
 168:    *
 169:    * @param encoding the encoding for this format
 170:    * @param sampleRate the sample rate
 171:    * @param sampleSizeInBits the sample size, in bits
 172:    * @param channels the number of channels
 173:    * @param frameSize the frame size, in bytes
 174:    * @param frameRate the frame rate, in frames per second
 175:    * @param bigEndian true if the data is stored big-endian
 176:    * @param properties a map describing properties of this format
 177:    */
 178:   public AudioFormat(Encoding encoding, float sampleRate, int sampleSizeInBits,
 179:              int channels, int frameSize, float frameRate,
 180:              boolean bigEndian, Map<String, Object> properties)
 181:   {
 182:     this.encoding = encoding;
 183:     this.sampleRate = sampleRate;
 184:     this.sampleSizeInBits = sampleSizeInBits;
 185:     this.channels = channels;
 186:     this.frameSize = frameSize;
 187:     this.frameRate = frameRate;
 188:     this.bigEndian = bigEndian;
 189:     this.properties = Collections.unmodifiableMap(new HashMap<String, Object>(properties));
 190:   }
 191: 
 192:   /**
 193:    * Create a new PCM-based audio format, given various attributes of it.
 194:    * The encoding will either be Encoding#PCM_SIGNED or Encoding#PCM_UNSIGNED.
 195:    * The frame size for this format will be derived from the sample size in
 196:    * bits and the number of channels, unless one of those is
 197:    * AudioSystem#NOT_SPECIFIED.  The frame rate will be the same as the sample
 198:    * rate, and the properties map will be empty.
 199:    * 
 200:    * @param sampleRate the sample rate
 201:    * @param sampleSizeInBits the sample size, in bits
 202:    * @param channels the number of channels
 203:    * @param signed true if this is a signed encoding
 204:    * @param bigEndian true if the data is stored big-endian
 205:    */
 206:   public AudioFormat(float sampleRate, int sampleSizeInBits,
 207:              int channels, boolean signed, boolean bigEndian)
 208:   {
 209:     this.encoding = signed ? Encoding.PCM_SIGNED : Encoding.PCM_UNSIGNED;
 210:     this.sampleRate = sampleRate;
 211:     this.sampleSizeInBits = sampleSizeInBits;
 212:     this.channels = channels;
 213:     // It isn't clear whether channels can be NOT_SPECIFIED.
 214:     if (sampleSizeInBits == AudioSystem.NOT_SPECIFIED
 215:         || channels == AudioSystem.NOT_SPECIFIED)
 216:       this.frameSize = AudioSystem.NOT_SPECIFIED;
 217:     else
 218:       this.frameSize = (sampleSizeInBits + 7) / 8 * channels;
 219:     this.frameRate = sampleRate;
 220:     this.bigEndian = bigEndian;
 221:     this.properties = Collections.<String, Object> emptyMap();
 222:   }
 223: 
 224:   /**
 225:    * Return the number of channels in this format.
 226:    */
 227:   public int getChannels()
 228:   {
 229:     return channels;
 230:   }
 231: 
 232:   /**
 233:    * Return the encoding of this format.
 234:    */
 235:   public Encoding getEncoding()
 236:   {
 237:     return encoding;
 238:   }
 239: 
 240:   /**
 241:    * Return the frame rate of this format.
 242:    */
 243:   public float getFrameRate()
 244:   {
 245:     return frameRate;
 246:   }
 247: 
 248:   /**
 249:    * Return the frame size of this format.
 250:    */
 251:   public int getFrameSize()
 252:   {
 253:     return frameSize;
 254:   }
 255: 
 256:   /**
 257:    * Given a key, return a property associated with this format;
 258:    * or null if this property is not set. 
 259:    * @param key the name of the property
 260:    * @return the value of the property, or null if the property is not set
 261:    */
 262:   public Object getProperty(String key)
 263:   {
 264:     return properties.get(key);
 265:   }
 266: 
 267:   /**
 268:    * Return the sample rate of this format.
 269:    */
 270:   public float getSampleRate()
 271:   {
 272:     return sampleRate;
 273:   }
 274: 
 275:   /**
 276:    * Return the sample size of this format, in bits.
 277:    */
 278:   public int getSampleSizeInBits()
 279:   {
 280:     return sampleSizeInBits;
 281:   }
 282: 
 283:   /**
 284:    * Return true if this format is big endian, false otherwise.
 285:    * This only matters for formats whose sample size is greater than
 286:    * one byte.
 287:    */
 288:   public boolean isBigEndian()
 289:   {
 290:     return bigEndian;
 291:   }
 292: 
 293:   /**
 294:    * Return true if this audio format matches another.
 295:    * @param fmt the format to match against
 296:    * @return true if they match, false otherwise
 297:    */
 298:   public boolean matches(AudioFormat fmt)
 299:   {
 300:     if (! encoding.equals(fmt.encoding)
 301:         || channels != fmt.channels
 302:         || sampleSizeInBits != fmt.sampleSizeInBits
 303:         || frameSize != fmt.frameSize)
 304:       return false;
 305:     if (sampleRate != AudioSystem.NOT_SPECIFIED
 306:         && fmt.sampleRate != AudioSystem.NOT_SPECIFIED
 307:         && sampleRate != fmt.sampleRate)
 308:       return false;
 309:     if (frameRate != AudioSystem.NOT_SPECIFIED
 310:         && fmt.frameRate != AudioSystem.NOT_SPECIFIED
 311:         && frameRate != fmt.frameRate)
 312:       return false;
 313:     if (sampleSizeInBits > 8)
 314:       return bigEndian == fmt.bigEndian;
 315:     return true;
 316:   }
 317: 
 318:   /**
 319:    * Return a read-only Map holding the properties associated with 
 320:    * this format.
 321:    */
 322:   public Map<String, Object> properties()
 323:   {
 324:     return properties;
 325:   }
 326: 
 327:   /**
 328:    * Return a description of this format.
 329:    */
 330:   public String toString()
 331:   {
 332:     StringBuffer result = new StringBuffer();
 333:     result.append(encoding);
 334:     result.append(" ");
 335:     result.append(sampleRate);
 336:     result.append(" Hz ");
 337:     result.append(sampleSizeInBits);
 338:     result.append(" bits ");
 339:     result.append(channels);
 340:     result.append(" channels");
 341:     if (sampleSizeInBits > 8)
 342:       result.append(bigEndian ? " big endian" : " little endian");
 343:     return result.toString();
 344:   }
 345: }