1 /*
   2  * Copyright (c) 1999, 2016, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.media.sound;
  27 
  28 import javax.sound.sampled.AudioFileFormat;
  29 import javax.sound.sampled.AudioFormat;
  30 
  31 /**
  32  * WAVE file format class.
  33  *
  34  * @author Jan Borgersen
  35  */
  36 final class WaveFileFormat extends StandardFileFormat {
  37 
  38     /**
  39      * Wave format type.
  40      */
  41     private final int waveType;
  42 
  43     //$$fb 2001-07-13: added management of header size in this class
  44     //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant
  45     private static final int STANDARD_HEADER_SIZE = 28;
  46 
  47     //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant
  48     /**
  49      * fmt_ chunk size in bytes
  50      */
  51     private static final int STANDARD_FMT_CHUNK_SIZE = 16;
  52 
  53     // magic numbers
  54     static final int RIFF_MAGIC = 1380533830;
  55     static final int WAVE_MAGIC = 1463899717;
  56     static final int FMT_MAGIC  = 0x666d7420; // "fmt "
  57     static final int DATA_MAGIC = 0x64617461; // "data"
  58 
  59     // encodings
  60     static final int WAVE_FORMAT_UNKNOWN   = 0x0000;
  61     static final int WAVE_FORMAT_PCM       = 0x0001;
  62     static final int WAVE_FORMAT_ADPCM     = 0x0002;
  63     static final int WAVE_FORMAT_IEEE_FLOAT= 0x0003;
  64     static final int WAVE_FORMAT_ALAW      = 0x0006;
  65     static final int WAVE_FORMAT_MULAW     = 0x0007;
  66     static final int WAVE_FORMAT_OKI_ADPCM = 0x0010;
  67     static final int WAVE_FORMAT_DIGISTD   = 0x0015;
  68     static final int WAVE_FORMAT_DIGIFIX   = 0x0016;
  69     static final int WAVE_IBM_FORMAT_MULAW = 0x0101;
  70     static final int WAVE_IBM_FORMAT_ALAW  = 0x0102;
  71     static final int WAVE_IBM_FORMAT_ADPCM = 0x0103;
  72     static final int WAVE_FORMAT_DVI_ADPCM = 0x0011;
  73     static final int WAVE_FORMAT_SX7383    = 0x1C07;
  74     static final int WAVE_FORMAT_EXTENSIBLE= 0xFFFE;
  75 
  76     WaveFileFormat(final AudioFileFormat.Type type, final long byteLength,
  77                    final AudioFormat format, final long frameLength) {
  78         super(type, byteLength, format, frameLength);
  79 
  80         AudioFormat.Encoding encoding = format.getEncoding();
  81 
  82         if( encoding.equals(AudioFormat.Encoding.ALAW) ) {
  83             waveType = WAVE_FORMAT_ALAW;
  84         } else if( encoding.equals(AudioFormat.Encoding.ULAW) ) {
  85             waveType = WAVE_FORMAT_MULAW;
  86         } else if( encoding.equals(AudioFormat.Encoding.PCM_SIGNED) ||
  87                    encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED) ) {
  88             waveType = WAVE_FORMAT_PCM;
  89         } else {
  90             waveType = WAVE_FORMAT_UNKNOWN;
  91         }
  92     }
  93 
  94     int getWaveType() {
  95         return waveType;
  96     }
  97 
  98     int getHeaderSize() {
  99         return getHeaderSize(getWaveType());
 100     }
 101 
 102     static int getHeaderSize(int waveType) {
 103         //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant
 104         // use dynamic format chunk size
 105         return STANDARD_HEADER_SIZE + getFmtChunkSize(waveType);
 106     }
 107 
 108     static int getFmtChunkSize(int waveType) {
 109         //$$fb 2002-04-16: Fix for 4636355: RIFF audio headers could be _more_ spec compliant
 110         // add 2 bytes for "codec specific data length" for non-PCM codecs
 111         int result = STANDARD_FMT_CHUNK_SIZE;
 112         if (waveType != WAVE_FORMAT_PCM) {
 113             result += 2; // WORD for "codec specific data length"
 114         }
 115         return result;
 116     }
 117 }