📄 encoder.java
字号:
/* * Encoder is the base class for all GSM encoding. * Copyright (C) 1999 Christopher Edwards * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */package org.tritonus.lowlevel.gsm;import java.io.*;import java.lang.*;public class Encoder extends Thread{ /* Every Encoder has a state through completion */ private Gsm_State g_s = new Gsm_State(); private Long_term lg_term_Obj = new Long_term(); private Lpc lpc_Obj = new Lpc(); private Rpe rpe_Obj = new Rpe(); private Short_term sh_term_Obj = new Short_term(); /* [0..7] LAR coefficients OUT */ private short LARc[] = new short[8]; /* [0..3] LTP lag OUT */ private short Nc[] = new short[4]; /* [0..3] coded LTP gain OUT */ private short Mc[] = new short[4]; /* [0..3] RPE grid selection OUT */ private short bc[] = new short[4]; /* [0..3] Coded maximum amplitude OUT */ private short xmaxc[] = new short[4]; /* [13*4] normalized RPE samples OUT */ private short xmc[] = new short[13*4]; /* Reads 160 bytes */ private int[] input_signal = new int[160]; /* [0..159] OUT */ /* Writes 33 bytes */ private byte[] frame = new byte[Gsm_Def.FRAME_SIZE]; /** * Encoder class constructor. */ public Encoder() { } /** * Remove the header info from the stream and verifies the file type. * As defined by the NeXT/Sun audio file format U-law (.au). * For more info see the README file. <br><br> * Note: Most of this info is not needed to reproduce the sound file * after encoding. All that is needed is the magic number and the sampling rate * to reproduce the sound file during decoding. * * @param in Strip the header from a Sun/Next formated sound stream. */ public static void stripAUHeader(InputStream in) throws Exception { DataInputStream input = new DataInputStream( (InputStream) in ); /* Just read these bits from the stream and do nothing with them */ int magic = input.readInt(); /* magic number SND_MAGIC ((int)0x2e736e64), * which equals ".snd".) */ input.readInt(); /* offset or pointer to the data */ input.readInt(); /* number of bytes of data */ int dataFormat = input.readInt(); /* the data format code */ int sampleRate = input.readInt(); /* the sampling rate = ~8000 samples/sec. */ input.readInt(); /* the number of channels */ input.readChar(); /* optional text information - 4 chars */ input.readChar(); input.readChar(); input.readChar(); if( magic != 0x2E736E64) // ".snd" in ASCII { // throw new GsmException("AuFile wrong Magic Number"); } else if( dataFormat != 1 ) // 8-Bit mu-Law { // throw new GsmException("AuFile not 8-bit Mu-Law"); } else if( sampleRate != 8000) // 8kHz { // throw new GsmException("AuFile not 8kHz"); } } /** * Encode the specified file. * <br>This method calls the <code>stripAUHeader</code> method for you.<br> * stripAUHeader will verify file type. * * @param input_file The name of the file to encode. * @param output_file The name of the GSM encoded file. */ public void encode(String input_file, String output_file) throws Exception { File arg1 = new File(input_file); if(!arg1.exists() || !arg1.isFile() || !arg1.canRead()) { throw new IOException("File : " + input_file + "\ndoes not exist or cannot be read."); } FileInputStream from = null; FileOutputStream to = null; try { from = new FileInputStream(input_file); to = new FileOutputStream(output_file); // Remove the header. It gets mangled by the encoding. stripAUHeader(from); int check_stream = 0; // Read bytes till EOF. while((check_stream = ulaw_input(from)) > 0) { //System.out.println("Entering Native method."); gsm_encode(); // Need to do some error check here. Update ulaw_output. ulaw_output(to); // Write bytes. } } catch (Exception e) { throw new Exception("Encoder: " + e.getMessage()); } finally { if (from != null) { try { from.close(); } catch (IOException e) { throw new IOException("Encoder: " + e.getMessage()); } } if (to != null) { try { to.close(); } catch (IOException e) { throw new IOException("Encoder: " + e.getMessage()); } } } } /** * Encode the specified InputStream. * * @param input The stream to encode. * @param output_file The name of the GSM encoded file. */ public void encode(InputStream input, String output_file) throws IOException { FileOutputStream to = null; try { to = new FileOutputStream(output_file); int check_stream = 0; // Read bytes till EOF. while((check_stream = ulaw_input(input)) > 0) { gsm_encode(); // Need to do some error check here. Update ulaw_output. ulaw_output(to); // Write bytes. } } catch (IOException e) { throw new IOException( "Encoder: " + e.getMessage()); } finally { if (to != null) { try { to.close(); } catch (IOException e) { throw new IOException("Encoder: " + e.getMessage()); } } } } /** Encodes a block of data. * * @param asBuffer an 160-element array with the data to encode * int PCM 16 bit format. * * @param abFrame the encoded GSM frame (33 bytes). */ public void encode(short[] asBuffer, byte[] abFrame) { for (int i = 0; i < 160; i++) { input_signal[i] = asBuffer[i]; } gsm_encode(); System.arraycopy(frame, 0, abFrame, 0, frame.length); } /** * Read 160 bytes from a U-law stream and set up the input_signal array. */ private int ulaw_input(InputStream in) throws IOException { int c = 0; int i = 0; for (i = 0; i < input_signal.length && ((c = in.read()) != -1); i++) { if (c < 0) { throw new IOException("Encoder ulaw_input: Corrupt InputStream."); } else { input_signal[i] = u2s[c]; } } return (i); } private void gsm_encode() { int index = 0; Gsm_Coder_java(); frame[index++] = (byte) (((0xD) << 4) /* 1 */ | ((LARc[0] >> 2) & 0xF)); frame[index++] = (byte) (((LARc[0] & 0x3) << 6) /* 2 */ | (LARc[1] & 0x3F)); frame[index++] = (byte) (((LARc[2] & 0x1F) << 3) /* 3 */ | ((LARc[3] >> 2) & 0x7)); frame[index++] = (byte) (((LARc[3] & 0x3) << 6) /* 4 */ | ((LARc[4] & 0xF) << 2) | ((LARc[5] >> 2) & 0x3)); frame[index++] = (byte) (((LARc[5] & 0x3) << 6) /* 5 */ | ((LARc[6] & 0x7) << 3) | (LARc[7] & 0x7)); frame[index++] = (byte) (((Nc[0] & 0x7F) << 1) /* 6 */ | ((bc[0] >> 1) & 0x1)); frame[index++] = (byte) (((bc[0] & 0x1) << 7) /* 7 */ | ((Mc[0] & 0x3) << 5) | ((xmaxc[0] >> 1) & 0x1F)); frame[index++] = (byte) (((xmaxc[0] & 0x1) << 7) /* 8 */ | ((xmc[0] & 0x7) << 4) | ((xmc[1] & 0x7) << 1) | ((xmc[2] >> 2) & 0x1)); frame[index++] = (byte) (((xmc[2] & 0x3) << 6) /* 9 */ | ((xmc[3] & 0x7) << 3) | (xmc[4] & 0x7)); frame[index++] = (byte) (((xmc[5] & 0x7) << 5) /* 10 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -