/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.restcomm.media.codec.g711.alaw; import org.restcomm.media.spi.dsp.Codec; import org.restcomm.media.spi.format.Format; import org.restcomm.media.spi.format.FormatFactory; import org.restcomm.media.spi.memory.Frame; import org.restcomm.media.spi.memory.Memory; /** * Implements G.711 A-Law decompressor. * * @author Oleg Kulikov */ public class Decoder implements Codec { private final static Format alaw = FormatFactory.createAudioFormat("pcma", 8000, 8, 1); private final static Format linear = FormatFactory.createAudioFormat("linear", 8000, 16, 1); private int j=0,i=0; private int sourceLen=0,destinationLen=0; private int currentIndex; /** decompress table constants separated into low and high bytes*/ private static byte aLawDecompressTable_low[] = new byte[]{ (byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80, (byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80, (byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0, (byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0xa8,(byte)0xb8,(byte)0x88,(byte)0x98,(byte)0xe8,(byte)0xf8,(byte)0xc8,(byte)0xd8, (byte)0x28,(byte)0x38,(byte)0x8,(byte)0x18,(byte)0x68,(byte)0x78,(byte)0x48,(byte)0x58, (byte)0xa8,(byte)0xb8,(byte)0x88,(byte)0x98,(byte)0xe8,(byte)0xf8,(byte)0xc8,(byte)0xd8, (byte)0x28,(byte)0x38,(byte)0x8,(byte)0x18,(byte)0x68,(byte)0x78,(byte)0x48,(byte)0x58, (byte)0xa0,(byte)0xe0,(byte)0x20,(byte)0x60,(byte)0xa0,(byte)0xe0,(byte)0x20,(byte)0x60, (byte)0xa0,(byte)0xe0,(byte)0x20,(byte)0x60,(byte)0xa0,(byte)0xe0,(byte)0x20,(byte)0x60, (byte)0x50,(byte)0x70,(byte)0x10,(byte)0x30,(byte)0xd0,(byte)0xf0,(byte)0x90,(byte)0xb0, (byte)0x50,(byte)0x70,(byte)0x10,(byte)0x30,(byte)0xd0,(byte)0xf0,(byte)0x90,(byte)0xb0, (byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80, (byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80, (byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40, (byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40,(byte)0xc0,(byte)0x40, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x58,(byte)0x48,(byte)0x78,(byte)0x68,(byte)0x18,(byte)0x8,(byte)0x38,(byte)0x28, (byte)0xd8,(byte)0xc8,(byte)0xf8,(byte)0xe8,(byte)0x98,(byte)0x88,(byte)0xb8,(byte)0xa8, (byte)0x58,(byte)0x48,(byte)0x78,(byte)0x68,(byte)0x18,(byte)0x8,(byte)0x38,(byte)0x28, (byte)0xd8,(byte)0xc8,(byte)0xf8,(byte)0xe8,(byte)0x98,(byte)0x88,(byte)0xb8,(byte)0xa8, (byte)0x60,(byte)0x20,(byte)0xe0,(byte)0xa0,(byte)0x60,(byte)0x20,(byte)0xe0,(byte)0xa0, (byte)0x60,(byte)0x20,(byte)0xe0,(byte)0xa0,(byte)0x60,(byte)0x20,(byte)0xe0,(byte)0xa0, (byte)0xb0,(byte)0x90,(byte)0xf0,(byte)0xd0,(byte)0x30,(byte)0x10,(byte)0x70,(byte)0x50, (byte)0xb0,(byte)0x90,(byte)0xf0,(byte)0xd0,(byte)0x30,(byte)0x10,(byte)0x70,(byte)0x50, }; private static byte aLawDecompressTable_high[] = new byte[]{ (byte)0xea,(byte)0xeb,(byte)0xe8,(byte)0xe9,(byte)0xee,(byte)0xef,(byte)0xec,(byte)0xed, (byte)0xe2,(byte)0xe3,(byte)0xe0,(byte)0xe1,(byte)0xe6,(byte)0xe7,(byte)0xe4,(byte)0xe5, (byte)0xf5,(byte)0xf5,(byte)0xf4,(byte)0xf4,(byte)0xf7,(byte)0xf7,(byte)0xf6,(byte)0xf6, (byte)0xf1,(byte)0xf1,(byte)0xf0,(byte)0xf0,(byte)0xf3,(byte)0xf3,(byte)0xf2,(byte)0xf2, (byte)0xaa,(byte)0xae,(byte)0xa2,(byte)0xa6,(byte)0xba,(byte)0xbe,(byte)0xb2,(byte)0xb6, (byte)0x8a,(byte)0x8e,(byte)0x82,(byte)0x86,(byte)0x9a,(byte)0x9e,(byte)0x92,(byte)0x96, (byte)0xd5,(byte)0xd7,(byte)0xd1,(byte)0xd3,(byte)0xdd,(byte)0xdf,(byte)0xd9,(byte)0xdb, (byte)0xc5,(byte)0xc7,(byte)0xc1,(byte)0xc3,(byte)0xcd,(byte)0xcf,(byte)0xc9,(byte)0xcb, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, (byte)0xfa,(byte)0xfa,(byte)0xfa,(byte)0xfa,(byte)0xfb,(byte)0xfb,(byte)0xfb,(byte)0xfb, (byte)0xf8,(byte)0xf8,(byte)0xf8,(byte)0xf8,(byte)0xf9,(byte)0xf9,(byte)0xf9,(byte)0xf9, (byte)0xfd,(byte)0xfd,(byte)0xfd,(byte)0xfd,(byte)0xfd,(byte)0xfd,(byte)0xfd,(byte)0xfd, (byte)0xfc,(byte)0xfc,(byte)0xfc,(byte)0xfc,(byte)0xfc,(byte)0xfc,(byte)0xfc,(byte)0xfc, (byte)0x15,(byte)0x14,(byte)0x17,(byte)0x16,(byte)0x11,(byte)0x10,(byte)0x13,(byte)0x12, (byte)0x1d,(byte)0x1c,(byte)0x1f,(byte)0x1e,(byte)0x19,(byte)0x18,(byte)0x1b,(byte)0x1a, (byte)0xa,(byte)0xa,(byte)0xb,(byte)0xb,(byte)0x8,(byte)0x8,(byte)0x9,(byte)0x9, (byte)0xe,(byte)0xe,(byte)0xf,(byte)0xf,(byte)0xc,(byte)0xc,(byte)0xd,(byte)0xd, (byte)0x56,(byte)0x52,(byte)0x5e,(byte)0x5a,(byte)0x46,(byte)0x42,(byte)0x4e,(byte)0x4a, (byte)0x76,(byte)0x72,(byte)0x7e,(byte)0x7a,(byte)0x66,(byte)0x62,(byte)0x6e,(byte)0x6a, (byte)0x2b,(byte)0x29,(byte)0x2f,(byte)0x2d,(byte)0x23,(byte)0x21,(byte)0x27,(byte)0x25, (byte)0x3b,(byte)0x39,(byte)0x3f,(byte)0x3d,(byte)0x33,(byte)0x31,(byte)0x37,(byte)0x35, (byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1, (byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1,(byte)0x1, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0,(byte)0x0, (byte)0x5,(byte)0x5,(byte)0x5,(byte)0x5,(byte)0x4,(byte)0x4,(byte)0x4,(byte)0x4, (byte)0x7,(byte)0x7,(byte)0x7,(byte)0x7,(byte)0x6,(byte)0x6,(byte)0x6,(byte)0x6, (byte)0x2,(byte)0x2,(byte)0x2,(byte)0x2,(byte)0x2,(byte)0x2,(byte)0x2,(byte)0x2, (byte)0x3,(byte)0x3,(byte)0x3,(byte)0x3,(byte)0x3,(byte)0x3,(byte)0x3,(byte)0x3, }; /** * (Non Java-doc) * * @see org.mobicents.media.server.impl.jmf.dsp.Codec#getSupportedFormat(). */ public Format getSupportedInputFormat() { return alaw; } /** * (Non Java-doc) * * @see org.mobicents.media.server.impl.jmf.dsp.Codec#getSupportedFormat(). */ public Format getSupportedOutputFormat() { return linear; } /** * (Non Java-doc) * * @see org.mobicents.media.server.dsp.Codec#process(Frame). */ public Frame process(Frame frame) { sourceLen=frame.getLength(); destinationLen=sourceLen * 2; Frame res = Memory.allocate(destinationLen); byte[] data=frame.getData(); byte[] resData=res.getData(); for (i = 0,j = 0; i < sourceLen; i++) { currentIndex = data[i] & 0xff; resData[j++] = aLawDecompressTable_low[currentIndex]; resData[j++] = aLawDecompressTable_high[currentIndex]; } res.setOffset(0); res.setLength(destinationLen); res.setTimestamp(frame.getTimestamp()); res.setDuration(frame.getDuration()); res.setSequenceNumber(frame.getSequenceNumber()); res.setEOM(frame.isEOM()); res.setFormat(linear); res.setHeader(frame.getHeader()); return res; } }