Package org.rubycoder.gsm

Source Code of org.rubycoder.gsm.GSMDecoderStream

package org.rubycoder.gsm;

// $Id: GSMDecoderStream.java,v 1.1 2008/09/18 10:51:48 kane77 Exp $

import org.rubycoder.gsm.GSMDecoder;
import java.io.InputStream;
import java.io.IOException;

// will extend InputStream eventually
class GSMDecoderStream extends InputStream{

  // make the 8k lookup table
  private static int[] lookup_table;

  private static byte lin2mu(int lin){
          int s,e,f; // sign, exp, mant
          int topp;
    lin>>=2;
          if (lin < 0) {
                  lin = -lin;
                  s=1;
          } else
                  s=0;
          for(int n=0;n<8;n++) {
                  topp=(0x20<<(n+1)) - 0x20 ;
            if (lin < topp ) {
                          e = n;
                          f = ( lin - (0x20<<e) + 0x20 ) >>> (e+1);
                          //System.out.print(" s=" + s + " e=" + e + " f=" + f );
                          return (byte)( ( (s << 7) | (e << 4) | (f & 0x0F) ) ^ 0xFF);
                  }
          }
        return (byte)(s<<8) ;
  }


  private static int[] create_lookup_table() {
    int i;
    int pcm;
    int[] res = new int[8192];

    for(i=0;i<8192;i++) {
      pcm = i-4096;
      // pcm in the range [-4096,4095]
      pcm<<=3;
      // pcm in the range [-32768,32760]
      // (this is high as the gsm signal can go as the
      // last 3 bits set are fixed at zero)
      //res[i] = lin2mu(pcm)+128;
      //res[i] = (int)(lin2mu(pcm))&0xff;
      res[i] = (lin2mu(pcm))&0xff;
//System.out.println("res["+i+":"+pcm+"]=="+res[i]);
    }

    return res;
  }

  // the InputStream methods

  private InputStream GSMStream;


  private int gsm_index = 0;
  private final byte[] gsm_frame;
  private final int[] buffer;
  private int buffer_index = 0;
  private int buffer_size = 0;

  private final GSMDecoder theDecoder;

  public GSMDecoderStream(InputStream is) {
    if (lookup_table==null)
      lookup_table = create_lookup_table();
    gsm_index = 0;
    GSMStream = is;
    buffer = new int[160];
    buffer_index = 0;
    buffer_size = 0;
    gsm_frame = new byte[33];
    theDecoder = new GSMDecoder();
  }

  public int available() throws IOException {
    int avail;

    // how many frames are still available?
    try {
      avail = GSMStream.available()/33;
    } catch (IOException ioe) {
      throw new IOException("Recieved IO Exception from source stream.");
    } catch (NullPointerException npe) {
      throw new IOException("Source stream not open.");
    }
    // each frame is 160 bytes long
    avail *= 160;
    // how much is in the buffer?
    avail += buffer_size-buffer_index;

    return avail;
  }

  public void close() {
    GSMStream = null;
  }

  public synchronized void mark(int size) {
    return;
  }

  public boolean markSupported() {
    return false;
  }

  public final int read() {
    int res;
    //System.out.println("read()");
    int read_count = 0;
    if (buffer_index>=buffer_size) {
      // can't handle any less than 33 bytes
      //System.out.println("reading a frame");
      try {
        read_count = GSMStream.read(gsm_frame);
      } catch (IOException ioe) {
        System.out.println("got io exception");
        close();
        return -1;
      } catch (NullPointerException npe) {
        return -1;
      }
      if (read_count<33) {
        //System.out.println("got less than 33 bytes");
        close();
        return -1;
      }
      //System.out.println("got "+read_count+" bytes from source");
      try {
        theDecoder.decode(gsm_frame,buffer);
      } catch (InvalidGSMFrameException igfe) {
        System.out.println("invalid frame");
        close();
        return -1;
      }
      buffer_index = 0;
      buffer_size = 160;
    }

    res = lookup_table[(buffer[buffer_index++]>>3)+4096];
    return res;
  }
 
  public final int read(byte output[], int start, int length) {
    //System.out.println("read(..,"+start+","+length+");");
    int val,i;
    if (GSMStream==null) return -1;
    for(i=start;i<length;i++) {


      read: {
        //System.out.println("read()");
        int read_count = 0;
        if (buffer_index>=buffer_size) {
          // can't handle any less than 33 bytes
          //System.out.println("reading a frame");
          gsm_index = 0;
          while (gsm_index<33) {
            try
              read_count = GSMStream.read(gsm_frame,gsm_index,33-gsm_index);
            } catch (IOException ioe) {
              System.out.println("got io exception");
              close();
              val = -1;
              break read;
            } catch (NullPointerException npe) {
              val = -1;
              break read;
            }
            //System.out.println("got "+read_count+" bytes from source");
            //if (read_count<33) {
            //  System.out.println("got less than 33 bytes");
            //  close();
            //  val = -1;
            //  break read;
            //}
            if (read_count<0) {
              System.out.println("got eof");
              close();
              val = -1;
              break read;
            }
            gsm_index += read_count;
          }
          try {
            theDecoder.decode(gsm_frame,buffer);
          } catch (InvalidGSMFrameException igfe) {
            System.out.println("invalid frame");
            close();
            val = -1;
            break read;
          }
          buffer_index = 0;
          buffer_size = 160;
        }

        val = lookup_table[(buffer[buffer_index++]>>3)+4096];
      }
      //return res;
      //val = read();


      if (val<0) {
        //System.out.println("got negative on read");
        break;
      }
      output[i]=(byte)(val);
      //System.out.println("output["+i+"]="+output[i]);
    }
    //System.out.println("read "+i+" bytes.");
    return i;
  }

  public final int read(byte output[]) {
    return read(output,0,output.length);
  }

  public void reset() {
    return;
  }

  public void skip(int n) {
    // not implemented yet
    return;
  }

}
TOP

Related Classes of org.rubycoder.gsm.GSMDecoderStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.