/* * CINELERRA * Copyright (C) 2008 Adam Williams * * 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 * */ #include "assets.h" #include "byteorder.h" #include "file.h" #include "filebase.h" #include "sizes.h" // ======================================= ulaw codecs float FileBase::ulawtofloat(char ulaw) { //printf("%f\n", ulawtofloat_ptr[ulaw]); return ulawtofloat_ptr[(unsigned char)ulaw]; } char FileBase::floattoulaw(float value) { return floattoulaw_ptr[(int)(value * 32767)]; } // turn off the trap as per the MIL-STD #undef ZEROTRAP // define the add-in bias for 16 bit samples #define uBIAS 0x84 #define uCLIP 32635 int FileBase::generate_ulaw_tables() { if( !ulawtofloat_table ) { static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 }; int sign, exponent, mantissa, sample; unsigned char ulawbyte; ulawtofloat_table = new float[256]; ulawtofloat_ptr = ulawtofloat_table; for(int i = 0; i < 256; i++) { ulawbyte = (unsigned char)i; ulawbyte = ~ ulawbyte; sign = ( ulawbyte & 0x80 ); exponent = ( ulawbyte >> 4 ) & 0x07; mantissa = ulawbyte & 0x0F; sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) ); if ( sign != 0 ) sample = -sample; ulawtofloat_ptr[(int)i] = (float)sample / 32768; } } if( !floattoulaw_table ) { int sign, exponent, mantissa; unsigned char ulawbyte; int sample; int exp_lut[256] = { 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, }; floattoulaw_table = new unsigned char[65536]; floattoulaw_ptr = floattoulaw_table + 32768; for(int i = -32768; i < 32768; i++) { sample = i; // Get the sample into sign-magnitude. sign = (sample >> 8) & 0x80; // set aside the sign if ( sign != 0 ) sample = -sample; // get magnitude if ( sample > uCLIP ) sample = uCLIP; // clip the magnitude // Convert from 16 bit linear to ulaw. sample = sample + uBIAS; exponent = exp_lut[( sample >> 7 ) & 0xFF]; mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F; ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa ); #ifdef ZEROTRAP if ( ulawbyte == 0 ) ulawbyte = 0x02; /* optional CCITT trap */ #endif floattoulaw_ptr[i] = ulawbyte; } } return 0; } int FileBase::delete_ulaw_tables() { if(floattoulaw_table) delete [] floattoulaw_table; if(ulawtofloat_table) delete [] ulawtofloat_table; floattoulaw_table = 0; ulawtofloat_table = 0; return 0; }