/* * @(#)JavaEncoder_ms.java 1.9 02/08/21 * * Copyright 1996-1998 by Sun Microsystems, Inc., * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. * All rights reserved. * * This software is the confidential and proprietary information * of Sun Microsystems, Inc. ("Confidential Information"). You * shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with Sun. */ package com.ibm.media.codec.audio.ima4; import javax.media.*; import javax.media.format.*; import javax.media.format.*; import com.sun.media.format.*; import com.sun.media.*; public class JavaEncoder_ms extends com.ibm.media.codec.audio.BufferedEncoder { //////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////// // state of the ima4 decoder private IMA4State ima4stateL,ima4stateR; // *** encoding control ? private int inputframeSizeInBytes = 1010; //////////////////////////////////////////////////////////////////////////// // Methods public JavaEncoder_ms() { supportedInputFormats = new AudioFormat[] { new AudioFormat( AudioFormat.LINEAR, AudioFormat.NOT_SPECIFIED, 16, AudioFormat.NOT_SPECIFIED, AudioFormat.LITTLE_ENDIAN, AudioFormat.SIGNED, AudioFormat.NOT_SPECIFIED,//inputframeSizeInBytes*8, AudioFormat.NOT_SPECIFIED, Format.byteArray )}; defaultOutputFormats = new AudioFormat[] { new WavAudioFormat(AudioFormat.IMA4_MS) }; PLUGIN_NAME="IMA4 MS Encoder"; } protected Format[] getMatchingOutputFormats(Format in) { AudioFormat af =(AudioFormat) in; int outFrameSizeInBits = ( (inputframeSizeInBytes-2) *2 + 4*8) * af.getChannels(); int wSamplesPerBlock = inputframeSizeInBytes / 2; supportedOutputFormats = new AudioFormat[] { new WavAudioFormat( AudioFormat.IMA4_MS, af.getSampleRate(), 4, af.getChannels(), outFrameSizeInBits, ((int)af.getSampleRate()) * 2 / 8 * outFrameSizeInBits / inputframeSizeInBytes, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.byteArray, new byte[] { (byte)(wSamplesPerBlock&0xff), (byte)(wSamplesPerBlock>>8) } ) }; historySize = inputframeSizeInBytes*af.getChannels(); return supportedOutputFormats; } /** Initializes the codec. **/ public void open() { ima4stateL=new IMA4State(); ima4stateR=new IMA4State(); } /** Clean up **/ public void close() { ima4stateL = null; ima4stateR = null; } // reset IMA4 encoder state public void codecReset() { ima4stateL.index = 0; ima4stateL.valprev = 0; ima4stateR.index = 0; ima4stateR.valprev = 0; } protected int calculateOutputSize(int inputSize) { //System.out.println("output number "+inputSize+" => "+calculateFramesNumber(inputSize) * 34); return calculateFramesNumber(inputSize) * ((inputframeSizeInBytes-4) * 4 +2) ; } protected int calculateFramesNumber(int inputSize) { //System.out.println("frame number "+inputSize+" => "+inputSize / 128); return inputSize / inputframeSizeInBytes; } protected boolean codecProcess(byte[] inpData,int readPtr, byte[] outData,int writePtr, int inpLength, int[] readBytes,int[] writeBytes, int[] frameNumber, int[] regions,int[] regiostypes) { int inCount = 0; int outCount = 0; int channels=inputFormat.getChannels(); boolean isStereo = ( channels == 2); int stride = isStereo ? 2 : 0; final int frames = inpLength/(channels*1010); int iterations = (inputframeSizeInBytes-2)>>1 ; regions[0]=writePtr; // MSDVI stereo format is a mess ! // header left (same as mono header) // header right (same as mono header) // 4 bytes left (8 samples) // 4 bytes right (8 samples) // 4 bytes left (8 samples) // 4 bytes right (8 samples) // : : : // : : : // 4 bytes left (8 samples) // 4 bytes right (8 samples) // ima4stateL,R are stored between chunks encoding. // System.out.println("iter "+iterations +" frames "+frames); for (int frameCounter = 0; frameCounter<frames ; frameCounter++) { //LEFT or mono int valprev= (inpData[readPtr+(inCount++)] & 0xff); valprev |= (inpData[readPtr+(inCount++)] << 8); ima4stateL.valprev=valprev; // validate index legality if (ima4stateL.index>88) { ima4stateL.index=88; } else if (ima4stateL.index<0) { ima4stateL.index=0; } outData[writePtr+(outCount++)]=(byte)(valprev); outData[writePtr+(outCount++)]=(byte)(valprev>>8); outData[writePtr+(outCount++)]=(byte)(ima4stateL.index); outCount++; if (isStereo) { valprev= (inpData[readPtr+(inCount++)] & 0xff); valprev |= (inpData[readPtr+(inCount++)] << 8); ima4stateR.valprev=valprev; // validate index legality if (ima4stateR.index>88) { ima4stateR.index=88; } else if (ima4stateR.index<0) { ima4stateR.index=0; } outData[writePtr+(outCount++)]=(byte)(valprev); outData[writePtr+(outCount++)]=(byte)(valprev>>8); outData[writePtr+(outCount++)]=(byte)(ima4stateR.index); outCount++; } for (int loop=0 ; loop<iterations/8 ; loop++ ) { IMA4.encode(inpData,inCount+readPtr,outData,outCount+writePtr,8,ima4stateL,stride); outCount += (8 >> 1); if (isStereo) { IMA4.encode(inpData,inCount+readPtr+2,outData,outCount+writePtr,8,ima4stateR,stride); outCount += (8 >> 1); inCount += (8 << 2); } else { inCount += (8 << 1); } } regions [frameCounter+1]= outCount + writePtr; regionsTypes[frameCounter ]= 0; } readBytes [0]=inCount; writeBytes[0]=outCount; frameNumber[0]=frames; return true; } }