Source for gnu.javax.sound.sampled.AU.AUReader

   1: /* AUReader.java -- Read AU files.
   2:    Copyright (C) 2006 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: package gnu.javax.sound.sampled.AU;
  39: 
  40: import javax.sound.sampled.AudioFormat;
  41: import javax.sound.sampled.AudioSystem;
  42: import javax.sound.sampled.AudioFileFormat;
  43: import javax.sound.sampled.AudioInputStream;
  44: import javax.sound.sampled.UnsupportedAudioFileException;
  45: import javax.sound.sampled.spi.AudioFileReader;
  46: import java.io.File;
  47: import java.io.IOException;
  48: import java.io.BufferedInputStream;
  49: import java.io.InputStream;
  50: import java.io.FileInputStream;
  51: import java.net.URL;
  52: import java.nio.ByteBuffer;
  53: 
  54: public class AUReader extends AudioFileReader
  55: {
  56:   private static class AUHeader
  57:   {
  58:     // Magic number identifying the file. '.snd'
  59:     private static final int MAGIC = 0x2e736e64;
  60: 
  61:     public static final int SIZE = 24; // size of the header
  62: 
  63:     // Encoding types
  64:     public static final int ULAW = 1; // 8-bit u-law
  65:     public static final int PCM8 = 2; // 8-bit PCM
  66:     public static final int PCM16 = 3; // 16-bit PCM
  67:     public static final int PCM24 = 4; // 24-bit PCM
  68:     public static final int PCM32 = 5; // 32-bit PCM
  69:     public static final int IEEE32 = 6; // 32-bit IEEE f.p.
  70:     public static final int IEEE64 = 7; // 64-bit IEEE f.p.
  71:     public static final int G721 = 23;
  72:     public static final int G722 = 24;
  73:     public static final int G723 = 25;
  74:     public static final int G723_5BIT = 26;
  75:     public static final int ALAW = 27; // 8-bit a-law
  76: 
  77:     // Header data.
  78:     public int headerSize;
  79:     public int fileSize; // this value may not be set.
  80:     public int encoding;
  81:     public int sampleRate;
  82:     public int channels;
  83:     public int sampleSizeInBits;
  84: 
  85:     public AUHeader(InputStream stream)
  86:       throws IOException, UnsupportedAudioFileException
  87:     {
  88:       byte[] hdr = new byte[24];
  89:       stream.read( hdr );
  90:       ByteBuffer buf = ByteBuffer.wrap(hdr);
  91: 
  92:       if( buf.getInt() != MAGIC )
  93:         throw new UnsupportedAudioFileException("Not an AU format audio file.");
  94:       headerSize = buf.getInt();
  95:       fileSize = buf.getInt();
  96:       encoding = buf.getInt();
  97:       sampleRate = buf.getInt();
  98:       channels = buf.getInt();
  99: 
 100:       switch(encoding)
 101:         {
 102:         case ULAW:
 103:         case PCM8:
 104:         case ALAW:
 105:           sampleSizeInBits = 8;
 106:           break;
 107:         case PCM16:
 108:           sampleSizeInBits = 16;
 109:           break;
 110:         case PCM24:
 111:           sampleSizeInBits = 24;
 112:           break;
 113:         case PCM32:
 114:           sampleSizeInBits = 32;
 115:           break;
 116:         default:   // other types exist but are not supported. Yet.
 117:           throw new UnsupportedAudioFileException("Unsupported encoding.");
 118:         }
 119:     }
 120: 
 121:   public AudioFormat getAudioFormat()
 122:     {
 123:       AudioFormat.Encoding encType = AudioFormat.Encoding.PCM_SIGNED;
 124:       if(encoding == 1)
 125:         encType = AudioFormat.Encoding.ULAW;
 126:       if(encoding == 27)
 127:         encType = AudioFormat.Encoding.ALAW;
 128: 
 129:       return new AudioFormat(encType,
 130:                              (float)sampleRate,
 131:                              sampleSizeInBits,
 132:                              channels,
 133:                              (sampleSizeInBits >> 3) * channels,
 134:                              (float)sampleRate,
 135:                              true);
 136:     }
 137: 
 138:   public AudioFileFormat getAudioFileFormat()
 139:     {
 140:       return new AudioFileFormat(new AUFormatType(),
 141:                                  getAudioFormat(),
 142:                                  AudioSystem.NOT_SPECIFIED);
 143:     }
 144:   }
 145: 
 146:   public static class AUFormatType extends AudioFileFormat.Type
 147:   {
 148:     public AUFormatType()
 149:     {
 150:       super("AU", ".au");
 151:     }
 152:   }
 153: 
 154:   public AudioFileFormat getAudioFileFormat(File file)
 155:     throws IOException, UnsupportedAudioFileException
 156:   {
 157:     return getAudioFileFormat(new FileInputStream(file));
 158:   }
 159: 
 160:   public AudioFileFormat getAudioFileFormat(InputStream stream)
 161:     throws IOException, UnsupportedAudioFileException
 162:   {
 163:     if(!stream.markSupported())
 164:       throw new IOException("Stream must support marking.");
 165: 
 166:     stream.mark(25);
 167:     AUHeader header = new AUHeader(stream);
 168:     stream.reset();
 169: 
 170:     return header.getAudioFileFormat();
 171:   }
 172: 
 173:   public AudioFileFormat getAudioFileFormat(URL url)
 174:     throws IOException, UnsupportedAudioFileException
 175:   {
 176:     return getAudioFileFormat(new BufferedInputStream(url.openStream()));
 177:   }
 178: 
 179:   public AudioInputStream getAudioInputStream(File file)
 180:     throws IOException, UnsupportedAudioFileException
 181:   {
 182:     InputStream stream = new FileInputStream(file);
 183:     long length = file.length();
 184: 
 185:     AUHeader header = new AUHeader( stream );
 186:     if( header.headerSize > AUHeader.SIZE )
 187:       stream.skip(header.headerSize - AUHeader.SIZE);
 188: 
 189:     length -= header.headerSize;
 190: 
 191:     return new AudioInputStream(stream, header.getAudioFormat(), length);
 192:   }
 193: 
 194:   public AudioInputStream getAudioInputStream(InputStream stream)
 195:     throws IOException, UnsupportedAudioFileException
 196:   {
 197:     AUHeader header = new AUHeader( stream );
 198:     if( header.headerSize > AUHeader.SIZE )
 199:       stream.skip(header.headerSize - AUHeader.SIZE);
 200: 
 201:     return new AudioInputStream(stream, header.getAudioFormat(),
 202:                                 AudioSystem.NOT_SPECIFIED);
 203:   }
 204: 
 205:   public AudioInputStream getAudioInputStream(URL url)
 206:     throws IOException, UnsupportedAudioFileException
 207:   {
 208:     return getAudioInputStream(new BufferedInputStream(url.openStream()));
 209:   }
 210: }