package uk.co.mmscomputing.sound;

import java.io.*;

public class ConvertInputStream extends FilterInputStream{

  /*
    Convert A-Law or u-Law byte stream into u-Law or A-Law byte stream

    static AudioFormat alawformat= new AudioFormat(AudioFormat.Encoding.ALAW,8000,8,1,1,8000,false);
    static AudioFormat ulawformat= new AudioFormat(AudioFormat.Encoding.ULAW,8000,8,1,1,8000,false);

  */

  static private byte[]   alaw2ulawtable={
       41,   42,   39,   40,   45,   46,   43,   44,
       33,   34,   31,   32,   37,   38,   35,   36,
       57,   58,   55,   56,   61,   62,   59,   60,
       49,   50,   47,   48,   53,   54,   51,   52,
       10,   11,    8,    9,   14,   15,   12,   13,
        2,    3,    0,    1,    6,    7,    4,    5,
       26,   27,   24,   25,   30,   31,   28,   29,
       18,   19,   16,   17,   22,   23,   20,   21,
       98,   99,   96,   97,  102,  103,  100,  101,
       93,   93,   92,   92,   95,   95,   94,   94,
      116,  118,  112,  114,  124,  126,  120,  122,
      106,  107,  104,  105,  110,  111,  108,  109,
       72,   73,   70,   71,   76,   77,   74,   75,
       64,   65,   63,   63,   68,   69,   66,   67,
       86,   87,   84,   85,   90,   91,   88,   89,
       79,   79,   78,   78,   82,   83,   80,   81,
      -87,  -86,  -89,  -88,  -83,  -82,  -85,  -84,
      -95,  -94,  -97,  -96,  -91,  -90,  -93,  -92,
      -71,  -70,  -73,  -72,  -67,  -66,  -69,  -68,
      -79,  -78,  -81,  -80,  -75,  -74,  -77,  -76,
     -118, -117, -120, -119, -114, -113, -116, -115,
     -126, -125, -128, -127, -122, -121, -124, -123,
     -102, -101, -104, -103,  -98,  -97, -100,  -99,
     -110, -109, -112, -111, -106, -105, -108, -107,
      -30,  -29,  -32,  -31,  -26,  -25,  -28,  -27,
      -35,  -35,  -36,  -36,  -33,  -33,  -34,  -34,
      -12,  -10,  -16,  -14,   -4,   -2,   -8,   -6,
      -22,  -21,  -24,  -23,  -18,  -17,  -20,  -19,
      -56,  -55,  -58,  -57,  -52,  -51,  -54,  -53,
      -64,  -63,  -65,  -65,  -60,  -59,  -62,  -61,
      -42,  -41,  -44,  -43,  -38,  -37,  -40,  -39,
      -49,  -49,  -50,  -50,  -46,  -45,  -48,  -47,
  };

  static private byte[]   ulaw2alawtable={                          
       42,   43,   40,   41,   46,   47,   44,   45,
       34,   35,   32,   33,   38,   39,   36,   37,
       58,   59,   56,   57,   62,   63,   60,   61,
       50,   51,   48,   49,   54,   55,   52,   53,
       11,    8,    9,   14,   15,   12,   13,    2,
        3,    0,    1,    6,    7,    4,    5,   26,
       27,   24,   25,   30,   31,   28,   29,   18,
       19,   16,   17,   22,   23,   20,   21,  107,
      104,  105,  110,  111,  108,  109,   98,   99,
       96,   97,  102,  103,  100,  101,  123,  121,
      126,  127,  124,  125,  114,  115,  112,  113,
      118,  119,  116,  117,   75,   73,   79,   77,
       66,   67,   64,   65,   70,   71,   68,   69,
       90,   91,   88,   89,   94,   95,   92,   93,
       82,   82,   83,   83,   80,   80,   81,   81,
       86,   86,   87,   87,   84,   84,   85,  -43,
      -86,  -85,  -88,  -87,  -82,  -81,  -84,  -83,
      -94,  -93,  -96,  -95,  -90,  -89,  -92,  -91,
      -70,  -69,  -72,  -71,  -66,  -65,  -68,  -67,
      -78,  -77,  -80,  -79,  -74,  -73,  -76,  -75,
     -117, -120, -119, -114, -113, -116, -115, -126,
     -125, -128, -127, -122, -121, -124, -123, -102,
     -101, -104, -103,  -98,  -97, -100,  -99, -110,
     -109, -112, -111, -106, -105, -108, -107,  -21,
      -24,  -23,  -18,  -17,  -20,  -19,  -30,  -29,
      -32,  -31,  -26,  -25,  -28,  -27,   -5,   -7,
       -2,   -1,   -4,   -3,  -14,  -13,  -16,  -15,
      -10,   -9,  -12,  -11,  -53,  -55,  -49,  -51,
      -62,  -61,  -64,  -63,  -58,  -57,  -60,  -59,
      -38,  -37,  -40,  -39,  -34,  -33,  -36,  -35,
      -46,  -46,  -45,  -45,  -48,  -48,  -47,  -47,
      -42,  -42,  -41,  -41,  -44,  -44,  -43,  -43,
  };

  private byte[]   table=null;

  public ConvertInputStream(InputStream in, boolean useALaw2uLaw)throws IOException{
    super(in);
    table=(useALaw2uLaw)?alaw2ulawtable:ulaw2alawtable;
  }

  public int read()throws IOException{
    int b=in.read();
    if(b==-1){return -1;};
    return table[b];
  }

  public int read(byte[] b, int off, int len)throws IOException{
    byte[] inb=new byte[len];
    len=in.read(inb);
    if(len==-1){return -1;};
    for(int i=0;i<len;i++){
      b[off++]=table[inb[i]&0x00FF];
    }
    return len;
  }
}