Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]
    1   /*
    2    * Copyright (c) 2007, 2010, 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   package com.sun.media.sound;
   26   
   27   import java.nio.ByteBuffer;
   28   import java.nio.ByteOrder;
   29   import java.nio.DoubleBuffer;
   30   import java.nio.FloatBuffer;
   31   
   32   import javax.sound.sampled.AudioFormat;
   33   import javax.sound.sampled.AudioFormat.Encoding;
   34   
   35   /**
   36    * This class is used to convert between 8,16,24,32,32+ bit signed/unsigned
   37    * big/litle endian fixed/floating point byte buffers and float buffers.
   38    *
   39    * @author Karl Helgason
   40    */
   41   public abstract class AudioFloatConverter {
   42   
   43       /***************************************************************************
   44        *
   45        * LSB Filter, used filter least significant byte in samples arrays.
   46        *
   47        * Is used filter out data in lsb byte when SampleSizeInBits is not
   48        * dividable by 8.
   49        *
   50        **************************************************************************/
   51   
   52       private static class AudioFloatLSBFilter extends AudioFloatConverter {
   53   
   54           private AudioFloatConverter converter;
   55   
   56           final private int offset;
   57   
   58           final private int stepsize;
   59   
   60           final private byte mask;
   61   
   62           private byte[] mask_buffer;
   63   
   64           public AudioFloatLSBFilter(AudioFloatConverter converter,
   65                   AudioFormat format) {
   66               int bits = format.getSampleSizeInBits();
   67               boolean bigEndian = format.isBigEndian();
   68               this.converter = converter;
   69               stepsize = (bits + 7) / 8;
   70               offset = bigEndian ? (stepsize - 1) : 0;
   71               int lsb_bits = bits % 8;
   72               if (lsb_bits == 0)
   73                   mask = (byte) 0x00;
   74               else if (lsb_bits == 1)
   75                   mask = (byte) 0x80;
   76               else if (lsb_bits == 2)
   77                   mask = (byte) 0xC0;
   78               else if (lsb_bits == 3)
   79                   mask = (byte) 0xE0;
   80               else if (lsb_bits == 4)
   81                   mask = (byte) 0xF0;
   82               else if (lsb_bits == 5)
   83                   mask = (byte) 0xF8;
   84               else if (lsb_bits == 6)
   85                   mask = (byte) 0xFC;
   86               else if (lsb_bits == 7)
   87                   mask = (byte) 0xFE;
   88               else
   89                   mask = (byte) 0xFF;
   90           }
   91   
   92           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
   93                   byte[] out_buff, int out_offset) {
   94               byte[] ret = converter.toByteArray(in_buff, in_offset, in_len,
   95                       out_buff, out_offset);
   96   
   97               int out_offset_end = in_len * stepsize;
   98               for (int i = out_offset + offset; i < out_offset_end; i += stepsize) {
   99                   out_buff[i] = (byte) (out_buff[i] & mask);
  100               }
  101   
  102               return ret;
  103           }
  104   
  105           public float[] toFloatArray(byte[] in_buff, int in_offset,
  106                   float[] out_buff, int out_offset, int out_len) {
  107               if (mask_buffer == null || mask_buffer.length < in_buff.length)
  108                   mask_buffer = new byte[in_buff.length];
  109               System.arraycopy(in_buff, 0, mask_buffer, 0, in_buff.length);
  110               int in_offset_end = out_len * stepsize;
  111               for (int i = in_offset + offset; i < in_offset_end; i += stepsize) {
  112                   mask_buffer[i] = (byte) (mask_buffer[i] & mask);
  113               }
  114               float[] ret = converter.toFloatArray(mask_buffer, in_offset,
  115                       out_buff, out_offset, out_len);
  116               return ret;
  117           }
  118   
  119       }
  120   
  121       /***************************************************************************
  122        *
  123        * 64 bit float, little/big-endian
  124        *
  125        **************************************************************************/
  126   
  127       // PCM 64 bit float, little-endian
  128       private static class AudioFloatConversion64L extends AudioFloatConverter {
  129           ByteBuffer bytebuffer = null;
  130   
  131           DoubleBuffer floatbuffer = null;
  132   
  133           double[] double_buff = null;
  134   
  135           public float[] toFloatArray(byte[] in_buff, int in_offset,
  136                   float[] out_buff, int out_offset, int out_len) {
  137               int in_len = out_len * 8;
  138               if (bytebuffer == null || bytebuffer.capacity() < in_len) {
  139                   bytebuffer = ByteBuffer.allocate(in_len).order(
  140                           ByteOrder.LITTLE_ENDIAN);
  141                   floatbuffer = bytebuffer.asDoubleBuffer();
  142               }
  143               bytebuffer.position(0);
  144               floatbuffer.position(0);
  145               bytebuffer.put(in_buff, in_offset, in_len);
  146               if (double_buff == null
  147                       || double_buff.length < out_len + out_offset)
  148                   double_buff = new double[out_len + out_offset];
  149               floatbuffer.get(double_buff, out_offset, out_len);
  150               int out_offset_end = out_offset + out_len;
  151               for (int i = out_offset; i < out_offset_end; i++) {
  152                   out_buff[i] = (float) double_buff[i];
  153               }
  154               return out_buff;
  155           }
  156   
  157           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  158                   byte[] out_buff, int out_offset) {
  159               int out_len = in_len * 8;
  160               if (bytebuffer == null || bytebuffer.capacity() < out_len) {
  161                   bytebuffer = ByteBuffer.allocate(out_len).order(
  162                           ByteOrder.LITTLE_ENDIAN);
  163                   floatbuffer = bytebuffer.asDoubleBuffer();
  164               }
  165               floatbuffer.position(0);
  166               bytebuffer.position(0);
  167               if (double_buff == null || double_buff.length < in_offset + in_len)
  168                   double_buff = new double[in_offset + in_len];
  169               int in_offset_end = in_offset + in_len;
  170               for (int i = in_offset; i < in_offset_end; i++) {
  171                   double_buff[i] = in_buff[i];
  172               }
  173               floatbuffer.put(double_buff, in_offset, in_len);
  174               bytebuffer.get(out_buff, out_offset, out_len);
  175               return out_buff;
  176           }
  177       }
  178   
  179       // PCM 64 bit float, big-endian
  180       private static class AudioFloatConversion64B extends AudioFloatConverter {
  181           ByteBuffer bytebuffer = null;
  182   
  183           DoubleBuffer floatbuffer = null;
  184   
  185           double[] double_buff = null;
  186   
  187           public float[] toFloatArray(byte[] in_buff, int in_offset,
  188                   float[] out_buff, int out_offset, int out_len) {
  189               int in_len = out_len * 8;
  190               if (bytebuffer == null || bytebuffer.capacity() < in_len) {
  191                   bytebuffer = ByteBuffer.allocate(in_len).order(
  192                           ByteOrder.BIG_ENDIAN);
  193                   floatbuffer = bytebuffer.asDoubleBuffer();
  194               }
  195               bytebuffer.position(0);
  196               floatbuffer.position(0);
  197               bytebuffer.put(in_buff, in_offset, in_len);
  198               if (double_buff == null
  199                       || double_buff.length < out_len + out_offset)
  200                   double_buff = new double[out_len + out_offset];
  201               floatbuffer.get(double_buff, out_offset, out_len);
  202               int out_offset_end = out_offset + out_len;
  203               for (int i = out_offset; i < out_offset_end; i++) {
  204                   out_buff[i] = (float) double_buff[i];
  205               }
  206               return out_buff;
  207           }
  208   
  209           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  210                   byte[] out_buff, int out_offset) {
  211               int out_len = in_len * 8;
  212               if (bytebuffer == null || bytebuffer.capacity() < out_len) {
  213                   bytebuffer = ByteBuffer.allocate(out_len).order(
  214                           ByteOrder.BIG_ENDIAN);
  215                   floatbuffer = bytebuffer.asDoubleBuffer();
  216               }
  217               floatbuffer.position(0);
  218               bytebuffer.position(0);
  219               if (double_buff == null || double_buff.length < in_offset + in_len)
  220                   double_buff = new double[in_offset + in_len];
  221               int in_offset_end = in_offset + in_len;
  222               for (int i = in_offset; i < in_offset_end; i++) {
  223                   double_buff[i] = in_buff[i];
  224               }
  225               floatbuffer.put(double_buff, in_offset, in_len);
  226               bytebuffer.get(out_buff, out_offset, out_len);
  227               return out_buff;
  228           }
  229       }
  230   
  231       /***************************************************************************
  232        *
  233        * 32 bit float, little/big-endian
  234        *
  235        **************************************************************************/
  236   
  237       // PCM 32 bit float, little-endian
  238       private static class AudioFloatConversion32L extends AudioFloatConverter {
  239           ByteBuffer bytebuffer = null;
  240   
  241           FloatBuffer floatbuffer = null;
  242   
  243           public float[] toFloatArray(byte[] in_buff, int in_offset,
  244                   float[] out_buff, int out_offset, int out_len) {
  245               int in_len = out_len * 4;
  246               if (bytebuffer == null || bytebuffer.capacity() < in_len) {
  247                   bytebuffer = ByteBuffer.allocate(in_len).order(
  248                           ByteOrder.LITTLE_ENDIAN);
  249                   floatbuffer = bytebuffer.asFloatBuffer();
  250               }
  251               bytebuffer.position(0);
  252               floatbuffer.position(0);
  253               bytebuffer.put(in_buff, in_offset, in_len);
  254               floatbuffer.get(out_buff, out_offset, out_len);
  255               return out_buff;
  256           }
  257   
  258           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  259                   byte[] out_buff, int out_offset) {
  260               int out_len = in_len * 4;
  261               if (bytebuffer == null || bytebuffer.capacity() < out_len) {
  262                   bytebuffer = ByteBuffer.allocate(out_len).order(
  263                           ByteOrder.LITTLE_ENDIAN);
  264                   floatbuffer = bytebuffer.asFloatBuffer();
  265               }
  266               floatbuffer.position(0);
  267               bytebuffer.position(0);
  268               floatbuffer.put(in_buff, in_offset, in_len);
  269               bytebuffer.get(out_buff, out_offset, out_len);
  270               return out_buff;
  271           }
  272       }
  273   
  274       // PCM 32 bit float, big-endian
  275       private static class AudioFloatConversion32B extends AudioFloatConverter {
  276           ByteBuffer bytebuffer = null;
  277   
  278           FloatBuffer floatbuffer = null;
  279   
  280           public float[] toFloatArray(byte[] in_buff, int in_offset,
  281                   float[] out_buff, int out_offset, int out_len) {
  282               int in_len = out_len * 4;
  283               if (bytebuffer == null || bytebuffer.capacity() < in_len) {
  284                   bytebuffer = ByteBuffer.allocate(in_len).order(
  285                           ByteOrder.BIG_ENDIAN);
  286                   floatbuffer = bytebuffer.asFloatBuffer();
  287               }
  288               bytebuffer.position(0);
  289               floatbuffer.position(0);
  290               bytebuffer.put(in_buff, in_offset, in_len);
  291               floatbuffer.get(out_buff, out_offset, out_len);
  292               return out_buff;
  293           }
  294   
  295           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  296                   byte[] out_buff, int out_offset) {
  297               int out_len = in_len * 4;
  298               if (bytebuffer == null || bytebuffer.capacity() < out_len) {
  299                   bytebuffer = ByteBuffer.allocate(out_len).order(
  300                           ByteOrder.BIG_ENDIAN);
  301                   floatbuffer = bytebuffer.asFloatBuffer();
  302               }
  303               floatbuffer.position(0);
  304               bytebuffer.position(0);
  305               floatbuffer.put(in_buff, in_offset, in_len);
  306               bytebuffer.get(out_buff, out_offset, out_len);
  307               return out_buff;
  308           }
  309       }
  310   
  311       /***************************************************************************
  312        *
  313        * 8 bit signed/unsigned
  314        *
  315        **************************************************************************/
  316   
  317       // PCM 8 bit, signed
  318       private static class AudioFloatConversion8S extends AudioFloatConverter {
  319           public float[] toFloatArray(byte[] in_buff, int in_offset,
  320                   float[] out_buff, int out_offset, int out_len) {
  321               int ix = in_offset;
  322               int ox = out_offset;
  323               for (int i = 0; i < out_len; i++)
  324                   out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
  325               return out_buff;
  326           }
  327   
  328           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  329                   byte[] out_buff, int out_offset) {
  330               int ix = in_offset;
  331               int ox = out_offset;
  332               for (int i = 0; i < in_len; i++)
  333                   out_buff[ox++] = (byte) (in_buff[ix++] * 127.0f);
  334               return out_buff;
  335           }
  336       }
  337   
  338       // PCM 8 bit, unsigned
  339       private static class AudioFloatConversion8U extends AudioFloatConverter {
  340           public float[] toFloatArray(byte[] in_buff, int in_offset,
  341                   float[] out_buff, int out_offset, int out_len) {
  342               int ix = in_offset;
  343               int ox = out_offset;
  344               for (int i = 0; i < out_len; i++)
  345                   out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127)
  346                           * (1.0f / 127.0f);
  347               return out_buff;
  348           }
  349   
  350           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  351                   byte[] out_buff, int out_offset) {
  352               int ix = in_offset;
  353               int ox = out_offset;
  354               for (int i = 0; i < in_len; i++)
  355                   out_buff[ox++] = (byte) (127 + in_buff[ix++] * 127.0f);
  356               return out_buff;
  357           }
  358       }
  359   
  360       /***************************************************************************
  361        *
  362        * 16 bit signed/unsigned, little/big-endian
  363        *
  364        **************************************************************************/
  365   
  366       // PCM 16 bit, signed, little-endian
  367       private static class AudioFloatConversion16SL extends AudioFloatConverter {
  368           public float[] toFloatArray(byte[] in_buff, int in_offset,
  369                   float[] out_buff, int out_offset, int out_len) {
  370               int ix = in_offset;
  371               int len = out_offset + out_len;
  372               for (int ox = out_offset; ox < len; ox++) {
  373                   out_buff[ox] = ((short) ((in_buff[ix++] & 0xFF) |
  374                              (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
  375               }
  376   
  377               return out_buff;
  378           }
  379   
  380           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  381                   byte[] out_buff, int out_offset) {
  382               int ox = out_offset;
  383               int len = in_offset + in_len;
  384               for (int ix = in_offset; ix < len; ix++) {
  385                   int x = (int) (in_buff[ix] * 32767.0);
  386                   out_buff[ox++] = (byte) x;
  387                   out_buff[ox++] = (byte) (x >>> 8);
  388               }
  389               return out_buff;
  390           }
  391       }
  392   
  393       // PCM 16 bit, signed, big-endian
  394       private static class AudioFloatConversion16SB extends AudioFloatConverter {
  395           public float[] toFloatArray(byte[] in_buff, int in_offset,
  396                   float[] out_buff, int out_offset, int out_len) {
  397               int ix = in_offset;
  398               int ox = out_offset;
  399               for (int i = 0; i < out_len; i++) {
  400                   out_buff[ox++] = ((short) ((in_buff[ix++] << 8) |
  401                           (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
  402               }
  403               return out_buff;
  404           }
  405   
  406           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  407                   byte[] out_buff, int out_offset) {
  408               int ix = in_offset;
  409               int ox = out_offset;
  410               for (int i = 0; i < in_len; i++) {
  411                   int x = (int) (in_buff[ix++] * 32767.0);
  412                   out_buff[ox++] = (byte) (x >>> 8);
  413                   out_buff[ox++] = (byte) x;
  414               }
  415               return out_buff;
  416           }
  417       }
  418   
  419       // PCM 16 bit, unsigned, little-endian
  420       private static class AudioFloatConversion16UL extends AudioFloatConverter {
  421           public float[] toFloatArray(byte[] in_buff, int in_offset,
  422                   float[] out_buff, int out_offset, int out_len) {
  423               int ix = in_offset;
  424               int ox = out_offset;
  425               for (int i = 0; i < out_len; i++) {
  426                   int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
  427                   out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
  428               }
  429               return out_buff;
  430           }
  431   
  432           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  433                   byte[] out_buff, int out_offset) {
  434               int ix = in_offset;
  435               int ox = out_offset;
  436               for (int i = 0; i < in_len; i++) {
  437                   int x = 32767 + (int) (in_buff[ix++] * 32767.0);
  438                   out_buff[ox++] = (byte) x;
  439                   out_buff[ox++] = (byte) (x >>> 8);
  440               }
  441               return out_buff;
  442           }
  443       }
  444   
  445       // PCM 16 bit, unsigned, big-endian
  446       private static class AudioFloatConversion16UB extends AudioFloatConverter {
  447           public float[] toFloatArray(byte[] in_buff, int in_offset,
  448                   float[] out_buff, int out_offset, int out_len) {
  449               int ix = in_offset;
  450               int ox = out_offset;
  451               for (int i = 0; i < out_len; i++) {
  452                   int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
  453                   out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
  454               }
  455               return out_buff;
  456           }
  457   
  458           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  459                   byte[] out_buff, int out_offset) {
  460               int ix = in_offset;
  461               int ox = out_offset;
  462               for (int i = 0; i < in_len; i++) {
  463                   int x = 32767 + (int) (in_buff[ix++] * 32767.0);
  464                   out_buff[ox++] = (byte) (x >>> 8);
  465                   out_buff[ox++] = (byte) x;
  466               }
  467               return out_buff;
  468           }
  469       }
  470   
  471       /***************************************************************************
  472        *
  473        * 24 bit signed/unsigned, little/big-endian
  474        *
  475        **************************************************************************/
  476   
  477       // PCM 24 bit, signed, little-endian
  478       private static class AudioFloatConversion24SL extends AudioFloatConverter {
  479           public float[] toFloatArray(byte[] in_buff, int in_offset,
  480                   float[] out_buff, int out_offset, int out_len) {
  481               int ix = in_offset;
  482               int ox = out_offset;
  483               for (int i = 0; i < out_len; i++) {
  484                   int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
  485                           | ((in_buff[ix++] & 0xFF) << 16);
  486                   if (x > 0x7FFFFF)
  487                       x -= 0x1000000;
  488                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
  489               }
  490               return out_buff;
  491           }
  492   
  493           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  494                   byte[] out_buff, int out_offset) {
  495               int ix = in_offset;
  496               int ox = out_offset;
  497               for (int i = 0; i < in_len; i++) {
  498                   int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
  499                   if (x < 0)
  500                       x += 0x1000000;
  501                   out_buff[ox++] = (byte) x;
  502                   out_buff[ox++] = (byte) (x >>> 8);
  503                   out_buff[ox++] = (byte) (x >>> 16);
  504               }
  505               return out_buff;
  506           }
  507       }
  508   
  509       // PCM 24 bit, signed, big-endian
  510       private static class AudioFloatConversion24SB extends AudioFloatConverter {
  511           public float[] toFloatArray(byte[] in_buff, int in_offset,
  512                   float[] out_buff, int out_offset, int out_len) {
  513               int ix = in_offset;
  514               int ox = out_offset;
  515               for (int i = 0; i < out_len; i++) {
  516                   int x = ((in_buff[ix++] & 0xFF) << 16)
  517                           | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
  518                   if (x > 0x7FFFFF)
  519                       x -= 0x1000000;
  520                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
  521               }
  522               return out_buff;
  523           }
  524   
  525           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  526                   byte[] out_buff, int out_offset) {
  527               int ix = in_offset;
  528               int ox = out_offset;
  529               for (int i = 0; i < in_len; i++) {
  530                   int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
  531                   if (x < 0)
  532                       x += 0x1000000;
  533                   out_buff[ox++] = (byte) (x >>> 16);
  534                   out_buff[ox++] = (byte) (x >>> 8);
  535                   out_buff[ox++] = (byte) x;
  536               }
  537               return out_buff;
  538           }
  539       }
  540   
  541       // PCM 24 bit, unsigned, little-endian
  542       private static class AudioFloatConversion24UL extends AudioFloatConverter {
  543           public float[] toFloatArray(byte[] in_buff, int in_offset,
  544                   float[] out_buff, int out_offset, int out_len) {
  545               int ix = in_offset;
  546               int ox = out_offset;
  547               for (int i = 0; i < out_len; i++) {
  548                   int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
  549                           | ((in_buff[ix++] & 0xFF) << 16);
  550                   x -= 0x7FFFFF;
  551                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
  552               }
  553               return out_buff;
  554           }
  555   
  556           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  557                   byte[] out_buff, int out_offset) {
  558               int ix = in_offset;
  559               int ox = out_offset;
  560               for (int i = 0; i < in_len; i++) {
  561                   int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
  562                   x += 0x7FFFFF;
  563                   out_buff[ox++] = (byte) x;
  564                   out_buff[ox++] = (byte) (x >>> 8);
  565                   out_buff[ox++] = (byte) (x >>> 16);
  566               }
  567               return out_buff;
  568           }
  569       }
  570   
  571       // PCM 24 bit, unsigned, big-endian
  572       private static class AudioFloatConversion24UB extends AudioFloatConverter {
  573           public float[] toFloatArray(byte[] in_buff, int in_offset,
  574                   float[] out_buff, int out_offset, int out_len) {
  575               int ix = in_offset;
  576               int ox = out_offset;
  577               for (int i = 0; i < out_len; i++) {
  578                   int x = ((in_buff[ix++] & 0xFF) << 16)
  579                           | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
  580                   x -= 0x7FFFFF;
  581                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
  582               }
  583               return out_buff;
  584           }
  585   
  586           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  587                   byte[] out_buff, int out_offset) {
  588               int ix = in_offset;
  589               int ox = out_offset;
  590               for (int i = 0; i < in_len; i++) {
  591                   int x = (int) (in_buff[ix++] * (float)0x7FFFFF);
  592                   x += 0x7FFFFF;
  593                   out_buff[ox++] = (byte) (x >>> 16);
  594                   out_buff[ox++] = (byte) (x >>> 8);
  595                   out_buff[ox++] = (byte) x;
  596               }
  597               return out_buff;
  598           }
  599       }
  600   
  601       /***************************************************************************
  602        *
  603        * 32 bit signed/unsigned, little/big-endian
  604        *
  605        **************************************************************************/
  606   
  607       // PCM 32 bit, signed, little-endian
  608       private static class AudioFloatConversion32SL extends AudioFloatConverter {
  609           public float[] toFloatArray(byte[] in_buff, int in_offset,
  610                   float[] out_buff, int out_offset, int out_len) {
  611               int ix = in_offset;
  612               int ox = out_offset;
  613               for (int i = 0; i < out_len; i++) {
  614                   int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
  615                           ((in_buff[ix++] & 0xFF) << 16) |
  616                           ((in_buff[ix++] & 0xFF) << 24);
  617                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
  618               }
  619               return out_buff;
  620           }
  621   
  622           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  623                   byte[] out_buff, int out_offset) {
  624               int ix = in_offset;
  625               int ox = out_offset;
  626               for (int i = 0; i < in_len; i++) {
  627                   int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
  628                   out_buff[ox++] = (byte) x;
  629                   out_buff[ox++] = (byte) (x >>> 8);
  630                   out_buff[ox++] = (byte) (x >>> 16);
  631                   out_buff[ox++] = (byte) (x >>> 24);
  632               }
  633               return out_buff;
  634           }
  635       }
  636   
  637       // PCM 32 bit, signed, big-endian
  638       private static class AudioFloatConversion32SB extends AudioFloatConverter {
  639           public float[] toFloatArray(byte[] in_buff, int in_offset,
  640                   float[] out_buff, int out_offset, int out_len) {
  641               int ix = in_offset;
  642               int ox = out_offset;
  643               for (int i = 0; i < out_len; i++) {
  644                   int x = ((in_buff[ix++] & 0xFF) << 24) |
  645                           ((in_buff[ix++] & 0xFF) << 16) |
  646                           ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
  647                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
  648               }
  649               return out_buff;
  650           }
  651   
  652           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  653                   byte[] out_buff, int out_offset) {
  654               int ix = in_offset;
  655               int ox = out_offset;
  656               for (int i = 0; i < in_len; i++) {
  657                   int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
  658                   out_buff[ox++] = (byte) (x >>> 24);
  659                   out_buff[ox++] = (byte) (x >>> 16);
  660                   out_buff[ox++] = (byte) (x >>> 8);
  661                   out_buff[ox++] = (byte) x;
  662               }
  663               return out_buff;
  664           }
  665       }
  666   
  667       // PCM 32 bit, unsigned, little-endian
  668       private static class AudioFloatConversion32UL extends AudioFloatConverter {
  669           public float[] toFloatArray(byte[] in_buff, int in_offset,
  670                   float[] out_buff, int out_offset, int out_len) {
  671               int ix = in_offset;
  672               int ox = out_offset;
  673               for (int i = 0; i < out_len; i++) {
  674                   int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
  675                           ((in_buff[ix++] & 0xFF) << 16) |
  676                           ((in_buff[ix++] & 0xFF) << 24);
  677                   x -= 0x7FFFFFFF;
  678                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
  679               }
  680               return out_buff;
  681           }
  682   
  683           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  684                   byte[] out_buff, int out_offset) {
  685               int ix = in_offset;
  686               int ox = out_offset;
  687               for (int i = 0; i < in_len; i++) {
  688                   int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
  689                   x += 0x7FFFFFFF;
  690                   out_buff[ox++] = (byte) x;
  691                   out_buff[ox++] = (byte) (x >>> 8);
  692                   out_buff[ox++] = (byte) (x >>> 16);
  693                   out_buff[ox++] = (byte) (x >>> 24);
  694               }
  695               return out_buff;
  696           }
  697       }
  698   
  699       // PCM 32 bit, unsigned, big-endian
  700       private static class AudioFloatConversion32UB extends AudioFloatConverter {
  701   
  702           public float[] toFloatArray(byte[] in_buff, int in_offset,
  703                   float[] out_buff, int out_offset, int out_len) {
  704               int ix = in_offset;
  705               int ox = out_offset;
  706               for (int i = 0; i < out_len; i++) {
  707                   int x = ((in_buff[ix++] & 0xFF) << 24) |
  708                           ((in_buff[ix++] & 0xFF) << 16) |
  709                           ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
  710                   x -= 0x7FFFFFFF;
  711                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
  712               }
  713               return out_buff;
  714           }
  715   
  716           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  717                   byte[] out_buff, int out_offset) {
  718               int ix = in_offset;
  719               int ox = out_offset;
  720               for (int i = 0; i < in_len; i++) {
  721                   int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
  722                   x += 0x7FFFFFFF;
  723                   out_buff[ox++] = (byte) (x >>> 24);
  724                   out_buff[ox++] = (byte) (x >>> 16);
  725                   out_buff[ox++] = (byte) (x >>> 8);
  726                   out_buff[ox++] = (byte) x;
  727               }
  728               return out_buff;
  729           }
  730       }
  731   
  732       /***************************************************************************
  733        *
  734        * 32+ bit signed/unsigned, little/big-endian
  735        *
  736        **************************************************************************/
  737   
  738       // PCM 32+ bit, signed, little-endian
  739       private static class AudioFloatConversion32xSL extends AudioFloatConverter {
  740   
  741           final int xbytes;
  742   
  743           public AudioFloatConversion32xSL(int xbytes) {
  744               this.xbytes = xbytes;
  745           }
  746   
  747           public float[] toFloatArray(byte[] in_buff, int in_offset,
  748                   float[] out_buff, int out_offset, int out_len) {
  749               int ix = in_offset;
  750               int ox = out_offset;
  751               for (int i = 0; i < out_len; i++) {
  752                   ix += xbytes;
  753                   int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
  754                           | ((in_buff[ix++] & 0xFF) << 16)
  755                           | ((in_buff[ix++] & 0xFF) << 24);
  756                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
  757               }
  758               return out_buff;
  759           }
  760   
  761           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  762                   byte[] out_buff, int out_offset) {
  763               int ix = in_offset;
  764               int ox = out_offset;
  765               for (int i = 0; i < in_len; i++) {
  766                   int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
  767                   for (int j = 0; j < xbytes; j++) {
  768                       out_buff[ox++] = 0;
  769                   }
  770                   out_buff[ox++] = (byte) x;
  771                   out_buff[ox++] = (byte) (x >>> 8);
  772                   out_buff[ox++] = (byte) (x >>> 16);
  773                   out_buff[ox++] = (byte) (x >>> 24);
  774               }
  775               return out_buff;
  776           }
  777       }
  778   
  779       // PCM 32+ bit, signed, big-endian
  780       private static class AudioFloatConversion32xSB extends AudioFloatConverter {
  781   
  782           final int xbytes;
  783   
  784           public AudioFloatConversion32xSB(int xbytes) {
  785               this.xbytes = xbytes;
  786           }
  787   
  788           public float[] toFloatArray(byte[] in_buff, int in_offset,
  789                   float[] out_buff, int out_offset, int out_len) {
  790               int ix = in_offset;
  791               int ox = out_offset;
  792               for (int i = 0; i < out_len; i++) {
  793                   int x = ((in_buff[ix++] & 0xFF) << 24)
  794                           | ((in_buff[ix++] & 0xFF) << 16)
  795                           | ((in_buff[ix++] & 0xFF) << 8)
  796                           | (in_buff[ix++] & 0xFF);
  797                   ix += xbytes;
  798                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
  799               }
  800               return out_buff;
  801           }
  802   
  803           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  804                   byte[] out_buff, int out_offset) {
  805               int ix = in_offset;
  806               int ox = out_offset;
  807               for (int i = 0; i < in_len; i++) {
  808                   int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
  809                   out_buff[ox++] = (byte) (x >>> 24);
  810                   out_buff[ox++] = (byte) (x >>> 16);
  811                   out_buff[ox++] = (byte) (x >>> 8);
  812                   out_buff[ox++] = (byte) x;
  813                   for (int j = 0; j < xbytes; j++) {
  814                       out_buff[ox++] = 0;
  815                   }
  816               }
  817               return out_buff;
  818           }
  819       }
  820   
  821       // PCM 32+ bit, unsigned, little-endian
  822       private static class AudioFloatConversion32xUL extends AudioFloatConverter {
  823   
  824           final int xbytes;
  825   
  826           public AudioFloatConversion32xUL(int xbytes) {
  827               this.xbytes = xbytes;
  828           }
  829   
  830           public float[] toFloatArray(byte[] in_buff, int in_offset,
  831                   float[] out_buff, int out_offset, int out_len) {
  832               int ix = in_offset;
  833               int ox = out_offset;
  834               for (int i = 0; i < out_len; i++) {
  835                   ix += xbytes;
  836                   int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
  837                           | ((in_buff[ix++] & 0xFF) << 16)
  838                           | ((in_buff[ix++] & 0xFF) << 24);
  839                   x -= 0x7FFFFFFF;
  840                   out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
  841               }
  842               return out_buff;
  843           }
  844   
  845           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  846                   byte[] out_buff, int out_offset) {
  847               int ix = in_offset;
  848               int ox = out_offset;
  849               for (int i = 0; i < in_len; i++) {
  850                   int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);
  851                   x += 0x7FFFFFFF;
  852                   for (int j = 0; j < xbytes; j++) {
  853                       out_buff[ox++] = 0;
  854                   }
  855                   out_buff[ox++] = (byte) x;
  856                   out_buff[ox++] = (byte) (x >>> 8);
  857                   out_buff[ox++] = (byte) (x >>> 16);
  858                   out_buff[ox++] = (byte) (x >>> 24);
  859               }
  860               return out_buff;
  861           }
  862       }
  863   
  864       // PCM 32+ bit, unsigned, big-endian
  865       private static class AudioFloatConversion32xUB extends AudioFloatConverter {
  866   
  867           final int xbytes;
  868   
  869           public AudioFloatConversion32xUB(int xbytes) {
  870               this.xbytes = xbytes;
  871           }
  872   
  873           public float[] toFloatArray(byte[] in_buff, int in_offset,
  874                   float[] out_buff, int out_offset, int out_len) {
  875               int ix = in_offset;
  876               int ox = out_offset;
  877               for (int i = 0; i < out_len; i++) {
  878                   int x = ((in_buff[ix++] & 0xFF) << 24) |
  879                           ((in_buff[ix++] & 0xFF) << 16) |
  880                           ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
  881                   ix += xbytes;
  882                   x -= 2147483647;
  883                   out_buff[ox++] = x * (1.0f / 2147483647.0f);
  884               }
  885               return out_buff;
  886           }
  887   
  888           public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
  889                   byte[] out_buff, int out_offset) {
  890               int ix = in_offset;
  891               int ox = out_offset;
  892               for (int i = 0; i < in_len; i++) {
  893                   int x = (int) (in_buff[ix++] * 2147483647.0);
  894                   x += 2147483647;
  895                   out_buff[ox++] = (byte) (x >>> 24);
  896                   out_buff[ox++] = (byte) (x >>> 16);
  897                   out_buff[ox++] = (byte) (x >>> 8);
  898                   out_buff[ox++] = (byte) x;
  899                   for (int j = 0; j < xbytes; j++) {
  900                       out_buff[ox++] = 0;
  901                   }
  902               }
  903               return out_buff;
  904           }
  905       }
  906   
  907       public static AudioFloatConverter getConverter(AudioFormat format) {
  908           AudioFloatConverter conv = null;
  909           if (format.getFrameSize() == 0)
  910               return null;
  911           if (format.getFrameSize() !=
  912                   ((format.getSampleSizeInBits() + 7) / 8) * format.getChannels()) {
  913               return null;
  914           }
  915           if (format.getEncoding().equals(Encoding.PCM_SIGNED)) {
  916               if (format.isBigEndian()) {
  917                   if (format.getSampleSizeInBits() <= 8) {
  918                       conv = new AudioFloatConversion8S();
  919                   } else if (format.getSampleSizeInBits() > 8 &&
  920                         format.getSampleSizeInBits() <= 16) {
  921                       conv = new AudioFloatConversion16SB();
  922                   } else if (format.getSampleSizeInBits() > 16 &&
  923                         format.getSampleSizeInBits() <= 24) {
  924                       conv = new AudioFloatConversion24SB();
  925                   } else if (format.getSampleSizeInBits() > 24 &&
  926                         format.getSampleSizeInBits() <= 32) {
  927                       conv = new AudioFloatConversion32SB();
  928                   } else if (format.getSampleSizeInBits() > 32) {
  929                       conv = new AudioFloatConversion32xSB(((format
  930                               .getSampleSizeInBits() + 7) / 8) - 4);
  931                   }
  932               } else {
  933                   if (format.getSampleSizeInBits() <= 8) {
  934                       conv = new AudioFloatConversion8S();
  935                   } else if (format.getSampleSizeInBits() > 8 &&
  936                            format.getSampleSizeInBits() <= 16) {
  937                       conv = new AudioFloatConversion16SL();
  938                   } else if (format.getSampleSizeInBits() > 16 &&
  939                            format.getSampleSizeInBits() <= 24) {
  940                       conv = new AudioFloatConversion24SL();
  941                   } else if (format.getSampleSizeInBits() > 24 &&
  942                            format.getSampleSizeInBits() <= 32) {
  943                       conv = new AudioFloatConversion32SL();
  944                   } else if (format.getSampleSizeInBits() > 32) {
  945                       conv = new AudioFloatConversion32xSL(((format
  946                               .getSampleSizeInBits() + 7) / 8) - 4);
  947                   }
  948               }
  949           } else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
  950               if (format.isBigEndian()) {
  951                   if (format.getSampleSizeInBits() <= 8) {
  952                       conv = new AudioFloatConversion8U();
  953                   } else if (format.getSampleSizeInBits() > 8 &&
  954                           format.getSampleSizeInBits() <= 16) {
  955                       conv = new AudioFloatConversion16UB();
  956                   } else if (format.getSampleSizeInBits() > 16 &&
  957                           format.getSampleSizeInBits() <= 24) {
  958                       conv = new AudioFloatConversion24UB();
  959                   } else if (format.getSampleSizeInBits() > 24 &&
  960                           format.getSampleSizeInBits() <= 32) {
  961                       conv = new AudioFloatConversion32UB();
  962                   } else if (format.getSampleSizeInBits() > 32) {
  963                       conv = new AudioFloatConversion32xUB(((
  964                               format.getSampleSizeInBits() + 7) / 8) - 4);
  965                   }
  966               } else {
  967                   if (format.getSampleSizeInBits() <= 8) {
  968                       conv = new AudioFloatConversion8U();
  969                   } else if (format.getSampleSizeInBits() > 8 &&
  970                           format.getSampleSizeInBits() <= 16) {
  971                       conv = new AudioFloatConversion16UL();
  972                   } else if (format.getSampleSizeInBits() > 16 &&
  973                           format.getSampleSizeInBits() <= 24) {
  974                       conv = new AudioFloatConversion24UL();
  975                   } else if (format.getSampleSizeInBits() > 24 &&
  976                           format.getSampleSizeInBits() <= 32) {
  977                       conv = new AudioFloatConversion32UL();
  978                   } else if (format.getSampleSizeInBits() > 32) {
  979                       conv = new AudioFloatConversion32xUL(((
  980                               format.getSampleSizeInBits() + 7) / 8) - 4);
  981                   }
  982               }
  983           } else if (format.getEncoding().equals(Encoding.PCM_FLOAT)) {
  984               if (format.getSampleSizeInBits() == 32) {
  985                   if (format.isBigEndian())
  986                       conv = new AudioFloatConversion32B();
  987                   else
  988                       conv = new AudioFloatConversion32L();
  989               } else if (format.getSampleSizeInBits() == 64) {
  990                   if (format.isBigEndian())
  991                       conv = new AudioFloatConversion64B();
  992                   else
  993                       conv = new AudioFloatConversion64L();
  994               }
  995   
  996           }
  997   
  998           if ((format.getEncoding().equals(Encoding.PCM_SIGNED) ||
  999                   format.getEncoding().equals(Encoding.PCM_UNSIGNED)) &&
 1000                   (format.getSampleSizeInBits() % 8 != 0)) {
 1001               conv = new AudioFloatLSBFilter(conv, format);
 1002           }
 1003   
 1004           if (conv != null)
 1005               conv.format = format;
 1006           return conv;
 1007       }
 1008   
 1009       private AudioFormat format;
 1010   
 1011       public AudioFormat getFormat() {
 1012           return format;
 1013       }
 1014   
 1015       public abstract float[] toFloatArray(byte[] in_buff, int in_offset,
 1016               float[] out_buff, int out_offset, int out_len);
 1017   
 1018       public float[] toFloatArray(byte[] in_buff, float[] out_buff,
 1019               int out_offset, int out_len) {
 1020           return toFloatArray(in_buff, 0, out_buff, out_offset, out_len);
 1021       }
 1022   
 1023       public float[] toFloatArray(byte[] in_buff, int in_offset,
 1024               float[] out_buff, int out_len) {
 1025           return toFloatArray(in_buff, in_offset, out_buff, 0, out_len);
 1026       }
 1027   
 1028       public float[] toFloatArray(byte[] in_buff, float[] out_buff, int out_len) {
 1029           return toFloatArray(in_buff, 0, out_buff, 0, out_len);
 1030       }
 1031   
 1032       public float[] toFloatArray(byte[] in_buff, float[] out_buff) {
 1033           return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length);
 1034       }
 1035   
 1036       public abstract byte[] toByteArray(float[] in_buff, int in_offset,
 1037               int in_len, byte[] out_buff, int out_offset);
 1038   
 1039       public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff,
 1040               int out_offset) {
 1041           return toByteArray(in_buff, 0, in_len, out_buff, out_offset);
 1042       }
 1043   
 1044       public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
 1045               byte[] out_buff) {
 1046           return toByteArray(in_buff, in_offset, in_len, out_buff, 0);
 1047       }
 1048   
 1049       public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff) {
 1050           return toByteArray(in_buff, 0, in_len, out_buff, 0);
 1051       }
 1052   
 1053       public byte[] toByteArray(float[] in_buff, byte[] out_buff) {
 1054           return toByteArray(in_buff, 0, in_buff.length, out_buff, 0);
 1055       }
 1056   }

Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]