package uk.co.mmscomputing.device.capi.sound; import java.io.*; import uk.co.mmscomputing.device.capi.*; public class PCMInputStream extends FilterInputStream{ /* Convert ISDN 'raw' byte stream into mono PCM byte stream PCM 8000.0 Hz, 16 bit, mono, SIGNED, little-endian static AudioFormat pcmformat = new AudioFormat(8000,16,1,true,false); */ static private int[] alawtable={ 0x80ea,0x8015,0xa8fe,0x5801,0x00aa,0x0056,0xa0fa,0x6005, 0x40f5,0xc00a,0xa8ff,0x5800,0x00d5,0x002b,0x50fd,0xb002, 0x80e2,0x801d,0x28fe,0xd801,0x008a,0x0076,0xa0f8,0x6007, 0x40f1,0xc00e,0x28ff,0xd800,0x00c5,0x003b,0x50fc,0xb003, 0x80ee,0x8011,0xe8fe,0x1801,0x00ba,0x0046,0xa0fb,0x6004, 0x40f7,0xc008,0xe8ff,0x1800,0x00dd,0x0023,0xd0fd,0x3002, 0x80e6,0x8019,0x68fe,0x9801,0x009a,0x0066,0xa0f9,0x6006, 0x40f3,0xc00c,0x68ff,0x9800,0x00cd,0x0033,0xd0fc,0x3003, 0x80e8,0x8017,0x88fe,0x7801,0x00a2,0x005e,0x20fa,0xe005, 0x40f4,0xc00b,0x88ff,0x7800,0x00d1,0x002f,0x10fd,0xf002, 0x80e0,0x801f,0x08fe,0xf801,0x0082,0x007e,0x20f8,0xe007, 0x40f0,0xc00f,0x08ff,0xf800,0x00c1,0x003f,0x10fc,0xf003, 0x80ec,0x8013,0xc8fe,0x3801,0x00b2,0x004e,0x20fb,0xe004, 0x40f6,0xc009,0xc8ff,0x3800,0x00d9,0x0027,0x90fd,0x7002, 0x80e4,0x801b,0x48fe,0xb801,0x0092,0x006e,0x20f9,0xe006, 0x40f2,0xc00d,0x48ff,0xb800,0x00c9,0x0037,0x90fc,0x7003, 0x80eb,0x8014,0xb8fe,0x4801,0x00ae,0x0052,0xe0fa,0x2005, 0xc0f5,0x400a,0xb8ff,0x4800,0x00d7,0x0029,0x70fd,0x9002, 0x80e3,0x801c,0x38fe,0xc801,0x008e,0x0072,0xe0f8,0x2007, 0xc0f1,0x400e,0x38ff,0xc800,0x00c7,0x0039,0x70fc,0x9003, 0x80ef,0x8010,0xf8fe,0x0801,0x00be,0x0042,0xe0fb,0x2004, 0xc0f7,0x4008,0xf8ff,0x0800,0x00df,0x0021,0xf0fd,0x1002, 0x80e7,0x8018,0x78fe,0x8801,0x009e,0x0062,0xe0f9,0x2006, 0xc0f3,0x400c,0x78ff,0x8800,0x00cf,0x0031,0xf0fc,0x1003, 0x80e9,0x8016,0x98fe,0x6801,0x00a6,0x005a,0x60fa,0xa005, 0xc0f4,0x400b,0x98ff,0x6800,0x00d3,0x002d,0x30fd,0xd002, 0x80e1,0x801e,0x18fe,0xe801,0x0086,0x007a,0x60f8,0xa007, 0xc0f0,0x400f,0x18ff,0xe800,0x00c3,0x003d,0x30fc,0xd003, 0x80ed,0x8012,0xd8fe,0x2801,0x00b6,0x004a,0x60fb,0xa004, 0xc0f6,0x4009,0xd8ff,0x2800,0x00db,0x0025,0xb0fd,0x5002, 0x80e5,0x801a,0x58fe,0xa801,0x0096,0x006a,0x60f9,0xa006, 0xc0f2,0x400d,0x58ff,0xa800,0x00cb,0x0035,0xb0fc,0x5003 }; static private int[] ulawtable={ 0x8482,0x7c7d,0xa4f8,0x5c07,0x04e1,0xfc1e,0x8cfe,0x7401, 0x84c1,0x7c3e,0x94fc,0x6c03,0xc4f0,0x3c0f,0x88ff,0x7800, 0x84a2,0x7c5d,0xa4fa,0x5c05,0x04e9,0xfc16,0x0cff,0xf400, 0x84d1,0x7c2e,0x94fd,0x6c02,0xc4f4,0x3c0b,0xc8ff,0x3800, 0x8492,0x7c6d,0xa4f9,0x5c06,0x04e5,0xfc1a,0xccfe,0x3401, 0x84c9,0x7c36,0x14fd,0xec02,0xc4f2,0x3c0d,0xa8ff,0x5800, 0x84b2,0x7c4d,0xa4fb,0x5c04,0x04ed,0xfc12,0x4cff,0xb400, 0x84d9,0x7c26,0x14fe,0xec01,0xc4f6,0x3c09,0xe8ff,0x1800, 0x848a,0x7c75,0x24f9,0xdc06,0x04e3,0xfc1c,0xacfe,0x5401, 0x84c5,0x7c3a,0xd4fc,0x2c03,0xc4f1,0x3c0e,0x98ff,0x6800, 0x84aa,0x7c55,0x24fb,0xdc04,0x04eb,0xfc14,0x2cff,0xd400, 0x84d5,0x7c2a,0xd4fd,0x2c02,0xc4f5,0x3c0a,0xd8ff,0x2800, 0x849a,0x7c65,0x24fa,0xdc05,0x04e7,0xfc18,0xecfe,0x1401, 0x84cd,0x7c32,0x54fd,0xac02,0xc4f3,0x3c0c,0xb8ff,0x4800, 0x84ba,0x7c45,0x24fc,0xdc03,0x04ef,0xfc10,0x6cff,0x9400, 0x84dd,0x7c22,0x54fe,0xac01,0xc4f7,0x3c08,0xf8ff,0x0800, 0x8486,0x7c79,0xe4f8,0x1c07,0x04e2,0xfc1d,0x9cfe,0x6401, 0x84c3,0x7c3c,0xb4fc,0x4c03,0x44f1,0xbc0e,0x90ff,0x7000, 0x84a6,0x7c59,0xe4fa,0x1c05,0x04ea,0xfc15,0x1cff,0xe400, 0x84d3,0x7c2c,0xb4fd,0x4c02,0x44f5,0xbc0a,0xd0ff,0x3000, 0x8496,0x7c69,0xe4f9,0x1c06,0x04e6,0xfc19,0xdcfe,0x2401, 0x84cb,0x7c34,0x34fd,0xcc02,0x44f3,0xbc0c,0xb0ff,0x5000, 0x84b6,0x7c49,0xe4fb,0x1c04,0x04ee,0xfc11,0x5cff,0xa400, 0x84db,0x7c24,0x34fe,0xcc01,0x44f7,0xbc08,0xf0ff,0x1000, 0x848e,0x7c71,0x64f9,0x9c06,0x04e4,0xfc1b,0xbcfe,0x4401, 0x84c7,0x7c38,0xf4fc,0x0c03,0x44f2,0xbc0d,0xa0ff,0x6000, 0x84ae,0x7c51,0x64fb,0x9c04,0x04ec,0xfc13,0x3cff,0xc400, 0x84d7,0x7c28,0xf4fd,0x0c02,0x44f6,0xbc09,0xe0ff,0x2000, 0x849e,0x7c61,0x64fa,0x9c05,0x04e8,0xfc17,0xfcfe,0x0401, 0x84cf,0x7c30,0x74fd,0x8c02,0x44f4,0xbc0b,0xc0ff,0x4000, 0x84be,0x7c41,0x64fc,0x9c03,0x04f0,0xfc0f,0x7cff,0x8400, 0x84df,0x7c20,0x74fe,0x8c01,0x44f8,0xbc07,0x0000,0x0000 }; private int[] table=null; public PCMInputStream(InputStream in, boolean useALaw)throws IOException{ super(in); table=(useALaw)?alawtable:ulawtable; } public int read()throws IOException{ throw new IOException(getClass().getName()+".read() :\n\tDo not support simple read()."); } public int read(byte[] b, int off, int len)throws IOException{ byte[] inb; int value; inb=new byte[len>>1]; // get A-Law or u-Law bytes len=in.read(inb); if(len==-1){return -1;}; for(int i=0;i<len;i++){ value = table[inb[i]&0x00FF]; b[off++]=(byte)((value>>8)&0x00FF); // little-endian b[off++]=(byte)(value&0x00FF); } return len<<1; } /* public int read(byte[] b, int off, int len)throws IOException{ int sample, value; int i = off; int max = off+len-1; // why -1 : because we need space for two bytes while(i<max){ sample = in.read(); if(sample==-1){ if(i==off){return -1;} // end of stream break; } value = table[sample]; b[i++]=(byte)((value>>8)&0x00FF); // little-endian b[i++]=(byte)(value&0x00FF); } return i-off; } */ public synchronized int available()throws IOException{ return super.available()<<1; // two PCM bytes for one A-Law u-Law byte } }