00001 /* 00002 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 /* 00023 ** This code is taken from aiff.c from libsndfile by Erik de Castro Lopo 00024 ** http://www.zip.com.au/~erikd/libsndfile/libsndfile-1.0.1.tar.gz 00025 ** 00026 ** This is a rough hack at converting from 80 bit IEEE float in AIFF header to an 00027 ** int and back again. It assumes that all sample rates are between 1 and 800MHz, 00028 ** which should be OK as other sound file formats use a 32 bit integer to store 00029 ** sample rate. 00030 ** 00031 ** There is another (probably better) version in the source code to the SoX but it 00032 ** has a copyright which probably prevents it from being allowable as GPL/LGPL. 00033 ** 00034 ** Another, very complete, implementation of the same conversions, written by 00035 ** Ken Turkowski <turk@computer.org> is available at 00036 ** http://www.worldserver.com/turk/opensource/ToFromIEEE.c.txt 00037 ** 00038 ** ========================================================================================= 00039 ** 00040 ** Copyright (C) 1999-2002 Erik de Castro Lopo <erikd@zip.com.au> 00041 ** 00042 ** This program is free software; you can redistribute it and/or modify 00043 ** it under the terms of the GNU Lesser General Public License as published by 00044 ** the Free Software Foundation; either version 2.1 of the License, or 00045 ** (at your option) any later version. 00046 ** 00047 ** This program is distributed in the hope that it will be useful, 00048 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00049 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00050 ** GNU Lesser General Public License for more details. 00051 ** 00052 ** You should have received a copy of the GNU Lesser General Public License 00053 ** along with this program; if not, write to the Free Software 00054 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00055 */ 00056 00057 #include <stdlib.h> 00058 #include <memory.h> 00059 00060 int 00061 tenbytefloat2int (unsigned char *bytes) 00062 { int val = 3 ; 00063 00064 if (bytes [0] & 0x80) /* Negative number. */ 00065 return 0 ; 00066 00067 if (bytes [0] <= 0x3F) /* Less than 1. */ 00068 return 1 ; 00069 00070 if (bytes [0] > 0x40) /* Way too big. */ 00071 return 0x4000000 ; 00072 00073 if (bytes [0] == 0x40 && bytes [1] > 0x1C) /* Too big. */ 00074 return 800000000 ; 00075 00076 /* Ok, can handle it. */ 00077 00078 val = (bytes [2] << 23) | 00079 (bytes [3] << 15) | (bytes [4] << 7) | (bytes [5] >> 1) ; 00080 00081 val >>= (29 - bytes [1]) ; 00082 00083 return val ; 00084 } /* tenbytefloat2int */ 00085 00086 00087 void 00088 uint2tenbytefloat (unsigned int num, unsigned char *bytes) 00089 { unsigned int mask = 0x40000000 ; 00090 int count ; 00091 00092 00093 memset (bytes, 0, 10) ; 00094 00095 if (num <= 1) 00096 { bytes [0] = 0x3F ; 00097 bytes [1] = 0xFF ; 00098 bytes [2] = 0x80 ; 00099 return ; 00100 } ; 00101 00102 bytes [0] = 0x40 ; 00103 00104 if (num >= mask) 00105 { bytes [1] = 0x1D ; 00106 return ; 00107 } ; 00108 00109 for (count = 0 ; count <= 32 ; count ++) 00110 { if (num & mask) 00111 break ; 00112 mask >>= 1 ; 00113 } ; 00114 00115 num <<= count + 1 ; 00116 bytes [1] = 29 - count ; 00117 bytes [2] = (num >> 24) & 0xFF ; 00118 bytes [3] = (num >> 16) & 0xFF ; 00119 bytes [4] = (num >> 8) & 0xFF ; 00120 bytes [5] = num & 0xFF ; 00121 00122 } /* uint2tenbytefloat */ 00123 00124