# HG changeset patch # User Nikita Kozlov # Date 1264204275 -3600 # Node ID f703b3e14f9a186c16a687151f31a456960b4bb3 # Parent 6089f3255c5fac52a388c4425e0b0ec1713b029d# Parent e29937c5670ca87872406c4b80420618c6deb889 merge diff -r e29937c5670c -r f703b3e14f9a .classpath --- a/.classpath Sat Jan 23 00:46:38 2010 +0100 +++ b/.classpath Sat Jan 23 00:51:15 2010 +0100 @@ -1,10 +1,7 @@ - - - - - - - - - - + + + + + + + diff -r e29937c5670c -r f703b3e14f9a AndroidManifest.xml --- a/AndroidManifest.xml Sat Jan 23 00:46:38 2010 +0100 +++ b/AndroidManifest.xml Sat Jan 23 00:51:15 2010 +0100 @@ -14,6 +14,7 @@ + - + + @@ -83,8 +91,12 @@ android:name="com.beem.project.beem.BEEM_SERVICE"> + + + + - + diff -r e29937c5670c -r f703b3e14f9a build.xml --- a/build.xml Sat Jan 23 00:46:38 2010 +0100 +++ b/build.xml Sat Jan 23 00:51:15 2010 +0100 @@ -66,7 +66,7 @@ - + diff -r e29937c5670c -r f703b3e14f9a jni/Android.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/Android.mk Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,50 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := gsm + +SRC_FILES := gsm/add.c\ + gsm/code.c\ + gsm/debug.c\ + gsm/decode.c\ + gsm/gsm_create.c\ + gsm/gsm_decode.c\ + gsm/gsm_destroy.c\ + gsm/gsm_encode.c\ + gsm/gsm_explode.c\ + gsm/gsm_implode.c\ + gsm/gsm_option.c\ + gsm/gsm_print.c\ + gsm/long_term.c\ + gsm/lpc.c\ + gsm/preprocess.c\ + gsm/rpe.c\ + gsm/short_term.c\ + gsm/table.c\ + gsm/gsm_jni.c +LOCAL_SRC_FILES := $(SRC_FILES) + +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_MODULE := g722 + +SRC_FILES := g722/g722_encode.c\ + g722/g722_decode.c\ + g722/g722_jni.c +LOCAL_SRC_FILES := $(SRC_FILES) + +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_MODULE := OSNetworkSystem + +SRC_FILES := OSNetworkSystem.cpp + +#LOCAL_LDLIBS := -llog +LOCAL_SRC_FILES := $(SRC_FILES) + +include $(BUILD_SHARED_LIBRARY) diff -r e29937c5670c -r f703b3e14f9a jni/Application.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/Application.mk Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,3 @@ +APP_PROJECT_PATH := /home/nikita/devel/beem/beem-audio/ +APP_BUILD_SCRIPT := ${APP_PROJECT_PATH}/jni/Android.mk +APP_MODULES := gsm g722 OSNetworkSystem diff -r e29937c5670c -r f703b3e14f9a jni/OSNetworkSystem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/OSNetworkSystem.cpp Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,3688 @@ +/* + * Copyright (C) 2009 The Sipdroid Open Source Project + * Copyright (C) 2007 The Android Open Source Project + * + * This file is part of Sipdroid (http://www.sipdroid.org) + * + * Sipdroid 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 3 of the License, or + * (at your option) any later version. + * + * This source code 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 source code; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define LOG_TAG "OSNetworkSystem" + +#include +#include "jni.h" +#include "errno.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +//#include +//#include +//#include "AndroidSystemNatives.h" + +/** + * @name Socket Errors + * Error codes for socket operations + * + * @internal SOCKERR* range from -200 to -299 avoid overlap + */ +#define SOCKERR_BADSOCKET -200 /* generic error */ +#define SOCKERR_NOTINITIALIZED -201 /* socket library uninitialized */ +#define SOCKERR_BADAF -202 /* bad address family */ +#define SOCKERR_BADPROTO -203 /* bad protocol */ +#define SOCKERR_BADTYPE -204 /* bad type */ +#define SOCKERR_SYSTEMBUSY -205 /* system busy handling requests */ +#define SOCKERR_SYSTEMFULL -206 /* too many sockets */ +#define SOCKERR_NOTCONNECTED -207 /* socket is not connected */ +#define SOCKERR_INTERRUPTED -208 /* the call was cancelled */ +#define SOCKERR_TIMEOUT -209 /* the operation timed out */ +#define SOCKERR_CONNRESET -210 /* the connection was reset */ +#define SOCKERR_WOULDBLOCK -211 /* the socket is marked as nonblocking operation would block */ +#define SOCKERR_ADDRNOTAVAIL -212 /* address not available */ +#define SOCKERR_ADDRINUSE -213 /* address already in use */ +#define SOCKERR_NOTBOUND -214 /* the socket is not bound */ +#define SOCKERR_UNKNOWNSOCKET -215 /* resolution of fileDescriptor to socket failed */ +#define SOCKERR_INVALIDTIMEOUT -216 /* the specified timeout is invalid */ +#define SOCKERR_FDSETFULL -217 /* Unable to create an FDSET */ +#define SOCKERR_TIMEVALFULL -218 /* Unable to create a TIMEVAL */ +#define SOCKERR_REMSOCKSHUTDOWN -219 /* The remote socket has shutdown gracefully */ +#define SOCKERR_NOTLISTENING -220 /* listen() was not invoked prior to accept() */ +#define SOCKERR_NOTSTREAMSOCK -221 /* The socket does not support connection-oriented service */ +#define SOCKERR_ALREADYBOUND -222 /* The socket is already bound to an address */ +#define SOCKERR_NBWITHLINGER -223 /* The socket is marked non-blocking & SO_LINGER is non-zero */ +#define SOCKERR_ISCONNECTED -224 /* The socket is already connected */ +#define SOCKERR_NOBUFFERS -225 /* No buffer space is available */ +#define SOCKERR_HOSTNOTFOUND -226 /* Authoritative Answer Host not found */ +#define SOCKERR_NODATA -227 /* Valid name, no data record of requested type */ +#define SOCKERR_BOUNDORCONN -228 /* The socket has not been bound or is already connected */ +#define SOCKERR_OPNOTSUPP -229 /* The socket does not support the operation */ +#define SOCKERR_OPTUNSUPP -230 /* The socket option is not supported */ +#define SOCKERR_OPTARGSINVALID -231 /* The socket option arguments are invalid */ +#define SOCKERR_SOCKLEVELINVALID -232 /* The socket level is invalid */ +#define SOCKERR_TIMEOUTFAILURE -233 +#define SOCKERR_SOCKADDRALLOCFAIL -234 /* Unable to allocate the sockaddr structure */ +#define SOCKERR_FDSET_SIZEBAD -235 /* The calculated maximum size of the file descriptor set is bad */ +#define SOCKERR_UNKNOWNFLAG -236 /* The flag is unknown */ +#define SOCKERR_MSGSIZE -237 /* The datagram was too big to fit the specified buffer & was truncated. */ +#define SOCKERR_NORECOVERY -238 /* The operation failed with no recovery possible */ +#define SOCKERR_ARGSINVALID -239 /* The arguments are invalid */ +#define SOCKERR_BADDESC -240 /* The socket argument is not a valid file descriptor */ +#define SOCKERR_NOTSOCK -241 /* The socket argument is not a socket */ +#define SOCKERR_HOSTENTALLOCFAIL -242 /* Unable to allocate the hostent structure */ +#define SOCKERR_TIMEVALALLOCFAIL -243 /* Unable to allocate the timeval structure */ +#define SOCKERR_LINGERALLOCFAIL -244 /* Unable to allocate the linger structure */ +#define SOCKERR_IPMREQALLOCFAIL -245 /* Unable to allocate the ipmreq structure */ +#define SOCKERR_FDSETALLOCFAIL -246 /* Unable to allocate the fdset structure */ +#define SOCKERR_OPFAILED -247 /* Operation failed */ +#define SOCKERR_VALUE_NULL -248 /* The value indexed was NULL */ +#define SOCKERR_CONNECTION_REFUSED -249 /* connection was refused */ +#define SOCKERR_ENETUNREACH -250 /* network is not reachable */ +#define SOCKERR_EACCES -251 /* permissions do not allow action on socket */ +#define SOCKERR_EHOSTUNREACH -252 /* no route to host */ +#define SOCKERR_EPIPE -253 /* broken pipe */ + +#define JAVASOCKOPT_TCP_NODELAY 1 +#define JAVASOCKOPT_IP_TOS 3 +#define JAVASOCKOPT_SO_REUSEADDR 4 +#define JAVASOCKOPT_SO_KEEPALIVE 8 +#define JAVASOCKOPT_MCAST_TIME_TO_LIVE 10 /* Currently unused */ +#define JAVASOCKOPT_SO_BINDADDR 15 +#define JAVASOCKOPT_MCAST_INTERFACE 16 +#define JAVASOCKOPT_MCAST_TTL 17 +#define JAVASOCKOPT_IP_MULTICAST_LOOP 18 +#define JAVASOCKOPT_MCAST_ADD_MEMBERSHIP 19 +#define JAVASOCKOPT_MCAST_DROP_MEMBERSHIP 20 +#define JAVASOCKOPT_IP_MULTICAST_IF2 31 +#define JAVASOCKOPT_SO_BROADCAST 32 +#define JAVASOCKOPT_SO_LINGER 128 +#define JAVASOCKOPT_REUSEADDR_AND_REUSEPORT 10001 +#define JAVASOCKOPT_SO_SNDBUF 4097 +#define JAVASOCKOPT_SO_RCVBUF 4098 +#define JAVASOCKOPT_SO_RCVTIMEOUT 4102 +#define JAVASOCKOPT_SO_OOBINLINE 4099 + +/* constants for calling multi-call functions */ +#define SOCKET_STEP_START 10 +#define SOCKET_STEP_CHECK 20 +#define SOCKET_STEP_DONE 30 + +#define BROKEN_MULTICAST_IF 1 +#define BROKEN_MULTICAST_TTL 2 +#define BROKEN_TCP_NODELAY 4 + +#define SOCKET_CONNECT_STEP_START 0 +#define SOCKET_CONNECT_STEP_CHECK 1 + +#define SOCKET_OP_NONE 0 +#define SOCKET_OP_READ 1 +#define SOCKET_OP_WRITE 2 +#define SOCKET_READ_WRITE 3 + +#define SOCKET_MSG_PEEK 1 +#define SOCKET_MSG_OOB 2 + +#define SOCKET_NOFLAGS 0 + +#undef BUFFERSIZE +#define BUFFERSIZE 2048 + +// wait for 500000 usec = 0.5 second +#define SEND_RETRY_TIME 500000 + + +struct CachedFields { + jfieldID fd_descriptor; + jclass iaddr_class; + jmethodID iaddr_class_init; + jmethodID iaddr_getbyaddress; + jfieldID iaddr_ipaddress; + jclass genericipmreq_class; + jclass integer_class; + jmethodID integer_class_init; + jfieldID integer_class_value; + jclass boolean_class; + jmethodID boolean_class_init; + jfieldID boolean_class_value; + jclass byte_class; + jmethodID byte_class_init; + jfieldID byte_class_value; + jclass string_class; + jmethodID string_class_init; + jfieldID socketimpl_address; + jfieldID socketimpl_port; + jclass dpack_class; + jfieldID dpack_address; + jfieldID dpack_port; + jfieldID dpack_length; + jclass fd_class; + jfieldID descriptor; +} gCachedFields; + +static int useAdbNetworking = 0; + +/* needed for connecting with timeout */ +typedef struct selectFDSet { + int nfds; + int sock; + fd_set writeSet; + fd_set readSet; + fd_set exceptionSet; +} selectFDSet; + +static const char * netLookupErrorString(int anErrorNum); + +#define log_socket_close(a,b) +#define log_socket_connect(a,b,c) +#define add_send_stats(a,b) +#define add_recv_stats(a,b) +#define adb_networking_connect_fd(a,b) 0 +#define adb_networking_gethostbyname(a,b) 0 +#define PROPERTY_VALUE_MAX 1 +#define property_get(a,b,c) +#define assert(a) +/* + * Throw an exception with the specified class and an optional message. + */ +int jniThrowException(JNIEnv* env, const char* className, const char* msg) +{ + jclass exceptionClass; + + exceptionClass = env->FindClass(className); + if (exceptionClass == NULL) { +// LOGE("Unable to find exception class %s\n", className); + assert(0); /* fatal during dev; should always be fatal? */ + return -1; + } + + if (env->ThrowNew(exceptionClass, msg) != JNI_OK) { +// LOGE("Failed throwing '%s' '%s'\n", className, msg); + assert(!"failed to throw"); + } + return 0; +} + +/* + * Internal helper function. + * + * Get the file descriptor. + */ +static inline int getFd(JNIEnv* env, jobject obj) +{ + return env->GetIntField(obj, gCachedFields.descriptor); +} + +/* + * Internal helper function. + * + * Set the file descriptor. + */ +static inline void setFd(JNIEnv* env, jobject obj, jint value) +{ + env->SetIntField(obj, gCachedFields.descriptor, value); +} + +/* + * For JNIHelp.c + * Get an int file descriptor from a java.io.FileDescriptor + */ + +static int jniGetFDFromFileDescriptor (JNIEnv* env, jobject fileDescriptor) { + + return getFd(env, fileDescriptor); +} + +/* + * For JNIHelp.c + * Set the descriptor of a java.io.FileDescriptor + */ + +static void jniSetFileDescriptorOfFD (JNIEnv* env, jobject fileDescriptor, int value) { + + setFd(env, fileDescriptor, value); +} + +/** + * Throws an SocketException with the message affiliated with the errorCode. + */ +static void throwSocketException(JNIEnv *env, int errorCode) { + jniThrowException(env, "java/net/SocketException", + netLookupErrorString(errorCode)); +} + +/** + * Throws an IOException with the given message. + */ +static void throwIOExceptionStr(JNIEnv *env, const char *message) { + jniThrowException(env, "java/io/IOException", message); +} + +/** + * Throws a NullPointerException. + */ +static void throwNullPointerException(JNIEnv *env) { + jniThrowException(env, "java/lang/NullPointerException", NULL); +} + +/** + * Converts a 4-byte array to a native address structure. Throws a + * NullPointerException or an IOException in case of error. This is + * signaled by a return value of -1. The normal return value is 0. + */ +static int javaAddressToStructIn( + JNIEnv *env, jbyteArray java_address, struct in_addr *address) { + + memset(address, 0, sizeof(address)); + + if (java_address == NULL) { + return -1; + } + + if (env->GetArrayLength(java_address) != sizeof(address->s_addr)) { + return -1; + } + + jbyte * java_address_bytes + = env->GetByteArrayElements(java_address, NULL); + + memcpy(&(address->s_addr), + java_address_bytes, + sizeof(address->s_addr)); + + env->ReleaseByteArrayElements(java_address, java_address_bytes, JNI_ABORT); + + return 0; +} + +/** + * Converts a native address structure to a 4-byte array. Throws a + * NullPointerException or an IOException in case of error. This is + * signaled by a return value of -1. The normal return value is 0. + */ +static int structInToJavaAddress( + JNIEnv *env, struct in_addr *address, jbyteArray java_address) { + + if (java_address == NULL) { + return -1; + } + + if (env->GetArrayLength(java_address) != sizeof(address->s_addr)) { + return -1; + } + + jbyte *java_address_bytes; + + java_address_bytes = env->GetByteArrayElements(java_address, NULL); + + memcpy(java_address_bytes, &(address->s_addr), sizeof(address->s_addr)); + + env->ReleaseByteArrayElements(java_address, java_address_bytes, 0); + + return 0; +} + +/** + * Converts a native address structure to an InetAddress object. + * Throws a NullPointerException or an IOException in case of + * error. This is signaled by a return value of -1. The normal + * return value is 0. + */ +static int socketAddressToInetAddress(JNIEnv *env, + struct sockaddr_in *sockaddress, jobject inetaddress, int *port) { + + jbyteArray ipaddress; + int result; + + ipaddress = (jbyteArray)env->GetObjectField(inetaddress, + gCachedFields.iaddr_ipaddress); + + if (structInToJavaAddress(env, &sockaddress->sin_addr, ipaddress) < 0) { + return -1; + } + + *port = ntohs(sockaddress->sin_port); + + return 0; +} + +/** + * Converts an InetAddress object to a native address structure. + * Throws a NullPointerException or an IOException in case of + * error. This is signaled by a return value of -1. The normal + * return value is 0. + */ +static int inetAddressToSocketAddress(JNIEnv *env, + jobject inetaddress, int port, struct sockaddr_in *sockaddress) { + + jbyteArray ipaddress; + int result; + + ipaddress = (jbyteArray)env->GetObjectField(inetaddress, + gCachedFields.iaddr_ipaddress); + + memset(sockaddress, 0, sizeof(sockaddress)); + + sockaddress->sin_family = AF_INET; + sockaddress->sin_port = htons(port); + + if (javaAddressToStructIn(env, ipaddress, &(sockaddress->sin_addr)) < 0) { + return -1; + } + + return 0; +} + +static jobject structInToInetAddress(JNIEnv *env, struct in_addr *address) { + jbyteArray bytes; + int success; + + bytes = env->NewByteArray(4); + + if (bytes == NULL) { + return NULL; + } + + if (structInToJavaAddress(env, address, bytes) < 0) { + return NULL; + } + + return env->CallStaticObjectMethod(gCachedFields.iaddr_class, + gCachedFields.iaddr_getbyaddress, bytes); +} + +/** + * Answer a new java.lang.Boolean object. + * + * @param env pointer to the JNI library + * @param anInt the Boolean constructor argument + * + * @return the new Boolean + */ + +static jobject newJavaLangBoolean(JNIEnv * env, jint anInt) { + jclass tempClass; + jmethodID tempMethod; + + tempClass = gCachedFields.boolean_class; + tempMethod = gCachedFields.boolean_class_init; + return env->NewObject(tempClass, tempMethod, (jboolean) (anInt != 0)); +} + +/** + * Answer a new java.lang.Byte object. + * + * @param env pointer to the JNI library + * @param anInt the Byte constructor argument + * + * @return the new Byte + */ + +static jobject newJavaLangByte(JNIEnv * env, jbyte val) { + jclass tempClass; + jmethodID tempMethod; + + tempClass = gCachedFields.byte_class; + tempMethod = gCachedFields.byte_class_init; + return env->NewObject(tempClass, tempMethod, val); +} + +/** + * Answer a new java.lang.Integer object. + * + * @param env pointer to the JNI library + * @param anInt the Integer constructor argument + * + * @return the new Integer + */ + +static jobject newJavaLangInteger(JNIEnv * env, jint anInt) { + jclass tempClass; + jmethodID tempMethod; + + tempClass = gCachedFields.integer_class; + tempMethod = gCachedFields.integer_class_init; + return env->NewObject(tempClass, tempMethod, anInt); +} + +/** + * Answer a new java.lang.String object. + * + * @param env pointer to the JNI library + * @param anInt the byte[] constructor argument + * + * @return the new String + */ + +static jobject newJavaLangString(JNIEnv * env, jbyteArray bytes) { + jclass tempClass; + jmethodID tempMethod; + + tempClass = gCachedFields.string_class; + tempMethod = gCachedFields.string_class_init; + return env->NewObject(tempClass, tempMethod, (jbyteArray) bytes); +} + +/** + * Query OS for timestamp. + * Retrieve the current value of system clock and convert to milliseconds. + * + * @param[in] portLibrary The port library. + * + * @return 0 on failure, time value in milliseconds on success. + * @deprecated Use @ref time_hires_clock and @ref time_hires_delta + * + * technically, this should return I_64 since both timeval.tv_sec and + * timeval.tv_usec are long + */ + +static int time_msec_clock() { + struct timeval tp; + struct timezone tzp; + + gettimeofday(&tp, &tzp); + return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); +} + +/** + * check if the passed sockaddr_in struct contains a localhost address + * + * @param[in] address pointer to the address to check + * + * @return 0 if the passed address isn't a localhost address + */ +static int isLocalhost(struct sockaddr_in *address) { + // return address == 127.0.0.1 + return (unsigned int) address->sin_addr.s_addr == 16777343; +} + +/** + * Answer the errorString corresponding to the errorNumber, if available. + * This function will answer a default error string, if the errorNumber is not + * recognized. + * + * This function will have to be reworked to handle internationalization + * properly, removing the explicit strings. + * + * @param anErrorNum the error code to resolve to a human readable string + * + * @return a human readable error string + */ + +static const char * netLookupErrorString(int anErrorNum) { + switch (anErrorNum) { + case SOCKERR_BADSOCKET: + return "Bad socket"; + case SOCKERR_NOTINITIALIZED: + return "Socket library uninitialized"; + case SOCKERR_BADAF: + return "Bad address family"; + case SOCKERR_BADPROTO: + return "Bad protocol"; + case SOCKERR_BADTYPE: + return "Bad type"; + case SOCKERR_SYSTEMBUSY: + return "System busy handling requests"; + case SOCKERR_SYSTEMFULL: + return "Too many sockets allocated"; + case SOCKERR_NOTCONNECTED: + return "Socket is not connected"; + case SOCKERR_INTERRUPTED: + return "The system call was cancelled"; + case SOCKERR_TIMEOUT: + return "The operation timed out"; + case SOCKERR_CONNRESET: + return "The connection was reset"; + case SOCKERR_WOULDBLOCK: + return "The nonblocking operation would block"; + case SOCKERR_ADDRNOTAVAIL: + return "The address is not available"; + case SOCKERR_ADDRINUSE: + return "The address is already in use"; + case SOCKERR_NOTBOUND: + return "The socket is not bound"; + case SOCKERR_UNKNOWNSOCKET: + return "Resolution of the FileDescriptor to socket failed"; + case SOCKERR_INVALIDTIMEOUT: + return "The specified timeout is invalid"; + case SOCKERR_FDSETFULL: + return "Unable to create an FDSET"; + case SOCKERR_TIMEVALFULL: + return "Unable to create a TIMEVAL"; + case SOCKERR_REMSOCKSHUTDOWN: + return "The remote socket has shutdown gracefully"; + case SOCKERR_NOTLISTENING: + return "Listen() was not invoked prior to accept()"; + case SOCKERR_NOTSTREAMSOCK: + return "The socket does not support connection-oriented service"; + case SOCKERR_ALREADYBOUND: + return "The socket is already bound to an address"; + case SOCKERR_NBWITHLINGER: + return "The socket is marked non-blocking & SO_LINGER is non-zero"; + case SOCKERR_ISCONNECTED: + return "The socket is already connected"; + case SOCKERR_NOBUFFERS: + return "No buffer space is available"; + case SOCKERR_HOSTNOTFOUND: + return "Authoritative Answer Host not found"; + case SOCKERR_NODATA: + return "Valid name, no data record of requested type"; + case SOCKERR_BOUNDORCONN: + return "The socket has not been bound or is already connected"; + case SOCKERR_OPNOTSUPP: + return "The socket does not support the operation"; + case SOCKERR_OPTUNSUPP: + return "The socket option is not supported"; + case SOCKERR_OPTARGSINVALID: + return "The socket option arguments are invalid"; + case SOCKERR_SOCKLEVELINVALID: + return "The socket level is invalid"; + case SOCKERR_TIMEOUTFAILURE: + return "The timeout operation failed"; + case SOCKERR_SOCKADDRALLOCFAIL: + return "Failed to allocate address structure"; + case SOCKERR_FDSET_SIZEBAD: + return "The calculated maximum size of the file descriptor set is bad"; + case SOCKERR_UNKNOWNFLAG: + return "The flag is unknown"; + case SOCKERR_MSGSIZE: + return "The datagram was too big to fit the specified buffer, so truncated"; + case SOCKERR_NORECOVERY: + return "The operation failed with no recovery possible"; + case SOCKERR_ARGSINVALID: + return "The arguments are invalid"; + case SOCKERR_BADDESC: + return "The socket argument is not a valid file descriptor"; + case SOCKERR_NOTSOCK: + return "The socket argument is not a socket"; + case SOCKERR_HOSTENTALLOCFAIL: + return "Unable to allocate the hostent structure"; + case SOCKERR_TIMEVALALLOCFAIL: + return "Unable to allocate the timeval structure"; + case SOCKERR_LINGERALLOCFAIL: + return "Unable to allocate the linger structure"; + case SOCKERR_IPMREQALLOCFAIL: + return "Unable to allocate the ipmreq structure"; + case SOCKERR_FDSETALLOCFAIL: + return "Unable to allocate the fdset structure"; + case SOCKERR_OPFAILED: + return "Operation failed"; + case SOCKERR_CONNECTION_REFUSED: + return "Connection refused"; + case SOCKERR_ENETUNREACH: + return "Network unreachable"; + case SOCKERR_EHOSTUNREACH: + return "No route to host"; + case SOCKERR_EPIPE: + return "Broken pipe"; + case SOCKERR_EACCES: + return "Permission denied (maybe missing INTERNET permission)"; + + default: +// LOGE("unknown socket error %d", anErrorNum); + return "unknown error"; + } +} + +static int convertError(int errorCode) { + switch (errorCode) { + case EBADF: + return SOCKERR_BADDESC; + case ENOBUFS: + return SOCKERR_NOBUFFERS; + case EOPNOTSUPP: + return SOCKERR_OPNOTSUPP; + case ENOPROTOOPT: + return SOCKERR_OPTUNSUPP; + case EINVAL: + return SOCKERR_SOCKLEVELINVALID; + case ENOTSOCK: + return SOCKERR_NOTSOCK; + case EINTR: + return SOCKERR_INTERRUPTED; + case ENOTCONN: + return SOCKERR_NOTCONNECTED; + case EAFNOSUPPORT: + return SOCKERR_BADAF; + /* note: CONNRESET not included because it has the same + * value as ECONNRESET and they both map to SOCKERR_CONNRESET */ + case ECONNRESET: + return SOCKERR_CONNRESET; + case EAGAIN: + return SOCKERR_WOULDBLOCK; + case EPROTONOSUPPORT: + return SOCKERR_BADPROTO; + case EFAULT: + return SOCKERR_ARGSINVALID; + case ETIMEDOUT: + return SOCKERR_TIMEOUT; + case ECONNREFUSED: + return SOCKERR_CONNECTION_REFUSED; + case ENETUNREACH: + return SOCKERR_ENETUNREACH; + case EACCES: + return SOCKERR_EACCES; + case EPIPE: + return SOCKERR_EPIPE; + case EHOSTUNREACH: + return SOCKERR_EHOSTUNREACH; + case EADDRINUSE: + return SOCKERR_ADDRINUSE; + case EADDRNOTAVAIL: + return SOCKERR_ADDRNOTAVAIL; + case EMSGSIZE: + return SOCKERR_MSGSIZE; + default: +// LOGE("unclassified errno %d (%s)", errorCode, strerror(errorCode)); + return SOCKERR_OPFAILED; + } +} + +static int sockSelect(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout) { + + int result = select(nfds, readfds, writefds, exceptfds, timeout); + + if (result < 0) { + if (errno == EINTR) { + result = SOCKERR_INTERRUPTED; + } else { + result = SOCKERR_OPFAILED; + } + } else if (result == 0) { + result = SOCKERR_TIMEOUT; + } + return result; +} + +#define SELECT_READ_TYPE 0 +#define SELECT_WRITE_TYPE 1 + +static int selectWait(int handle, int uSecTime, int type) { + fd_set fdset; + struct timeval time, *timePtr; + int result = 0; + int size = handle + 1; + + FD_ZERO(&fdset); + FD_SET(handle, &fdset); + + if (0 <= uSecTime) { + /* Use a timeout if uSecTime >= 0 */ + memset(&time, 0, sizeof(time)); + time.tv_usec = uSecTime; + timePtr = &time; + } else { + /* Infinite timeout if uSecTime < 0 */ + timePtr = NULL; + } + + if (type == SELECT_READ_TYPE) { + result = sockSelect(size, &fdset, NULL, NULL, timePtr); + } else { + result = sockSelect(size, NULL, &fdset, NULL, timePtr); + } + return result; +} + +static int pollSelectWait(JNIEnv *env, jobject fileDescriptor, int timeout, int type) { + /* now try reading the socket for the timespan timeout. + * if timeout is 0 try forever until the soclets gets ready or until an + * exception occurs. + */ + int pollTimeoutUSec = 100000, pollMsec = 100; + int finishTime = 0; + int timeLeft = timeout; + int hasTimeout = timeout > 0 ? 1 : 0; + int result = 0; + int handle; + + if (hasTimeout) { + finishTime = time_msec_clock() + timeout; + } + + int poll = 1; + + while (poll) { /* begin polling loop */ + + /* + * Fetch the handle every time in case the socket is closed. + */ + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_INTERRUPTED); + return -1; + } + + if (hasTimeout) { + + if (timeLeft - 10 < pollMsec) { + pollTimeoutUSec = timeLeft <= 0 ? 0 : (timeLeft * 1000); + } + + result = selectWait(handle, pollTimeoutUSec, type); + + /* + * because we are polling at a time smaller than timeout + * (presumably) lets treat an interrupt and timeout the same - go + * see if we're done timewise, and then just try again if not. + */ + if (SOCKERR_TIMEOUT == result || + SOCKERR_INTERRUPTED == result) { + + timeLeft = finishTime - time_msec_clock(); + + if (timeLeft <= 0) { + /* + * Always throw the "timeout" message because that is + * effectively what has happened, even if we happen to + * have been interrupted. + */ + jniThrowException(env, "java/net/SocketTimeoutException", + netLookupErrorString(SOCKERR_TIMEOUT)); + } else { + continue; // try again + } + + } else if (0 > result) { + log_socket_close(handle, result); + throwSocketException(env, result); + } + poll = 0; + + } else { /* polling with no timeout (why would you do this?)*/ + + result = selectWait(handle, pollTimeoutUSec, type); + + /* + * if interrupted (or a timeout) just retry + */ + if (SOCKERR_TIMEOUT == result || + SOCKERR_INTERRUPTED == result) { + + continue; // try again + } else if (0 > result) { + log_socket_close(handle, result); + throwSocketException(env, result); + } + poll = 0; + } + } /* end polling loop */ + + return result; +} + +/** + * A helper method, to set the connect context to a Long object. + * + * @param env pointer to the JNI library + * @param longclass Java Long Object + */ +void setConnectContext(JNIEnv *env,jobject longclass,jbyte * context) { + jclass descriptorCLS; + jfieldID descriptorFID; + descriptorCLS = env->FindClass("java/lang/Long"); + descriptorFID = env->GetFieldID(descriptorCLS, "value", "J"); + env->SetLongField(longclass, descriptorFID, (jlong)((jint)context)); +}; + +/** + * A helper method, to get the connect context. + * + * @param env pointer to the JNI library + * @param longclass Java Long Object + */ +jbyte *getConnectContext(JNIEnv *env, jobject longclass) { + jclass descriptorCLS; + jfieldID descriptorFID; + descriptorCLS = env->FindClass("java/lang/Long"); + descriptorFID = env->GetFieldID(descriptorCLS, "value", "J"); + return (jbyte*) ((jint)env->GetLongField(longclass, descriptorFID)); +}; + +// typical ip checksum +unsigned short ip_checksum(unsigned short* buffer, int size) { + register unsigned short * buf = buffer; + register int bufleft = size; + register unsigned long sum = 0; + + while (bufleft > 1) { + sum = sum + (*buf++); + bufleft = bufleft - sizeof(unsigned short ); + } + if (bufleft) { + sum = sum + (*(unsigned char*)buf); + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + + return (unsigned short )(~sum); +} + +/** + * Establish a connection to a peer with a timeout. This function is called + * repeatedly in order to carry out the connect and to allow other tasks to + * proceed on certain platforms. The caller must first call with + * step = SOCKET_STEP_START, if the result is SOCKERR_NOTCONNECTED it will then + * call it with step = CHECK until either another error or 0 is returned to + * indicate the connect is complete. Each time the function should sleep for no + * more than timeout milliseconds. If the connect succeeds or an error occurs, + * the caller must always end the process by calling the function with + * step = SOCKET_STEP_DONE + * + * @param[in] portLibrary The port library. + * @param[in] sock pointer to the unconnected local socket. + * @param[in] addr pointer to the sockaddr, specifying remote host/port. + * @param[in] timeout the timeout in milliseconds. If timeout is negative, + * perform a block operation. + * @param[in,out] pointer to context pointer. Filled in on first call and then + * to be passed into each subsequent call. + * + * @return 0, if no errors occurred, otherwise the (negative) error code. + */ +static int sockConnectWithTimeout(int handle, struct sockaddr_in addr, + unsigned int timeout, unsigned int step, jbyte *ctxt) { + int rc = 0; + struct timeval passedTimeout; + int errorVal; + socklen_t errorValLen = sizeof(int); + struct selectFDSet *context = NULL; + + if (SOCKET_STEP_START == step) { + + context = (struct selectFDSet *) ctxt; + + context->sock = handle; + context->nfds = handle + 1; + + if (useAdbNetworking && !isLocalhost(&addr)) { + + // LOGD("+connect to address 0x%08x (via adb)", + // addr.sin_addr.s_addr); + rc = adb_networking_connect_fd(handle, &addr); + // LOGD("-connect ret %d errno %d (via adb)", rc, errno); + + } else { + log_socket_connect(handle, ntohl(addr.sin_addr.s_addr), + ntohs(addr.sin_port)); + /* set the socket to non-blocking */ + int block = JNI_TRUE; + rc = ioctl(handle, FIONBIO, &block); + if (0 != rc) { + return convertError(rc); + } + + // LOGD("+connect to address 0x%08x (via normal) on handle %d", + // addr.sin_addr.s_addr, handle); + do { + rc = connect(handle, (struct sockaddr *) &addr, + sizeof(struct sockaddr)); + } while (rc < 0 && errno == EINTR); + // LOGD("-connect to address 0x%08x (via normal) returned %d", + // addr.sin_addr.s_addr, (int) rc); + + } + + if (rc == -1) { + rc = errno; + switch (rc) { + case EINTR: + return SOCKERR_ALREADYBOUND; + case EAGAIN: + case EINPROGRESS: + return SOCKERR_NOTCONNECTED; + default: + return convertError(rc); + } + } + + /* we connected right off the bat so just return */ + return rc; + + } else if (SOCKET_STEP_CHECK == step) { + /* now check if we have connected yet */ + + context = (struct selectFDSet *) ctxt; + + /* + * set the timeout value to be used. Because on some unix platforms we + * don't get notified when a socket is closed we only sleep for 100ms + * at a time + */ + passedTimeout.tv_sec = 0; + if (timeout > 100) { + passedTimeout.tv_usec = 100 * 1000; + } else if ((int)timeout >= 0) { + passedTimeout.tv_usec = timeout * 1000; + } + + /* initialize the FD sets for the select */ + FD_ZERO(&(context->exceptionSet)); + FD_ZERO(&(context->writeSet)); + FD_ZERO(&(context->readSet)); + FD_SET(context->sock, &(context->writeSet)); + FD_SET(context->sock, &(context->readSet)); + FD_SET(context->sock, &(context->exceptionSet)); + + rc = select(context->nfds, + &(context->readSet), + &(context->writeSet), + &(context->exceptionSet), + (int)timeout >= 0 ? &passedTimeout : NULL); + + /* if there is at least one descriptor ready to be checked */ + if (0 < rc) { + /* if the descriptor is in the write set we connected or failed */ + if (FD_ISSET(context->sock, &(context->writeSet))) { + + if (!FD_ISSET(context->sock, &(context->readSet))) { + /* ok we have connected ok */ + return 0; + } else { + /* ok we have more work to do to figure it out */ + if (getsockopt(context->sock, SOL_SOCKET, SO_ERROR, + &errorVal, &errorValLen) >= 0) { + return errorVal ? convertError(errorVal) : 0; + } else { + return convertError(errno); + } + } + } + + /* if the descriptor is in the exception set the connect failed */ + if (FD_ISSET(context->sock, &(context->exceptionSet))) { + if (getsockopt(context->sock, SOL_SOCKET, SO_ERROR, &errorVal, + &errorValLen) >= 0) { + return errorVal ? convertError(errorVal) : 0; + } + rc = errno; + return convertError(rc); + } + + } else if (rc < 0) { + /* something went wrong with the select call */ + rc = errno; + + /* if it was EINTR we can just try again. Return not connected */ + if (EINTR == rc) { + return SOCKERR_NOTCONNECTED; + } + + /* some other error occured so look it up and return */ + return convertError(rc); + } + + /* + * if we get here the timeout expired or the connect had not yet + * completed just indicate that the connect is not yet complete + */ + return SOCKERR_NOTCONNECTED; + } else if (SOCKET_STEP_DONE == step) { + /* we are done the connect or an error occured so clean up */ + if (handle != -1) { + int block = JNI_FALSE; + ioctl(handle, FIONBIO, &block); + } + return 0; + } + return SOCKERR_ARGSINVALID; +} + +/** + * Join/Leave the nominated multicast group on the specified socket. + * Implemented by setting the multicast 'add membership'/'drop membership' + * option at the HY_IPPROTO_IP level on the socket. + * + * Implementation note for multicast sockets in general: + * + * - This code is untested, because at the time of this writing multicast can't + * be properly tested on Android due to GSM routing restrictions. So it might + * or might not work. + * + * - The REUSEPORT socket option that Harmony employs is not supported on Linux + * and thus also not supported on Android. It's is not needed for multicast + * to work anyway (REUSEADDR should suffice). + * + * @param env pointer to the JNI library. + * @param socketP pointer to the hysocket to join/leave on. + * @param optVal pointer to the InetAddress, the multicast group to join/drop. + * + * @exception SocketException if an error occurs during the call + */ +static void mcastAddDropMembership (JNIEnv * env, int handle, jobject optVal, + int ignoreIF, int setSockOptVal) { + int result; + struct ip_mreq ipmreqP; + struct sockaddr_in sockaddrP; + int length = sizeof(struct ip_mreq); + socklen_t lengthIF = sizeof(struct sockaddr_in); + + /* + * JNI objects needed to access the information in the optVal oject + * passed in. The object passed in is a GenericIPMreq object + */ + jclass cls; + jfieldID multiaddrID; + jfieldID interfaceAddrID; + jobject multiaddr; + jobject interfaceAddr; + + /* + * check whether we are getting an InetAddress or an Generic IPMreq, for now + * we support both so that we will not break the tests + */ + if (env->IsInstanceOf (optVal, gCachedFields.iaddr_class)) { + + ipmreqP.imr_interface.s_addr = htonl(INADDR_ANY); + if (!ignoreIF) { + + result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF, &sockaddrP, + &lengthIF); + + if (0 != result) { + throwSocketException (env, convertError(errno)); + return; + } + + memcpy(&(ipmreqP.imr_interface.s_addr), &(sockaddrP.sin_addr), 4); + } + + result = inetAddressToSocketAddress(env, optVal, 0, &sockaddrP); + + if (result < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + memcpy(&(ipmreqP.imr_multiaddr.s_addr), &(sockaddrP.sin_addr), 4); + + result = setsockopt(handle, IPPROTO_IP, setSockOptVal, &ipmreqP, length); + if (0 != result) { + throwSocketException (env, convertError(errno)); + return; + } + + } else { + + /* we need the multicast address regardless of the type of address */ + cls = env->GetObjectClass(optVal); + multiaddrID = env->GetFieldID(cls, "multiaddr", "Ljava/net/InetAddress;"); + multiaddr = env->GetObjectField(optVal, multiaddrID); + + result = inetAddressToSocketAddress(env, multiaddr, 0, &sockaddrP); + + if (result < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + memcpy(&(ipmreqP.imr_multiaddr.s_addr), &(sockaddrP.sin_addr), 4); + + /* we need to use an IP_MREQ as it is an IPV4 address */ + interfaceAddrID = env->GetFieldID(cls, "interfaceAddr", + "Ljava/net/InetAddress;"); + interfaceAddr = env->GetObjectField(optVal, interfaceAddrID); + + ipmreqP.imr_interface.s_addr = htonl(INADDR_ANY); + + /* + * if an interfaceAddr was passed then use that value, otherwise set the + * interface to all 0 to indicate the system should select the interface + * used + */ + if (!ignoreIF) { + if (NULL != interfaceAddr) { + + result = inetAddressToSocketAddress(env, interfaceAddr, 0, + &sockaddrP); + + if (result < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + memcpy(&(ipmreqP.imr_interface.s_addr), &(sockaddrP.sin_addr), 4); + + } + } + + /* join/drop the multicast address */ + result = setsockopt(handle, IPPROTO_IP, setSockOptVal, &ipmreqP, length); + if (0 != result) { + throwSocketException (env, convertError(errno)); + return; + } + } +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_oneTimeInitializationImpl(JNIEnv* env, jobject obj, + jboolean jcl_supports_ipv6) { + // LOGD("ENTER oneTimeInitializationImpl of OSNetworkSystem"); + + char useAdbNetworkingProperty[PROPERTY_VALUE_MAX]; + char adbConnectedProperty[PROPERTY_VALUE_MAX]; + + property_get("android.net.use-adb-networking", useAdbNetworkingProperty, ""); + property_get("adb.connected", adbConnectedProperty, ""); + + if (strlen((char *)useAdbNetworkingProperty) > 0 + && strlen((char *)adbConnectedProperty) > 0) { + useAdbNetworking = 1; + } + + memset(&gCachedFields, 0, sizeof(gCachedFields)); + + // initializing InetAddress + + jclass iaddrclass = env->FindClass("java/net/InetAddress"); + + if (iaddrclass == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.net.InetAddress"); + return; + } + + gCachedFields.iaddr_class = (jclass) env->NewGlobalRef(iaddrclass); + + jmethodID iaddrclassinit = env->GetMethodID(iaddrclass, "", "()V"); + + if (iaddrclassinit == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", "InetAddress.()"); + return; + } + + gCachedFields.iaddr_class_init = iaddrclassinit; + + jmethodID iaddrgetbyaddress = env->GetStaticMethodID(iaddrclass, + "getByAddress", "([B)Ljava/net/InetAddress;"); + + if (iaddrgetbyaddress == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", + "InetAddress.getByAddress(byte[] val)"); + return; + } + + gCachedFields.iaddr_getbyaddress = iaddrgetbyaddress; + + jmethodID iaddrgetaddress = env->GetStaticMethodID(iaddrclass, + "getByAddress", "([B)Ljava/net/InetAddress;"); + + + + + jfieldID iaddripaddress = env->GetFieldID(iaddrclass, "ipaddress", "[B"); + + if (iaddripaddress == NULL) { + jniThrowException(env, "java/lang/NoSuchFieldError", + "Can't find field InetAddress.ipaddress"); + return; + } + + gCachedFields.iaddr_ipaddress = iaddripaddress; + + // get the GenericIPMreq class + + jclass genericipmreqclass = env->FindClass("org/apache/harmony/luni/net/GenericIPMreq"); + + if (genericipmreqclass == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "org.apache.harmony.luni.net.GenericIPMreq"); + return; + } + + gCachedFields.genericipmreq_class = (jclass) env->NewGlobalRef(genericipmreqclass); + + // initializing Integer + + jclass integerclass = env->FindClass("java/lang/Integer"); + + if (integerclass == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.lang.Integer"); + return; + } + + jmethodID integerclassinit = env->GetMethodID(integerclass, "", "(I)V"); + + if (integerclassinit == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", + "Integer.(int val)"); + return; + } + + jfieldID integerclassvalue = env->GetFieldID(integerclass, "value", "I"); + + if (integerclassvalue == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", "Integer.value"); + return; + } + + gCachedFields.integer_class = (jclass) env->NewGlobalRef(integerclass); + gCachedFields.integer_class_init = integerclassinit; + gCachedFields.integer_class_value = integerclassvalue; + + // initializing Boolean + + jclass booleanclass = env->FindClass("java/lang/Boolean"); + + if (booleanclass == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.lang.Boolean"); + return; + } + + jmethodID booleanclassinit = env->GetMethodID(booleanclass, "", "(Z)V"); + + if (booleanclassinit == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", + "Boolean.(boolean val)"); + return; + } + + jfieldID booleanclassvalue = env->GetFieldID(booleanclass, "value", "Z"); + + if (booleanclassvalue == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", "Boolean.value"); + return; + } + + gCachedFields.boolean_class = (jclass) env->NewGlobalRef(booleanclass); + gCachedFields.boolean_class_init = booleanclassinit; + gCachedFields.boolean_class_value = booleanclassvalue; + + // initializing Byte + + jclass byteclass = env->FindClass("java/lang/Byte"); + + if (byteclass == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.lang.Byte"); + return; + } + + jmethodID byteclassinit = env->GetMethodID(byteclass, "", "(B)V"); + + if (byteclassinit == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", + "Byte.(byte val)"); + return; + } + + jfieldID byteclassvalue = env->GetFieldID(byteclass, "value", "B"); + + if (byteclassvalue == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", "Byte.value"); + return; + } + + gCachedFields.byte_class = (jclass) env->NewGlobalRef(byteclass); + gCachedFields.byte_class_init = byteclassinit; + gCachedFields.byte_class_value = byteclassvalue; + + // initializing String + + jclass stringclass = env->FindClass("java/lang/String"); + + if (stringclass == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.lang.String"); + return; + } + + jmethodID stringclassinit = env->GetMethodID(stringclass, "", "([B)V"); + + if (stringclassinit == NULL) { + jniThrowException(env, "java/lang/NoSuchMethodError", + "String.(byte[] val)"); + return; + } + + gCachedFields.string_class = (jclass) env->NewGlobalRef(stringclass); + gCachedFields.string_class_init = stringclassinit; + + // initializing ScoketImpl + + jclass socketimplclass = env->FindClass("java/net/SocketImpl"); + + if (socketimplclass == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.net.SocketImpl"); + return; + } + + jfieldID socketimplport = env->GetFieldID(socketimplclass, "port", "I"); + + if (socketimplport == NULL) { + jniThrowException(env, "java/lang/NoSuchFieldError", "SocketImpl.port"); + return; + } + + jfieldID socketimpladdress = env->GetFieldID(socketimplclass, "address", + "Ljava/net/InetAddress;"); + + if (socketimpladdress == NULL) { + jniThrowException(env, "java/lang/NoSuchFieldError", + "SocketImpl.address"); + return; + } + + gCachedFields.socketimpl_address = socketimpladdress; + gCachedFields.socketimpl_port = socketimplport; + + gCachedFields.dpack_class = env->FindClass("java/net/DatagramPacket"); + if (gCachedFields.dpack_class == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.net.DatagramPacket"); + return; + } + + gCachedFields.dpack_address = env->GetFieldID(gCachedFields.dpack_class, + "address", "Ljava/net/InetAddress;"); + if (gCachedFields.dpack_address == NULL) { + jniThrowException(env, "java/lang/NoSuchFieldError", + "DatagramPacket.address"); + return; + } + + gCachedFields.dpack_port = env->GetFieldID(gCachedFields.dpack_class, + "port", "I"); + if (gCachedFields.dpack_port == NULL) { + jniThrowException(env, "java/lang/NoSuchFieldError", + "DatagramPacket.port"); + return; + } + + gCachedFields.dpack_length = env->GetFieldID(gCachedFields.dpack_class, + "length", "I"); + if (gCachedFields.dpack_length == NULL) { + jniThrowException(env, "java/lang/NoSuchFieldError", + "DatagramPacket.length"); + return; + } + + gCachedFields.fd_class = env->FindClass("java/io/FileDescriptor"); + if (gCachedFields.fd_class == NULL) { + jniThrowException(env, "java/lang/ClassNotFoundException", + "java.io.FileDescriptor"); + return; + } + gCachedFields.descriptor = env->GetFieldID(gCachedFields.fd_class, "descriptor", "I"); + if (gCachedFields.descriptor == NULL) { + jniThrowException(env, "java/lang/NoSuchFieldError", + "FileDescriptor.descriptor"); + return; + } + +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createSocketImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jboolean preferIPv4Stack) { + // LOGD("ENTER createSocketImpl"); + + int ret = socket(PF_INET, SOCK_STREAM, 0); + + if (ret < 0) { + int err = convertError(errno); + throwSocketException(env, err); + return; + } + + jniSetFileDescriptorOfFD(env, fileDescriptor, ret); + + return; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createDatagramSocketImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jboolean preferIPv4Stack) { + // LOGD("ENTER createDatagramSocketImpl"); + + int ret = socket(PF_INET, SOCK_DGRAM, 0); + + if (ret < 0) { + int err = convertError(errno); + throwSocketException(env, err); + return; + } + + jniSetFileDescriptorOfFD(env, fileDescriptor, ret); + + return; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_readSocketDirectImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint address, jint offset, jint count, + jint timeout) { + // LOGD("ENTER readSocketDirectImpl"); + + int handle; + jbyte *message = (jbyte *)address; + int result, ret, localCount; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + result = selectWait(handle, timeout, SELECT_READ_TYPE); + + if (0 > result) { + return 0; + } + + localCount = (count < 65536) ? count : 65536; + + do { + ret = recv(handle, (jbyte *) message, localCount, SOCKET_NOFLAGS); + } while (ret < 0 && errno == EINTR); + + if (0 == ret) { + return -1; + } else if (ret == -1) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return 0; + } + add_recv_stats(handle, ret); + return ret; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_readSocketImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jbyteArray data, jint offset, jint count, + jint timeout) { + // LOGD("ENTER readSocketImpl"); + + jbyte *message; + int result, localCount; + + jbyte internalBuffer[BUFFERSIZE]; + + localCount = (count < 65536) ? count : 65536; + + if (localCount > BUFFERSIZE) { + message = (jbyte*)malloc(localCount * sizeof(jbyte)); + if (message == NULL) { + jniThrowException(env, "java/lang/OutOfMemoryError", + "couldn't allocate enough memory for readSocket"); + return 0; + } + } else { + message = (jbyte *)internalBuffer; + } + + result = Java_org_sipdroid_net_impl_OSNetworkSystem_readSocketDirectImpl(env, clazz, fileDescriptor, + (jint) message, offset, count, timeout); + + if (result > 0) { + env->SetByteArrayRegion(data, offset, result, (jbyte *)message); + } + + if (((jbyte *)message) != internalBuffer) { + free(( jbyte *)message); + } + + return result; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_writeSocketDirectImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint address, jint offset, jint count) { + // LOGD("ENTER writeSocketDirectImpl"); + + int handle; + jbyte *message = (jbyte *)address; + int result = 0, sent = 0; + + if (count <= 0) { + return 0; + } + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + result = send(handle, (jbyte *) message, (int) count, SOCKET_NOFLAGS); + if (result < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + + if (SOCKERR_WOULDBLOCK == err){ + jclass socketExClass,errorCodeExClass; + jmethodID errorCodeExConstructor, socketExConstructor,socketExCauseMethod; + jobject errorCodeEx, socketEx; + const char* errorMessage = netLookupErrorString(err); + jstring errorMessageString = env->NewStringUTF(errorMessage); + + errorCodeExClass = env->FindClass("org/apache/harmony/luni/util/ErrorCodeException"); + if (!errorCodeExClass){ + return 0; + } + errorCodeExConstructor = env->GetMethodID(errorCodeExClass,"","(I)V"); + if (!errorCodeExConstructor){ + return 0; + } + errorCodeEx = env->NewObject(errorCodeExClass,errorCodeExConstructor,err); + + socketExClass = env->FindClass("java/net/SocketException"); + if (!socketExClass) { + return 0; + } + socketExConstructor = env->GetMethodID(socketExClass,"","(Ljava/lang/String;)V"); + if (!socketExConstructor) { + return 0; + } + socketEx = env->NewObject(socketExClass, socketExConstructor, errorMessageString); + socketExCauseMethod = env->GetMethodID(socketExClass,"initCause","(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); + env->CallObjectMethod(socketEx,socketExCauseMethod,errorCodeEx); + env->Throw((jthrowable)socketEx); + return 0; + } + throwSocketException(env, err); + return 0; + } + + add_send_stats(handle, result); + return result; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_writeSocketImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jbyteArray data, jint offset, jint count) { + // LOGD("ENTER writeSocketImpl"); + + jbyte *message; + int sent = 0; + jint result = 0; + +/* TODO: ARRAY PINNING */ +#define INTERNAL_SEND_BUFFER_MAX 512 + jbyte internalBuffer[INTERNAL_SEND_BUFFER_MAX]; + + if (count > INTERNAL_SEND_BUFFER_MAX) { + message = (jbyte*)malloc(count * sizeof( jbyte)); + if (message == NULL) { + jniThrowException(env, "java/lang/OutOfMemoryError", + "couldn't allocate enough memory for writeSocket"); + return 0; + } + } else { + message = (jbyte *)internalBuffer; + } + + env->GetByteArrayRegion(data, offset, count, message); + + result = Java_org_sipdroid_net_impl_OSNetworkSystem_writeSocketDirectImpl(env, clazz, fileDescriptor, + (jint) message, offset, count); + + if (( jbyte *)message != internalBuffer) { + free(( jbyte *)message); + } +#undef INTERNAL_SEND_BUFFER_MAX + return result; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_setNonBlockingImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jboolean nonblocking) { + // LOGD("ENTER setNonBlockingImpl"); + + int handle; + int result; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + int block = nonblocking; + + result = ioctl(handle, FIONBIO, &block); + + if (result == -1) { + throwSocketException(env, convertError(errno)); + } +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint trafficClass, jobject inetAddr, jint port); + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_connectWithTimeoutSocketImpl(JNIEnv* env, + jclass clazz, jobject fileDescriptor, jint timeout, jint trafficClass, + jobject inetAddr, jint port, jint step, jbyteArray passContext) { + // LOGD("ENTER connectWithTimeoutSocketImpl"); + + int handle; + int result = 0; + struct sockaddr_in address; + jbyte *context = NULL; + + memset(&address, 0, sizeof(address)); + + address.sin_family = AF_INET; + + result = inetAddressToSocketAddress(env, inetAddr, port, + (struct sockaddr_in *) &address); + + if (result < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return result; + } + + // Check if we're using adb networking and redirect in case it is used. + if (useAdbNetworking && !isLocalhost(&address)) { + return Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(env, clazz, fileDescriptor, + trafficClass, inetAddr, port); + } + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return -1; + } + + address.sin_port = htons(port); + + context = (jbyte *)env->GetPrimitiveArrayCritical(passContext, NULL); + + switch (step) { + case SOCKET_CONNECT_STEP_START: + result = sockConnectWithTimeout(handle, address, 0, + SOCKET_STEP_START, context); + break; + case SOCKET_CONNECT_STEP_CHECK: + result = sockConnectWithTimeout(handle, address, timeout, + SOCKET_STEP_CHECK, context); + break; + } + + env->ReleasePrimitiveArrayCritical(passContext, context, JNI_ABORT); + + if (0 == result) { + /* connected , so stop here */ + sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, NULL); + } else if (result != SOCKERR_NOTCONNECTED) { + /* can not connect... */ + sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, NULL); + if (result == SOCKERR_EACCES) { + jniThrowException(env, "java/lang/SecurityException", + netLookupErrorString(result)); + } else { + jniThrowException(env, "java/net/ConnectException", + netLookupErrorString(result)); + } + } + + return result; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_connectStreamWithTimeoutSocketImpl(JNIEnv* env, + jclass clazz, jobject fileDescriptor, jint remotePort, jint timeout, + jint trafficClass, jobject inetAddr) { + // LOGD("ENTER connectStreamWithTimeoutSocketImpl"); + + int result = 0; + int handle; + struct sockaddr_in address; + jbyte *context = NULL; + int remainingTimeout = timeout; + int passedTimeout = 0; + int finishTime = 0; + int blocking = 0; + char hasTimeout = timeout > 0; + + /* if a timeout was specified calculate the finish time value */ + if (hasTimeout) { + finishTime = time_msec_clock() + (int) timeout; + } + + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } else { + result = inetAddressToSocketAddress(env, inetAddr, remotePort, + (struct sockaddr_in *) &address); + + if (result < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + // Check if we're using adb networking and redirect in case it is used. + if (useAdbNetworking && !isLocalhost(&address)) { + int retVal = Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(env, clazz, + fileDescriptor, trafficClass, inetAddr, remotePort); + if (retVal != 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + } + return; + } + + /* + * we will be looping checking for when we are connected so allocate + * the descriptor sets that we will use + */ + context =(jbyte *) malloc(sizeof(struct selectFDSet)); + + if (NULL == context) { + throwSocketException(env, SOCKERR_NOBUFFERS); + return; + } + + result = sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_START, context); + if (0 == result) { + /* ok we connected right away so we are done */ + sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, context); + goto bail; + } else if (result != SOCKERR_NOTCONNECTED) { + log_socket_close(handle, result); + sockConnectWithTimeout(handle, address, 0, SOCKET_STEP_DONE, + context); + /* we got an error other than NOTCONNECTED so we cannot continue */ + if (SOCKERR_EACCES == result) { + jniThrowException(env, "java/lang/SecurityException", + netLookupErrorString(result)); + } else { + throwSocketException(env, result); + } + goto bail; + } + + while (SOCKERR_NOTCONNECTED == result) { + passedTimeout = remainingTimeout; + + /* + * ok now try and connect. Depending on the platform this may sleep + * for up to passedTimeout milliseconds + */ + result = sockConnectWithTimeout(handle, address, passedTimeout, + SOCKET_STEP_CHECK, context); + + /* + * now check if the socket is still connected. + * Do it here as some platforms seem to think they + * are connected if the socket is closed on them. + */ + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + sockConnectWithTimeout(handle, address, 0, + SOCKET_STEP_DONE, context); + throwSocketException(env, SOCKERR_BADSOCKET); + goto bail; + } + + /* + * check if we are now connected, + * if so we can finish the process and return + */ + if (0 == result) { + sockConnectWithTimeout(handle, address, 0, + SOCKET_STEP_DONE, context); + goto bail; + } + + /* + * if the error is SOCKERR_NOTCONNECTED then we have not yet + * connected and we may not be done yet + */ + if (SOCKERR_NOTCONNECTED == result) { + /* check if the timeout has expired */ + if (hasTimeout) { + remainingTimeout = finishTime - time_msec_clock(); + if (remainingTimeout <= 0) { + log_socket_close(handle, result); + sockConnectWithTimeout(handle, address, 0, + SOCKET_STEP_DONE, context); + jniThrowException(env, + "java/net/SocketTimeoutException", + netLookupErrorString(result)); + goto bail; + } + } else { + remainingTimeout = 100; + } + } else { + log_socket_close(handle, result); + sockConnectWithTimeout(handle, address, remainingTimeout, + SOCKET_STEP_DONE, context); + if ((SOCKERR_CONNRESET == result) || + (SOCKERR_CONNECTION_REFUSED == result) || + (SOCKERR_ADDRNOTAVAIL == result) || + (SOCKERR_ADDRINUSE == result) || + (SOCKERR_ENETUNREACH == result)) { + jniThrowException(env, "java/net/ConnectException", + netLookupErrorString(result)); + } else if (SOCKERR_EACCES == result) { + jniThrowException(env, "java/lang/SecurityException", + netLookupErrorString(result)); + } else { + throwSocketException(env, result); + } + goto bail; + } + } + } + +bail: + + /* free the memory for the FD set */ + if (context != NULL) { + free(context); + } +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_connectSocketImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint trafficClass, jobject inetAddr, jint port) { + //LOGD("ENTER direct-call connectSocketImpl\n"); + + struct sockaddr_in address; + int ret; + int handle; + jbyteArray java_in_addr; + + memset(&address, 0, sizeof(address)); + + address.sin_family = AF_INET; + + ret = inetAddressToSocketAddress(env, inetAddr, port, + (struct sockaddr_in *) &address); + + if (ret < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return ret; + } + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return -1; + } + + address.sin_port = htons(port); + + if (useAdbNetworking && !isLocalhost(&address)) { + + // LOGD("+connect to address 0x%08x port %d (via adb)", + // address.sin_addr.s_addr, (int) port); + ret = adb_networking_connect_fd(handle, &address); + // LOGD("-connect ret %d errno %d (via adb)", ret, errno); + + } else { + + // call this method with a timeout of zero + Java_org_sipdroid_net_impl_OSNetworkSystem_connectStreamWithTimeoutSocketImpl(env, clazz, + fileDescriptor, port, 0, trafficClass, inetAddr); + if (env->ExceptionOccurred() != 0) { + return -1; + } else { + return 0; + } + + } + + if (ret < 0) { + jniThrowException(env, "java/net/ConnectException", + netLookupErrorString(convertError(errno))); + return ret; + } + + return ret; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_socketBindImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint port, jobject inetAddress) { + // LOGD("ENTER socketBindImpl"); + + struct sockaddr_in sockaddress; + int ret; + int handle; + + ret = inetAddressToSocketAddress(env, inetAddress, port, + (struct sockaddr_in *) &sockaddress); + + if (ret < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + ret = bind(handle, (const sockaddr*)&sockaddress, sizeof(sockaddress)); + + if (ret < 0) { + jniThrowException(env, "java/net/BindException", + netLookupErrorString(convertError(errno))); + return; + } +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_listenStreamSocketImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint backlog) { + // LOGD("ENTER listenStreamSocketImpl"); + + int ret; + int handle; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + ret = listen(handle, backlog); + + if (ret < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return; + } +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_availableStreamImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor) { + // LOGD("ENTER availableStreamImpl"); + + int handle; + char message[BUFFERSIZE]; + + int result; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + do { + result = selectWait(handle, 1, SELECT_READ_TYPE); + + if (SOCKERR_TIMEOUT == result) { + // The read operation timed out, so answer 0 bytes available + return 0; + } else if (SOCKERR_INTERRUPTED == result) { + continue; + } else if (0 > result) { + log_socket_close(handle, result); + throwSocketException(env, result); + return 0; + } + } while (SOCKERR_INTERRUPTED == result); + + result = recv(handle, (jbyte *) message, BUFFERSIZE, MSG_PEEK); + + if (0 > result) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return 0; + } + add_recv_stats(handle, result); + return result; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass clazz, + jobject fdServer, jobject newSocket, jobject fdnewSocket, jint timeout) { + // LOGD("ENTER acceptSocketImpl"); + + union { + struct sockaddr address; + struct sockaddr_in in_address; + } sa; + + int ret; + int retFD; + int result; + int handle; + socklen_t addrlen; + + if (newSocket == NULL) { + throwNullPointerException(env); + return; + } + + result = pollSelectWait(env, fdServer, timeout, SELECT_READ_TYPE); + + if (0 > result) { + return; + } + + handle = jniGetFDFromFileDescriptor(env, fdServer); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + do { + addrlen = sizeof(sa); + ret = accept(handle, &(sa.address), &addrlen); + } while (ret < 0 && errno == EINTR); + + if (ret < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return; + } + + retFD = ret; + + /* For AF_INET / inetOrLocal == true only: put + * peer address and port in instance variables + * We don't bother for UNIX domain sockets, since most peers are + * anonymous anyway + */ + if (sa.address.sa_family == AF_INET) { + // inetOrLocal should also be true + + jobject inetAddress; + + inetAddress = structInToInetAddress(env, &(sa.in_address.sin_addr)); + + if (inetAddress == NULL) { + close(retFD); + newSocket = NULL; + return; + } + + env->SetObjectField(newSocket, + gCachedFields.socketimpl_address, inetAddress); + + env->SetIntField(newSocket, gCachedFields.socketimpl_port, + ntohs(sa.in_address.sin_port)); + } + + jniSetFileDescriptorOfFD(env, fdnewSocket, retFD); +} + +extern "C" jboolean Java_org_sipdroid_net_impl_OSNetworkSystem_supportsUrgentDataImpl(JNIEnv* env, + jclass clazz, jobject fileDescriptor) { + // LOGD("ENTER supportsUrgentDataImpl"); + + int handle; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + if (handle == 0 || handle == -1) { + return JNI_FALSE; + } + + return JNI_TRUE; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_sendUrgentDataImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jbyte value) { + // LOGD("ENTER sendUrgentDataImpl"); + + int handle; + int result; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + result = send(handle, (jbyte *) &value, 1, MSG_OOB); + if (result < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + } +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass clazz, + jobject fd, jint port, jint trafficClass, jobject inetAddress) { + // LOGD("ENTER connectDatagramImpl2"); + + int handle = jniGetFDFromFileDescriptor(env, fd); + + struct sockaddr_in sockAddr; + int ret; + + ret = inetAddressToSocketAddress(env, inetAddress, port, &sockAddr); + + if (ret < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + log_socket_connect(handle, ntohl(sockAddr.sin_addr.s_addr), port); + int result = connect(handle, (struct sockaddr *)&sockAddr, sizeof(sockAddr)); + if (result < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + } +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass clazz, + jobject fd) { + // LOGD("ENTER disconnectDatagramImpl"); + + int handle = jniGetFDFromFileDescriptor(env, fd); + + struct sockaddr_in *sockAddr; + socklen_t sockAddrLen = sizeof(struct sockaddr_in); + sockAddr = (struct sockaddr_in *) malloc(sockAddrLen); + memset(sockAddr, 0, sockAddrLen); + + sockAddr->sin_family = AF_UNSPEC; + int result = connect(handle, (struct sockaddr *)sockAddr, sockAddrLen); + free(sockAddr); + + if (result < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + } +} + +extern "C" jboolean Java_org_sipdroid_net_impl_OSNetworkSystem_socketBindImpl2(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint port, jboolean bindToDevice, + jobject inetAddress) { + // LOGD("ENTER socketBindImpl2"); + + struct sockaddr_in sockaddress; + int ret; + int handle; + + ret = inetAddressToSocketAddress(env, inetAddress, port, + (struct sockaddr_in *) &sockaddress); + + if (ret < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + ret = bind(handle, (const sockaddr*)&sockaddress, sizeof(sockaddress)); + + if (ret < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + jniThrowException(env, "java/net/BindException", netLookupErrorString(err)); + return 0; + } + + return 0; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz, + jobject fd, jobject sender, jint receiveTimeout) { + // LOGD("ENTER peekDatagramImpl"); + + int port = -1; + + int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE); + if (0> result) { + return (jint) 0; + } + + int handle = jniGetFDFromFileDescriptor(env, fd); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + struct sockaddr_in sockAddr; + socklen_t sockAddrLen = sizeof(sockAddr); + + int length = recvfrom(handle, NULL, 0, MSG_PEEK, + (struct sockaddr *)&sockAddr, &sockAddrLen); + + if (length < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return 0; + } + + if (socketAddressToInetAddress(env, &sockAddr, sender, &port) < 0) { + throwIOExceptionStr(env, "Address conversion failed"); + return -1; + } + add_recv_stats(handle, length); + return port; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_receiveDatagramDirectImpl(JNIEnv* env, jclass clazz, + jobject fd, jobject packet, jint address, jint offset, jint length, + jint receiveTimeout, jboolean peek) { + // LOGD("ENTER receiveDatagramDirectImpl"); + + int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE); + if (0 > result) { + return (jint) 0; + } + + int handle = jniGetFDFromFileDescriptor(env, fd); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + struct sockaddr_in sockAddr; + socklen_t sockAddrLen = sizeof(sockAddr); + + int mode = peek ? MSG_PEEK : 0; + + int actualLength = recvfrom(handle, (char*)(address + offset), length, mode, + (struct sockaddr *)&sockAddr, &sockAddrLen); + + if (actualLength < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return 0; + } + + if (packet != NULL) { + int port = ntohs(sockAddr.sin_port); + jobject sender = env->GetObjectField(packet, gCachedFields.dpack_address); + //__android_log_print(ANDROID_LOG_INFO,"OSNetwork","Sender address %x ", sender); + if (sender != 0) { + jbyteArray addr = (jbyteArray)env->GetObjectField(sender, gCachedFields.iaddr_ipaddress); + //__android_log_print(ANDROID_LOG_INFO,"OSNetwork","Sender Recup"); + if ((structInToJavaAddress(env, &sockAddr.sin_addr, addr)) < 0) { + jniThrowException(env, "java/net/SocketException", + "Could not set address of packet."); + return 0; + } + } + else { + jbyteArray addr = env->NewByteArray(sizeof(struct in_addr)); + if ((structInToJavaAddress(env, &sockAddr.sin_addr, addr)) < 0) { + jniThrowException(env, "java/net/SocketException", + "Could not set address of packet."); + return 0; + } + sender = env->CallStaticObjectMethod( + gCachedFields.iaddr_class, gCachedFields.iaddr_getbyaddress, + addr); + + } + env->SetObjectField(packet, gCachedFields.dpack_address, sender); + env->SetIntField(packet, gCachedFields.dpack_port, port); + env->SetIntField(packet, gCachedFields.dpack_length, actualLength); + } + add_recv_stats(handle, actualLength); + return actualLength; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_receiveDatagramImpl(JNIEnv* env, jclass clazz, + jobject fd, jobject packet, jbyteArray data, jint offset, jint length, + jint receiveTimeout, jboolean peek) { + // LOGD("ENTER receiveDatagramImpl"); + + int localLength = (length < 65536) ? length : 65536; + jbyte *bytes = (jbyte*) malloc(localLength); + if (bytes == NULL) { + jniThrowException(env, "java/lang/OutOfMemoryError", + "couldn't allocate enough memory for receiveDatagram"); + return 0; + } + + int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_receiveDatagramDirectImpl(env, clazz, fd, + packet, (jint)bytes, offset, localLength, receiveTimeout, peek); + + if (actualLength > 0) { + env->SetByteArrayRegion(data, offset, actualLength, bytes); + } + free(bytes); + + return actualLength; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv* env, + jclass clazz, jobject fd, jobject packet, jint address, jint offset, + jint length, jint receiveTimeout, jboolean peek) { + // LOGD("ENTER receiveConnectedDatagramDirectImpl"); + + int result = pollSelectWait (env, fd, receiveTimeout, SELECT_READ_TYPE); + + if (0 > result) { + return 0; + } + + int handle = jniGetFDFromFileDescriptor(env, fd); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + int mode = peek ? MSG_PEEK : 0; + + int actualLength = recvfrom(handle, + (char*)(address + offset), length, mode, NULL, NULL); + + if (actualLength < 0) { + jniThrowException(env, "java/net/PortUnreachableException", ""); + return 0; + } + + if ( packet != NULL) { + env->SetIntField(packet, gCachedFields.dpack_length, actualLength); + } + add_recv_stats(handle, actualLength); + return actualLength; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_recvConnectedDatagramImpl(JNIEnv* env, jclass clazz, + jobject fd, jobject packet, jbyteArray data, jint offset, jint length, + jint receiveTimeout, jboolean peek) { + // LOGD("ENTER receiveConnectedDatagramImpl"); + + int localLength = (length < 65536) ? length : 65536; + jbyte *bytes = (jbyte*) malloc(localLength); + if (bytes == NULL) { + jniThrowException(env, "java/lang/OutOfMemoryError", + "couldn't allocate enough memory for recvConnectedDatagram"); + return 0; + } + + int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_recvConnectedDatagramDirectImpl(env, + clazz, fd, packet, (jint)bytes, offset, localLength, + receiveTimeout, peek); + + if (actualLength > 0) { + env->SetByteArrayRegion(data, offset, actualLength, bytes); + } + free(bytes); + + return actualLength; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramDirectImpl(JNIEnv* env, jclass clazz, + jobject fd, jint address, jint offset, jint length, jint port, + jboolean bindToDevice, jint trafficClass, jobject inetAddress) { + // LOGD("ENTER sendDatagramDirectImpl"); + + int result = 0; + + int handle = jniGetFDFromFileDescriptor(env, fd); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + struct sockaddr_in receiver; + + if (inetAddressToSocketAddress(env, inetAddress, port, &receiver) < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + result = sendto(handle, (char*)(address + offset), length, SOCKET_NOFLAGS, + (struct sockaddr*)&receiver, sizeof(receiver)); + + if (result < 0) { + int err = convertError(errno); + if ((SOCKERR_CONNRESET == err) + || (SOCKERR_CONNECTION_REFUSED == err)) { + return 0; + } else { + log_socket_close(handle, err); + throwSocketException(env, err); + return 0; + } + } + add_send_stats(handle, result); + return result; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramImpl(JNIEnv* env, jclass clazz, + jobject fd, jbyteArray data, jint offset, jint length, jint port, + jboolean bindToDevice, jint trafficClass, jobject inetAddress) { + // LOGD("ENTER sendDatagramImpl"); + + jbyte *bytes = env->GetByteArrayElements(data, NULL); + int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramDirectImpl(env, clazz, fd, + (jint)bytes, offset, length, port, bindToDevice, trafficClass, + inetAddress); + env->ReleaseByteArrayElements(data, bytes, JNI_ABORT); + + return actualLength; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv* env, + jclass clazz, jobject fd, jint address, jint offset, jint length, + jboolean bindToDevice) { + // LOGD("ENTER sendConnectedDatagramDirectImpl"); + + int handle = jniGetFDFromFileDescriptor(env, fd); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + int result = send(handle, (char*)(address + offset), length, 0); + + if (result < 0) { + int err = convertError(errno); + if ((SOCKERR_CONNRESET == err) || (SOCKERR_CONNECTION_REFUSED == err)) { + return 0; + } else { + log_socket_close(handle, err); + throwSocketException(env, err); + return 0; + } + } + add_send_stats(handle, length); + return result; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendConnectedDatagramImpl(JNIEnv* env, jclass clazz, + jobject fd, jbyteArray data, jint offset, jint length, + jboolean bindToDevice) { + // LOGD("ENTER sendConnectedDatagramImpl"); + + jbyte *bytes = env->GetByteArrayElements(data, NULL); + int actualLength = Java_org_sipdroid_net_impl_OSNetworkSystem_sendConnectedDatagramDirectImpl(env, + clazz, fd, (jint)bytes, offset, length, bindToDevice); + env->ReleaseByteArrayElements(data, bytes, JNI_ABORT); + + return actualLength; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createServerStreamSocketImpl(JNIEnv* env, + jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) { + // LOGD("ENTER createServerStreamSocketImpl"); + + if (fileDescriptor == NULL) { + throwNullPointerException(env); + return; + } + + int handle = socket(PF_INET, SOCK_STREAM, 0); + + if (handle < 0) { + int err = convertError(errno); + throwSocketException(env, err); + return; + } + + jniSetFileDescriptorOfFD(env, fileDescriptor, handle); + + int value = 1; + + setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int)); +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_createMulticastSocketImpl(JNIEnv* env, + jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) { + // LOGD("ENTER createMulticastSocketImpl"); + + int handle = socket(PF_INET, SOCK_DGRAM, 0); + + if (handle < 0) { + int err = convertError(errno); + throwSocketException(env, err); + return; + } + + jniSetFileDescriptorOfFD(env, fileDescriptor, handle); + + int value = 1; + + // setsockopt(handle, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(jbyte)); + setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int)); +} + +/* + * @param timeout in milliseconds. If zero, block until data received + */ +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_receiveStreamImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jbyteArray data, jint offset, jint count, + jint timeout) { + // LOGD("ENTER receiveStreamImpl"); + + int result; + int handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + // Cap read length to available buf size + int spaceAvailable = env->GetArrayLength(data) - offset; + int localCount = count < spaceAvailable? count : spaceAvailable; + + jboolean isCopy; + jbyte *body = env->GetByteArrayElements(data, &isCopy); + + // set timeout + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, + sizeof(struct timeval)); + + do { + result = recv(handle, body + offset, localCount, SOCKET_NOFLAGS); + } while (result < 0 && errno == EINTR); + + env->ReleaseByteArrayElements(data, body, 0); + + /* + * If no bytes are read, return -1 to signal 'endOfFile' + * to the Java input stream + */ + if (0 < result) { + add_recv_stats(handle, result); + return result; + } else if (0 == result) { + return -1; + } else { + // If EAGAIN or EWOULDBLOCK, read timed out + if (errno == EAGAIN || errno == EWOULDBLOCK) { + jniThrowException(env, "java/net/SocketTimeoutException", + netLookupErrorString(SOCKERR_TIMEOUT)); + } else { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + } + return 0; + } +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendStreamImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jbyteArray data, jint offset, jint count) { + // LOGD("ENTER sendStreamImpl"); + + int handle = 0; + int result = 0, sent = 0; + + jboolean isCopy; + jbyte *message = env->GetByteArrayElements(data, &isCopy); + + // Cap write length to available buf size + int spaceAvailable = env->GetArrayLength(data) - offset; + if (count > spaceAvailable) count = spaceAvailable; + + while (sent < count) { + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + if (handle == 0 || handle == -1) { + throwSocketException(env, + sent == 0 ? SOCKERR_BADSOCKET : SOCKERR_INTERRUPTED); + env->ReleaseByteArrayElements(data, message, 0); + return 0; + } + + // LOGD("before select %d", count); + selectWait(handle, SEND_RETRY_TIME, SELECT_WRITE_TYPE); + result = send(handle, (jbyte *)message + offset + sent, + (int) count - sent, SOCKET_NOFLAGS); + + if (result < 0) { + result = errno; + if (result == EAGAIN ||result == EWOULDBLOCK) { + // LOGD("write blocked %d", sent); + continue; + } + env->ReleaseByteArrayElements(data, message, 0); + int err = convertError(result); + log_socket_close(handle, err); + throwSocketException(env, err); + return 0; + } + sent += result; + } + + env->ReleaseByteArrayElements(data, message, 0); + add_send_stats(handle, sent); + return sent; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_shutdownInputImpl(JNIEnv* env, jobject obj, + jobject fileDescriptor) { + // LOGD("ENTER shutdownInputImpl"); + + int ret; + int handle; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + ret = shutdown(handle, SHUT_RD); + + if (ret < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return; + } +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_shutdownOutputImpl(JNIEnv* env, jobject obj, + jobject fileDescriptor) { + // LOGD("ENTER shutdownOutputImpl"); + + int ret; + int handle; + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + return; + } + + ret = shutdown(handle, SHUT_WR); + + if (ret < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + return; + } +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_sendDatagramImpl2(JNIEnv* env, jclass clazz, + jobject fd, jbyteArray data, jint offset, jint length, jint port, + jobject inetAddress) { + // LOGD("ENTER sendDatagramImpl2"); + + jbyte *message; + jbyte nhostAddrBytes[4]; + unsigned short nPort; + int result = 0, sent = 0; + int handle = 0; + struct sockaddr_in sockaddrP; + + if (inetAddress != NULL) { + + result = inetAddressToSocketAddress(env, inetAddress, port, + (struct sockaddr_in *) &sockaddrP); + + if (result < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + + handle = jniGetFDFromFileDescriptor(env, fd); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return 0; + } + } + + message = (jbyte*) malloc(length * sizeof(jbyte)); + if (message == NULL) { + jniThrowException(env, "java/lang/OutOfMemoryError", + "couldn't allocate enough memory for readSocket"); + return 0; + } + + env->GetByteArrayRegion(data, offset, length, message); + + while (sent < length) { + handle = jniGetFDFromFileDescriptor(env, fd); + + if (handle == 0 || handle == -1) { + throwSocketException(env, + sent == 0 ? SOCKERR_BADSOCKET : SOCKERR_INTERRUPTED); + free(message); + return 0; + } + + result = sendto(handle, (char *) (message + sent), + (int) (length - sent), SOCKET_NOFLAGS, + (struct sockaddr *) &sockaddrP, sizeof(sockaddrP)); + + if (result < 0) { + int err = convertError(errno); + log_socket_close(handle, err); + throwSocketException(env, err); + free(message); + return 0; + } + + sent += result; + } + + free(message); + add_send_stats(handle, sent); + return sent; +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_selectImpl(JNIEnv* env, jclass clazz, + jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC, + jint countWriteC, jintArray outFlags, jlong timeout) { + // LOGD("ENTER selectImpl"); + + struct timeval timeP; + int result = 0; + int size = 0; + jobject gotFD; + fd_set *fdset_read,*fdset_write; + int handle; + jboolean isCopy ; + jint *flagArray; + int val; + unsigned int time_sec = (unsigned int)timeout/1000; + unsigned int time_msec = (unsigned int)(timeout%1000); + + fdset_read = (fd_set *)malloc(sizeof(fd_set)); + fdset_write = (fd_set *)malloc(sizeof(fd_set)); + + FD_ZERO(fdset_read); + FD_ZERO(fdset_write); + + for (val = 0; valGetObjectArrayElement(readFDArray,val); + + handle = jniGetFDFromFileDescriptor(env, gotFD); + + FD_SET(handle, fdset_read); + + if (0 > (size - handle)) { + size = handle; + } + } + + for (val = 0; valGetObjectArrayElement(writeFDArray,val); + + handle = jniGetFDFromFileDescriptor(env, gotFD); + + FD_SET(handle, fdset_write); + + if (0 > (size - handle)) { + size = handle; + } + } + + /* the size is the max_fd + 1 */ + size =size + 1; + + if (0 > size) { + result = SOCKERR_FDSET_SIZEBAD; + } else { + /* only set when timeout >= 0 (non-block)*/ + if (0 <= timeout) { + + timeP.tv_sec = time_sec; + timeP.tv_usec = time_msec*1000; + + result = sockSelect(size, fdset_read, fdset_write, NULL, &timeP); + + } else { + result = sockSelect(size, fdset_read, fdset_write, NULL, NULL); + } + } + + if (0 < result) { + /*output the result to a int array*/ + flagArray = env->GetIntArrayElements(outFlags, &isCopy); + + for (val=0; valGetObjectArrayElement(readFDArray,val); + + handle = jniGetFDFromFileDescriptor(env, gotFD); + + if (FD_ISSET(handle,fdset_read)) { + flagArray[val] = SOCKET_OP_READ; + } else { + flagArray[val] = SOCKET_OP_NONE; + } + } + + for (val=0; valGetObjectArrayElement(writeFDArray,val); + + handle = jniGetFDFromFileDescriptor(env, gotFD); + + if (FD_ISSET(handle,fdset_write)) { + flagArray[val+countReadC] = SOCKET_OP_WRITE; + } else { + flagArray[val+countReadC] = SOCKET_OP_NONE; + } + } + + env->ReleaseIntArrayElements(outFlags, flagArray, 0); + } + + free(fdset_write); + free(fdset_read); + + /* return both correct and error result, let java handle the exception*/ + return result; +} + +extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketLocalAddressImpl(JNIEnv* env, + jclass clazz, jobject fileDescriptor, jboolean preferIPv6Addresses) { + // LOGD("ENTER getSocketLocalAddressImpl"); + + struct sockaddr_in addr; + socklen_t addrLen = sizeof(addr); + + memset(&addr, 0, addrLen); + + int handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + int result; + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_UNKNOWNSOCKET); + return NULL; + } + + result = getsockname(handle, (struct sockaddr *)&addr, &addrLen); + + // Spec says ignore all errors + + return structInToInetAddress(env, &(addr.sin_addr)); + +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jboolean preferIPv6Addresses) { + // LOGD("ENTER getSocketLocalPortImpl"); + + struct sockaddr_in addr; + socklen_t addrLen = sizeof(addr); + + int handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + int result; + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_UNKNOWNSOCKET); + return 0; + } + + result = getsockname(handle, (struct sockaddr *)&addr, &addrLen); + + if (0 != result) { + // The java spec does not indicate any exceptions on this call + return 0; + } else { + return ntohs(addr.sin_port); + } +} + +extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint anOption) { + // LOGD("ENTER getSocketOptionImpl"); + + int handle; + int intValue = 0; + socklen_t intSize = sizeof(int); + unsigned char byteValue = 0; + socklen_t byteSize = sizeof(unsigned char); + int result; + struct sockaddr_in sockVal; + socklen_t sockSize = sizeof(sockVal); + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return NULL; + } + + switch ((int) anOption & 0xffff) { + case JAVASOCKOPT_SO_LINGER: { + struct linger lingr; + socklen_t size = sizeof(struct linger); + result = getsockopt(handle, SOL_SOCKET, SO_LINGER, &lingr, &size); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + if (!lingr.l_onoff) { + intValue = -1; + } else { + intValue = lingr.l_linger; + } + return newJavaLangInteger(env, intValue); + } + case JAVASOCKOPT_TCP_NODELAY: { + if ((anOption >> 16) & BROKEN_TCP_NODELAY) { + return NULL; + } + result = getsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangBoolean(env, intValue); + } + case JAVASOCKOPT_MCAST_TTL: { + if ((anOption >> 16) & BROKEN_MULTICAST_TTL) { + return newJavaLangByte(env, 0); + } + result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_TTL, &byteValue, &byteSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangByte(env, (jbyte)(byteValue & 0xFF)); + } + case JAVASOCKOPT_MCAST_INTERFACE: { + if ((anOption >> 16) & BROKEN_MULTICAST_IF) { + return NULL; + } + result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF, &sockVal, &sockSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return structInToInetAddress(env, &(sockVal.sin_addr)); + } + case JAVASOCKOPT_SO_SNDBUF: { + result = getsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangInteger(env, intValue); + } + case JAVASOCKOPT_SO_RCVBUF: { + result = getsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangInteger(env, intValue); + } + case JAVASOCKOPT_SO_BROADCAST: { + result = getsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangBoolean(env, intValue); + } + case JAVASOCKOPT_SO_REUSEADDR: { + result = getsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangBoolean(env, intValue); + } + case JAVASOCKOPT_SO_KEEPALIVE: { + result = getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangBoolean(env, intValue); + } + case JAVASOCKOPT_SO_OOBINLINE: { + result = getsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangBoolean(env, intValue); + } + case JAVASOCKOPT_IP_MULTICAST_LOOP: { + result = getsockopt(handle, IPPROTO_IP, IP_MULTICAST_LOOP, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangBoolean(env, intValue); + } + case JAVASOCKOPT_IP_TOS: { + result = getsockopt(handle, IPPROTO_IP, IP_TOS, &intValue, &intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangInteger(env, intValue); + } + case JAVASOCKOPT_SO_RCVTIMEOUT: { + struct timeval timeout; + socklen_t size = sizeof(timeout); + result = getsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout, &size); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return NULL; + } + return newJavaLangInteger(env, timeout.tv_sec * 1000 + timeout.tv_usec/1000); + } + default: { + throwSocketException(env, SOCKERR_OPTUNSUPP); + return NULL; + } + } + +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_setSocketOptionImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor, jint anOption, jobject optVal) { + // LOGD("ENTER setSocketOptionImpl"); + + int handle, result; + int intVal, intSize = sizeof(int); + unsigned char byteVal, byteSize = sizeof(unsigned char); + struct sockaddr_in sockVal; + int sockSize = sizeof(sockVal); + + if (env->IsInstanceOf(optVal, gCachedFields.integer_class)) { + intVal = (int) env->GetIntField(optVal, gCachedFields.integer_class_value); + } else if (env->IsInstanceOf(optVal, gCachedFields.boolean_class)) { + intVal = (int) env->GetBooleanField(optVal, gCachedFields.boolean_class_value); + } else if (env->IsInstanceOf(optVal, gCachedFields.byte_class)) { + byteVal = (int) env->GetByteField(optVal, gCachedFields.byte_class_value); + } else if (env->IsInstanceOf(optVal, gCachedFields.iaddr_class)) { + if (inetAddressToSocketAddress(env, optVal, 0, &sockVal) < 0) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + } else if (env->IsInstanceOf(optVal, gCachedFields.genericipmreq_class)) { + // we'll use optVal directly + } else { + throwSocketException(env, SOCKERR_OPTUNSUPP); + return; + } + + handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + switch ((int) anOption & 0xffff) { + case JAVASOCKOPT_SO_LINGER: { + struct linger lingr; + lingr.l_onoff = intVal > 0 ? 1 : 0; + lingr.l_linger = intVal; + result = setsockopt(handle, SOL_SOCKET, SO_LINGER, &lingr, + sizeof(struct linger)); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_TCP_NODELAY: { + if ((anOption >> 16) & BROKEN_TCP_NODELAY) { + return; + } + result = setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_MCAST_TTL: { + if ((anOption >> 16) & BROKEN_MULTICAST_TTL) { + return; + } + result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_TTL, &byteVal, byteSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_MCAST_ADD_MEMBERSHIP: { + mcastAddDropMembership(env, handle, optVal, + (anOption >> 16) & BROKEN_MULTICAST_IF, IP_ADD_MEMBERSHIP); + return; + } + + case JAVASOCKOPT_MCAST_DROP_MEMBERSHIP: { + mcastAddDropMembership(env, handle, optVal, + (anOption >> 16) & BROKEN_MULTICAST_IF, IP_DROP_MEMBERSHIP); + return; + } + + case JAVASOCKOPT_MCAST_INTERFACE: { + if ((anOption >> 16) & BROKEN_MULTICAST_IF) { + return; + } + result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_IF, &sockVal, sockSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_SO_SNDBUF: { + result = setsockopt(handle, SOL_SOCKET, SO_SNDBUF, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_SO_RCVBUF: { + result = setsockopt(handle, SOL_SOCKET, SO_RCVBUF, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_SO_BROADCAST: { + result = setsockopt(handle, SOL_SOCKET, SO_BROADCAST, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_SO_REUSEADDR: { + result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + case JAVASOCKOPT_SO_KEEPALIVE: { + result = setsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_SO_OOBINLINE: { + result = setsockopt(handle, SOL_SOCKET, SO_OOBINLINE, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_IP_MULTICAST_LOOP: { + result = setsockopt(handle, IPPROTO_IP, IP_MULTICAST_LOOP, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_IP_TOS: { + result = setsockopt(handle, IPPROTO_IP, IP_TOS, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_REUSEADDR_AND_REUSEPORT: { + // SO_REUSEPORT doesn't need to get set on this System + result = setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &intVal, intSize); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + case JAVASOCKOPT_SO_RCVTIMEOUT: { + struct timeval timeout; + timeout.tv_sec = intVal / 1000; + timeout.tv_usec = (intVal % 1000) * 1000; + result = setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, &timeout, + sizeof(struct timeval)); + if (0 != result) { + throwSocketException(env, convertError(errno)); + return; + } + break; + } + + default: { + throwSocketException(env, SOCKERR_OPTUNSUPP); + } + } +} + +extern "C" jint Java_org_sipdroid_net_impl_OSNetworkSystem_getSocketFlagsImpl(JNIEnv* env, jclass clazz) { + // LOGD("ENTER getSocketFlagsImpl"); + + // Not implemented by harmony + return 0; +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_socketCloseImpl(JNIEnv* env, jclass clazz, + jobject fileDescriptor) { + // LOGD("ENTER socketCloseImpl"); + + int handle = jniGetFDFromFileDescriptor(env, fileDescriptor); + + if (handle == 0 || handle == -1) { + throwSocketException(env, SOCKERR_BADSOCKET); + return; + } + + log_socket_close(handle, SOCKET_CLOSE_LOCAL); + + jniSetFileDescriptorOfFD(env, fileDescriptor, -1); + + close(handle); +} + +extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getHostByAddrImpl(JNIEnv* env, jclass clazz, + jbyteArray addrStr) { + // LOGD("ENTER getHostByAddrImpl"); + + if (addrStr == NULL) { + throwNullPointerException(env); + return JNI_FALSE; + } + + jstring address = (jstring)newJavaLangString(env, addrStr); + jstring result; + const char* addr = env->GetStringUTFChars(address, NULL); + + struct hostent* ent = gethostbyaddr(addr, strlen(addr), AF_INET); + + if (ent != NULL && ent->h_name != NULL) { + result = env->NewStringUTF(ent->h_name); + } else { + result = NULL; + } + + env->ReleaseStringUTFChars(address, addr); + + return result; +} + +extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_getHostByNameImpl(JNIEnv* env, jclass clazz, + jstring nameStr, jboolean preferIPv6Addresses) { + // LOGD("ENTER getHostByNameImpl"); + + if (nameStr == NULL) { + throwNullPointerException(env); + return NULL; + } + + const char* name = env->GetStringUTFChars(nameStr, NULL); + + if (useAdbNetworking) { + + union { + struct in_addr a; + jbyte j[4]; + } outaddr; + + // LOGD("ADB networking: +gethostbyname '%s'", name); + int err; + err = adb_networking_gethostbyname(name, &(outaddr.a)); + + env->ReleaseStringUTFChars(nameStr, name); +#if 0 + LOGD("ADB networking: -gethostbyname err %d addr 0x%08x %u.%u.%u.%u", + err, (unsigned int)outaddr.a.s_addr, + outaddr.j[0],outaddr.j[1], + outaddr.j[2],outaddr.j[3]); +#endif + + if (err < 0) { + return NULL; + } else { + jbyteArray addr = env->NewByteArray(4); + env->SetByteArrayRegion(addr, 0, 4, outaddr.j); + return addr; + } + } else { + + // normal case...no adb networking + struct hostent* ent = gethostbyname(name); + + env->ReleaseStringUTFChars(nameStr, name); + + if (ent != NULL && ent->h_length > 0) { + jbyteArray addr = env->NewByteArray(4); + jbyte v[4]; + memcpy(v, ent->h_addr, 4); + env->SetByteArrayRegion(addr, 0, 4, v); + return addr; + } else { + return NULL; + } + } +} + +extern "C" void Java_org_sipdroid_net_impl_OSNetworkSystem_setInetAddressImpl(JNIEnv* env, jobject obj, + jobject sender, jbyteArray address) { + // LOGD("ENTER setInetAddressImpl"); + + env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address); +} + +/* +extern "C" jobject Java_org_sipdroid_net_impl_OSNetworkSystem_inheritedChannelImpl(JNIEnv* env, jobject obj) { + // LOGD("ENTER inheritedChannelImpl"); + + int socket = 0; + int opt; + socklen_t length = sizeof(opt); + int socket_type; + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + jclass channel_class, socketaddr_class, serverSocket_class, socketImpl_class; + jobject channel_object = NULL, socketaddr_object, serverSocket_object; + jobject fd_object, addr_object, localAddr_object, socketImpl_object; + jfieldID port_field, socketaddr_field, bound_field, fd_field; + jfieldID serverSocket_field, socketImpl_field, addr_field, localAddr_field; + jmethodID channel_new; + jbyteArray addr_array; + struct sockaddr_in *sock; + jbyte * address; + jbyte * localAddr; + jboolean jtrue = JNI_TRUE; + + if (0 != getsockopt(socket, SOL_SOCKET, SO_TYPE, &opt, &length)) { + return NULL; + } + if (SOCK_STREAM !=opt && SOCK_DGRAM !=opt) { + return NULL; + } + socket_type = opt; + + length = sizeof(struct sockaddr); + if (0 != getsockname(socket, (struct sockaddr *)&local_addr, &length)) { + return NULL; + } else { + if (AF_INET != local_addr.sin_family || length != sizeof(struct sockaddr)) { + return NULL; + } + localAddr = (jbyte*) malloc(sizeof(jbyte)*4); + if (NULL == localAddr) { + return NULL; + } + memcpy (localAddr, &(local_addr.sin_addr.s_addr), 4); + } + if (0 != getpeername(socket, (struct sockaddr *)&remote_addr, &length)) { + remote_addr.sin_port = 0; + remote_addr.sin_addr.s_addr = 0; + address = (jbyte*) malloc(sizeof(jbyte)*4); + bzero(address, sizeof(jbyte)*4); + } else { + if (AF_INET != remote_addr.sin_family + || length != sizeof(struct sockaddr)) { + return NULL; + } + address = (jbyte*) malloc(sizeof(jbyte)*4); + memcpy (address, &(remote_addr.sin_addr.s_addr), 4); + } + + // analysis end, begin pack to java + if (SOCK_STREAM == opt) { + if (remote_addr.sin_port!=0) { + //socket + channel_class = env->FindClass( + "org/apache/harmony/nio/internal/SocketChannelImpl"); + if (NULL == channel_class) { + goto clean; + } + + channel_new = env->GetMethodID(channel_class, "", "()V"); + if (NULL == channel_new) { + goto clean; + } + channel_object = env->NewObject(channel_class, channel_new); + if (NULL == channel_object) { + goto clean; + } + // new and set FileDescript + + fd_field = env->GetFieldID(channel_class, "fd", + "java/io/FielDescriptor"); + fd_object = env->GetObjectField(channel_object, fd_field); + if (NULL == fd_object) { + goto clean; + } + + jniSetFileDescriptorOfFD(env, fd_object, socket); + + // local port + port_field = env->GetFieldID(channel_class, "localPort", "I"); + env->SetIntField(channel_object, port_field, + ntohs(local_addr.sin_port)); + + // new and set remote addr + addr_object = env->NewObject(gCachedFields.iaddr_class, + gCachedFields.iaddr_class_init); + if (NULL == addr_object) { + goto clean; + } + socketaddr_class = env->FindClass("java/net/InetSocketAddress"); + socketaddr_field = env->GetFieldID(channel_class, "connectAddress", + "Ljava/net/InetSocketAddress;"); + socketaddr_object = env->GetObjectField(channel_object, + socketaddr_field); + if (NULL == socketaddr_object) { + goto clean; + } + addr_field = env->GetFieldID(socketaddr_class, "addr", + "Ljava/net/InetAddress;"); + env->SetObjectField(socketaddr_object, addr_field, addr_object); + addr_array = env->NewByteArray((jsize)4); + env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, address); + env->SetObjectField(addr_object, gCachedFields.iaddr_ipaddress, + addr_array); + + // localAddr + socketaddr_class = env->FindClass("java/net/InetSocketAddress"); + socketaddr_field = env->GetFieldID(channel_class, "connectAddress", + "Ljava/net/InetSocketAddress;"); + socketaddr_object = env->GetObjectField(channel_object, + socketaddr_field); + + localAddr_field = env->GetFieldID(channel_class, "localAddress", + "Ljava/net/InetAddress;"); + localAddr_object = env->NewObject(gCachedFields.iaddr_class, + gCachedFields.iaddr_class_init); + jfieldID socketaddr_field = env->GetFieldID(channel_class, + "connectAddress", "Ljava/net/InetSocketAddress;"); + jobject socketaddr_object = env->GetObjectField(channel_object, + socketaddr_field); + env->SetObjectField(socketaddr_object, localAddr_field, + localAddr_object); + if (NULL == localAddr_object) { + goto clean; + } + addr_array = env->NewByteArray((jsize)4); + env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, localAddr); + env->SetObjectField(localAddr_object, gCachedFields.iaddr_ipaddress, + addr_array); + + + // set port + port_field = env->GetFieldID(socketaddr_class, "port", "I"); + env->SetIntField(socketaddr_object, port_field, + ntohs(remote_addr.sin_port)); + + // set bound + if (0 != local_addr.sin_port) { + bound_field = env->GetFieldID(channel_class, "isBound", "Z"); + env->SetBooleanField(channel_object, bound_field, jtrue); + } + + } else { + //serverSocket + channel_class = env->FindClass( + "org/apache/harmony/nio/internal/ServerSocketChannelImpl"); + if (NULL == channel_class) { + goto clean; + } + + channel_new = env->GetMethodID(channel_class, "", "()V"); + if (NULL == channel_new) { + goto clean; + } + channel_object = env->NewObject(channel_class, channel_new); + if (NULL == channel_object) { + goto clean; + } + + serverSocket_field = env->GetFieldID(channel_class, "socket", + "Ljava/net/ServerSocket;"); + serverSocket_class = env->FindClass("Ljava/net/ServerSocket;"); + serverSocket_object = env->GetObjectField(channel_object, + serverSocket_field); + // set bound + if (0 != local_addr.sin_port) { + bound_field = env->GetFieldID(channel_class, "isBound", "Z"); + env->SetBooleanField(channel_object, bound_field, jtrue); + bound_field = env->GetFieldID(serverSocket_class, "isBound", "Z"); + env->SetBooleanField(serverSocket_object, bound_field, jtrue); + } + // localAddr + socketImpl_class = env->FindClass("java/net/SocketImpl"); + socketImpl_field = env->GetFieldID(channel_class, "impl", + "Ljava/net/SocketImpl;"); + socketImpl_object = env->GetObjectField(channel_object, + socketImpl_field); + if (NULL == socketImpl_object) { + goto clean; + } + + localAddr_field = env->GetFieldID(channel_class, "localAddress", + "Ljava/net/InetAddress;"); + localAddr_object = env->NewObject(gCachedFields.iaddr_class, + gCachedFields.iaddr_class_init); + if (NULL == localAddr_object) { + goto clean; + } + env->SetObjectField(socketImpl_object, localAddr_field, + localAddr_object); + addr_array = env->NewByteArray((jsize)4); + env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, localAddr); + env->SetObjectField(localAddr_object, + gCachedFields.iaddr_ipaddress, addr_array); + + // set port + port_field = env->GetFieldID(socketImpl_class, "localport", "I"); + env->SetIntField(socketImpl_object, port_field, + ntohs(local_addr.sin_port)); + } + } else { + //Datagram Socket + // new DatagramChannel + channel_class = env->FindClass( + "org/apache/harmony/nio/internal/DatagramChannelImpl"); + if (NULL == channel_class) { + goto clean; + } + + channel_new = env->GetMethodID(channel_class, "", "()V"); + if (NULL == channel_new) { + goto clean; + } + channel_object = env->NewObject(channel_class, channel_new); + if (NULL == channel_object) { + goto clean; + } + + // new and set FileDescript + fd_field = env->GetFieldID(channel_class, "fd", "java/io/FileDescriptor"); + fd_object = env->GetObjectField(channel_object, fd_field); + if (NULL == fd_object) { + goto clean; + } + + jniSetFileDescriptorOfFD(env, fd_object, socket); + + port_field = env->GetFieldID(channel_class, "localPort", "I"); + env->SetIntField(channel_object, port_field, ntohs(local_addr.sin_port)); + + // new and set remote addr + addr_object = env->NewObject(gCachedFields.iaddr_class, + gCachedFields.iaddr_class_init); + if (NULL == addr_object) { + goto clean; + } + socketaddr_class = env->FindClass("java/net/InetSocketAddress"); + socketaddr_field = env->GetFieldID(channel_class, "connectAddress", + "Ljava/net/InetSocketAddress;"); + socketaddr_object = env->GetObjectField(channel_object, socketaddr_field); + if (NULL == socketaddr_object) { + goto clean; + } + addr_field = env->GetFieldID(socketaddr_class, "addr", + "Ljava/net/InetAddress;"); + env->SetObjectField(socketaddr_object, addr_field, addr_object); + addr_array = env->NewByteArray((jsize)4); + env->SetByteArrayRegion(addr_array, (jsize)0, (jsize)4, address); + env->SetObjectField(addr_object, gCachedFields.iaddr_ipaddress, addr_array); + + // set bound + if (0 != local_addr.sin_port) { + bound_field = env->GetFieldID(channel_class, "isBound", "Z"); + env->SetBooleanField(channel_object, bound_field, jtrue); + } + } +clean: + free(address); + free(localAddr); + return channel_object; +} +*/ diff -r e29937c5670c -r f703b3e14f9a jni/g722/g722.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/g722/g722.h Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,159 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g722.h - The ITU G.722 codec. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * Despite my general liking of the GPL, I place my own contributions + * to this code in the public domain for the benefit of all mankind - + * even the slimy ones who might try to proprietize my work and use it + * to my detriment. + * + * Based on a single channel G.722 codec which is: + * + ***** Copyright (c) CMU 1993 ***** + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722.h 48959 2006-12-25 06:42:15Z rizzo $ + */ + + +/*! \file */ + +#if !defined(_G722_H_) +#define _G722_H_ + +/*! \page g722_page G.722 encoding and decoding +\section g722_page_sec_1 What does it do? +The G.722 module is a bit exact implementation of the ITU G.722 specification for all three +specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests. + +To allow fast and flexible interworking with narrow band telephony, the encoder and decoder +support an option for the linear audio to be an 8k samples/second stream. In this mode the +codec is considerably faster, and still fully compatible with wideband terminals using G.722. + +\section g722_page_sec_2 How does it work? +???. +*/ + +#if !defined(__STDINT_MACROS) +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; +#endif + +enum +{ + G722_SAMPLE_RATE_8000 = 0x0001, + G722_PACKED = 0x0002 +}; + +#ifndef INT16_MAX +#define INT16_MAX 32767 +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32768) +#endif + +typedef struct +{ + /*! TRUE if the operating in the special ITU test mode, with the band split filters + disabled. */ + int itu_test_mode; + /*! TRUE if the G.722 data is packed */ + int packed; + /*! TRUE if encode from 8k samples/second */ + int eight_k; + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ + int bits_per_sample; + + /*! Signal history for the QMF */ + int x[24]; + + struct + { + int s; + int sp; + int sz; + int r[3]; + int a[3]; + int ap[3]; + int p[3]; + int d[7]; + int b[7]; + int bp[7]; + int sg[7]; + int nb; + int det; + } band[2]; + + unsigned int in_buffer; + int in_bits; + unsigned int out_buffer; + int out_bits; +} g722_encode_state_t; + +typedef struct +{ + /*! TRUE if the operating in the special ITU test mode, with the band split filters + disabled. */ + int itu_test_mode; + /*! TRUE if the G.722 data is packed */ + int packed; + /*! TRUE if decode to 8k samples/second */ + int eight_k; + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ + int bits_per_sample; + + /*! Signal history for the QMF */ + int x[24]; + + struct + { + int s; + int sp; + int sz; + int r[3]; + int a[3]; + int ap[3]; + int p[3]; + int d[7]; + int b[7]; + int bp[7]; + int sg[7]; + int nb; + int det; + } band[2]; + + unsigned int in_buffer; + int in_bits; + unsigned int out_buffer; + int out_bits; +} g722_decode_state_t; + +#ifdef __cplusplus +extern "C" { +#endif + +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options); +int g722_encode_release(g722_encode_state_t *s); +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len); + +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options); +int g722_decode_release(g722_decode_state_t *s); +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len); + +#ifdef __cplusplus +} +#endif + +#endif diff -r e29937c5670c -r f703b3e14f9a jni/g722/g722_decode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/g722/g722_decode.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,398 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g722_decode.c - The ITU G.722 codec, decode part. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * Despite my general liking of the GPL, I place my own contributions + * to this code in the public domain for the benefit of all mankind - + * even the slimy ones who might try to proprietize my work and use it + * to my detriment. + * + * Based in part on a single channel G.722 codec which is: + * + * Copyright (c) CMU 1993 + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722_decode.c 48661 2006-12-21 00:08:21Z mattf $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +//#include +#include +#include +#if 0 +#include +#endif + +#include "g722.h" + +#if !defined(FALSE) +#define FALSE 0 +#endif +#if !defined(TRUE) +#define TRUE (!FALSE) +#endif + +static int16_t saturate(int32_t amp) +{ + int16_t amp16; + + /* Hopefully this is optimised for the common case - not clipping */ + amp16 = (int16_t) amp; + if (amp == amp16) + return amp16; + if (amp > INT16_MAX) + return INT16_MAX; + return INT16_MIN; +} +/*- End of function --------------------------------------------------------*/ + +static void block4(g722_decode_state_t *s, int band, int d); + +static void block4(g722_decode_state_t *s, int band, int d) +{ + int wd1; + int wd2; + int wd3; + int i; + + /* Block 4, RECONS */ + s->band[band].d[0] = d; + s->band[band].r[0] = saturate(s->band[band].s + d); + + /* Block 4, PARREC */ + s->band[band].p[0] = saturate(s->band[band].sz + d); + + /* Block 4, UPPOL2 */ + for (i = 0; i < 3; i++) + s->band[band].sg[i] = s->band[band].p[i] >> 15; + wd1 = saturate(s->band[band].a[1] << 2); + + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; + if (wd2 > 32767) + wd2 = 32767; + wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128; + wd3 += (wd2 >> 7); + wd3 += (s->band[band].a[2]*32512) >> 15; + if (wd3 > 12288) + wd3 = 12288; + else if (wd3 < -12288) + wd3 = -12288; + s->band[band].ap[2] = wd3; + + /* Block 4, UPPOL1 */ + s->band[band].sg[0] = s->band[band].p[0] >> 15; + s->band[band].sg[1] = s->band[band].p[1] >> 15; + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; + wd2 = (s->band[band].a[1]*32640) >> 15; + + s->band[band].ap[1] = saturate(wd1 + wd2); + wd3 = saturate(15360 - s->band[band].ap[2]); + if (s->band[band].ap[1] > wd3) + s->band[band].ap[1] = wd3; + else if (s->band[band].ap[1] < -wd3) + s->band[band].ap[1] = -wd3; + + /* Block 4, UPZERO */ + wd1 = (d == 0) ? 0 : 128; + s->band[band].sg[0] = d >> 15; + for (i = 1; i < 7; i++) + { + s->band[band].sg[i] = s->band[band].d[i] >> 15; + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; + wd3 = (s->band[band].b[i]*32640) >> 15; + s->band[band].bp[i] = saturate(wd2 + wd3); + } + + /* Block 4, DELAYA */ + for (i = 6; i > 0; i--) + { + s->band[band].d[i] = s->band[band].d[i - 1]; + s->band[band].b[i] = s->band[band].bp[i]; + } + + for (i = 2; i > 0; i--) + { + s->band[band].r[i] = s->band[band].r[i - 1]; + s->band[band].p[i] = s->band[band].p[i - 1]; + s->band[band].a[i] = s->band[band].ap[i]; + } + + /* Block 4, FILTEP */ + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); + wd1 = (s->band[band].a[1]*wd1) >> 15; + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); + wd2 = (s->band[band].a[2]*wd2) >> 15; + s->band[band].sp = saturate(wd1 + wd2); + + /* Block 4, FILTEZ */ + s->band[band].sz = 0; + for (i = 6; i > 0; i--) + { + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; + } + s->band[band].sz = saturate(s->band[band].sz); + + /* Block 4, PREDIC */ + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); +} +/*- End of function --------------------------------------------------------*/ + +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options) +{ + if (s == NULL) + { + if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + if (rate == 48000) + s->bits_per_sample = 6; + else if (rate == 56000) + s->bits_per_sample = 7; + else + s->bits_per_sample = 8; + if ((options & G722_SAMPLE_RATE_8000)) + s->eight_k = TRUE; + if ((options & G722_PACKED) && s->bits_per_sample != 8) + s->packed = TRUE; + else + s->packed = FALSE; + s->band[0].det = 32; + s->band[1].det = 8; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int g722_decode_release(g722_decode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len) +{ + static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 }; + static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 }; + static const int ilb[32] = + { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, + 2383, 2435, 2489, 2543, 2599, 2656, 2714, + 2774, 2834, 2896, 2960, 3025, 3091, 3158, + 3228, 3298, 3371, 3444, 3520, 3597, 3676, + 3756, 3838, 3922, 4008 + }; + static const int wh[3] = {0, -214, 798}; + static const int rh2[4] = {2, 1, 2, 1}; + static const int qm2[4] = {-7408, -1616, 7408, 1616}; + static const int qm4[16] = + { + 0, -20456, -12896, -8968, + -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, + 4240, 2584, 1200, 0 + }; + static const int qm5[32] = + { + -280, -280, -23352, -17560, + -14120, -11664, -9752, -8184, + -6864, -5712, -4696, -3784, + -2960, -2208, -1520, -880, + 23352, 17560, 14120, 11664, + 9752, 8184, 6864, 5712, + 4696, 3784, 2960, 2208, + 1520, 880, 280, -280 + }; + static const int qm6[64] = + { + -136, -136, -136, -136, + -24808, -21904, -19008, -16704, + -14984, -13512, -12280, -11192, + -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, + -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, + -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, + 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, + 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, + 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, + 432, 136, -432, -136 + }; + static const int qmf_coeffs[12] = + { + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, + }; + + int dlowt; + int rlow; + int ihigh; + int dhigh; + int rhigh; + int xout1; + int xout2; + int wd1; + int wd2; + int wd3; + int code; + int outlen; + int i; + int j; + + outlen = 0; + rhigh = 0; + for (j = 0; j < len; ) + { + if (s->packed) + { + /* Unpack the code bits */ + if (s->in_bits < s->bits_per_sample) + { + s->in_buffer |= (g722_data[j++] << s->in_bits); + s->in_bits += 8; + } + code = s->in_buffer & ((1 << s->bits_per_sample) - 1); + s->in_buffer >>= s->bits_per_sample; + s->in_bits -= s->bits_per_sample; + } + else + { + code = g722_data[j++]; + } + + switch (s->bits_per_sample) + { + default: + case 8: + wd1 = code & 0x3F; + ihigh = (code >> 6) & 0x03; + wd2 = qm6[wd1]; + wd1 >>= 2; + break; + case 7: + wd1 = code & 0x1F; + ihigh = (code >> 5) & 0x03; + wd2 = qm5[wd1]; + wd1 >>= 1; + break; + case 6: + wd1 = code & 0x0F; + ihigh = (code >> 4) & 0x03; + wd2 = qm4[wd1]; + break; + } + /* Block 5L, LOW BAND INVQBL */ + wd2 = (s->band[0].det*wd2) >> 15; + /* Block 5L, RECONS */ + rlow = s->band[0].s + wd2; + /* Block 6L, LIMIT */ + if (rlow > 16383) + rlow = 16383; + else if (rlow < -16384) + rlow = -16384; + + /* Block 2L, INVQAL */ + wd2 = qm4[wd1]; + dlowt = (s->band[0].det*wd2) >> 15; + + /* Block 3L, LOGSCL */ + wd2 = rl42[wd1]; + wd1 = (s->band[0].nb*127) >> 7; + wd1 += wl[wd2]; + if (wd1 < 0) + wd1 = 0; + else if (wd1 > 18432) + wd1 = 18432; + s->band[0].nb = wd1; + + /* Block 3L, SCALEL */ + wd1 = (s->band[0].nb >> 6) & 31; + wd2 = 8 - (s->band[0].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[0].det = wd3 << 2; + + block4(s, 0, dlowt); + + if (!s->eight_k) + { + /* Block 2H, INVQAH */ + wd2 = qm2[ihigh]; + dhigh = (s->band[1].det*wd2) >> 15; + /* Block 5H, RECONS */ + rhigh = dhigh + s->band[1].s; + /* Block 6H, LIMIT */ + if (rhigh > 16383) + rhigh = 16383; + else if (rhigh < -16384) + rhigh = -16384; + + /* Block 2H, INVQAH */ + wd2 = rh2[ihigh]; + wd1 = (s->band[1].nb*127) >> 7; + wd1 += wh[wd2]; + if (wd1 < 0) + wd1 = 0; + else if (wd1 > 22528) + wd1 = 22528; + s->band[1].nb = wd1; + + /* Block 3H, SCALEH */ + wd1 = (s->band[1].nb >> 6) & 31; + wd2 = 10 - (s->band[1].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[1].det = wd3 << 2; + + block4(s, 1, dhigh); + } + + if (s->itu_test_mode) + { + amp[outlen++] = (int16_t) (rlow << 1); + amp[outlen++] = (int16_t) (rhigh << 1); + } + else + { + if (s->eight_k) + { + amp[outlen++] = (int16_t) rlow; + } + else + { + /* Apply the receive QMF */ + for (i = 0; i < 22; i++) + s->x[i] = s->x[i + 2]; + s->x[22] = rlow + rhigh; + s->x[23] = rlow - rhigh; + + xout1 = 0; + xout2 = 0; + for (i = 0; i < 12; i++) + { + xout2 += s->x[2*i]*qmf_coeffs[i]; + xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i]; + } + amp[outlen++] = (int16_t) (xout1 >> 12); + amp[outlen++] = (int16_t) (xout2 >> 12); + } + } + } + return outlen; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff -r e29937c5670c -r f703b3e14f9a jni/g722/g722_encode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/g722/g722_encode.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,400 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g722_encode.c - The ITU G.722 codec, encode part. + * + * Written by Steve Underwood + * + * Copyright (C) 2005 Steve Underwood + * + * All rights reserved. + * + * Despite my general liking of the GPL, I place my own contributions + * to this code in the public domain for the benefit of all mankind - + * even the slimy ones who might try to proprietize my work and use it + * to my detriment. + * + * Based on a single channel 64kbps only G.722 codec which is: + * + ***** Copyright (c) CMU 1993 ***** + * Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * + * $Id: g722_encode.c 48661 2006-12-21 00:08:21Z mattf $ + */ + +/*! \file */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +//#include +#include +#include +#if 0 +#include +#endif + +#include "g722.h" + +#if !defined(FALSE) +#define FALSE 0 +#endif +#if !defined(TRUE) +#define TRUE (!FALSE) +#endif + +static int16_t saturate(int32_t amp) +{ + int16_t amp16; + + /* Hopefully this is optimised for the common case - not clipping */ + amp16 = (int16_t) amp; + if (amp == amp16) + return amp16; + if (amp > INT16_MAX) + return INT16_MAX; + return INT16_MIN; +} +/*- End of function --------------------------------------------------------*/ + +static void block4(g722_encode_state_t *s, int band, int d) +{ + int wd1; + int wd2; + int wd3; + int i; + + /* Block 4, RECONS */ + s->band[band].d[0] = d; + s->band[band].r[0] = saturate(s->band[band].s + d); + + /* Block 4, PARREC */ + s->band[band].p[0] = saturate(s->band[band].sz + d); + + /* Block 4, UPPOL2 */ + for (i = 0; i < 3; i++) + s->band[band].sg[i] = s->band[band].p[i] >> 15; + wd1 = saturate(s->band[band].a[1] << 2); + + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; + if (wd2 > 32767) + wd2 = 32767; + wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128); + wd3 += (s->band[band].a[2]*32512) >> 15; + if (wd3 > 12288) + wd3 = 12288; + else if (wd3 < -12288) + wd3 = -12288; + s->band[band].ap[2] = wd3; + + /* Block 4, UPPOL1 */ + s->band[band].sg[0] = s->band[band].p[0] >> 15; + s->band[band].sg[1] = s->band[band].p[1] >> 15; + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; + wd2 = (s->band[band].a[1]*32640) >> 15; + + s->band[band].ap[1] = saturate(wd1 + wd2); + wd3 = saturate(15360 - s->band[band].ap[2]); + if (s->band[band].ap[1] > wd3) + s->band[band].ap[1] = wd3; + else if (s->band[band].ap[1] < -wd3) + s->band[band].ap[1] = -wd3; + + /* Block 4, UPZERO */ + wd1 = (d == 0) ? 0 : 128; + s->band[band].sg[0] = d >> 15; + for (i = 1; i < 7; i++) + { + s->band[band].sg[i] = s->band[band].d[i] >> 15; + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; + wd3 = (s->band[band].b[i]*32640) >> 15; + s->band[band].bp[i] = saturate(wd2 + wd3); + } + + /* Block 4, DELAYA */ + for (i = 6; i > 0; i--) + { + s->band[band].d[i] = s->band[band].d[i - 1]; + s->band[band].b[i] = s->band[band].bp[i]; + } + + for (i = 2; i > 0; i--) + { + s->band[band].r[i] = s->band[band].r[i - 1]; + s->band[band].p[i] = s->band[band].p[i - 1]; + s->band[band].a[i] = s->band[band].ap[i]; + } + + /* Block 4, FILTEP */ + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); + wd1 = (s->band[band].a[1]*wd1) >> 15; + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); + wd2 = (s->band[band].a[2]*wd2) >> 15; + s->band[band].sp = saturate(wd1 + wd2); + + /* Block 4, FILTEZ */ + s->band[band].sz = 0; + for (i = 6; i > 0; i--) + { + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; + } + s->band[band].sz = saturate(s->band[band].sz); + + /* Block 4, PREDIC */ + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); +} +/*- End of function --------------------------------------------------------*/ + +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options) +{ + if (s == NULL) + { + if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + if (rate == 48000) + s->bits_per_sample = 6; + else if (rate == 56000) + s->bits_per_sample = 7; + else + s->bits_per_sample = 8; + if ((options & G722_SAMPLE_RATE_8000)) + s->eight_k = TRUE; + if ((options & G722_PACKED) && s->bits_per_sample != 8) + s->packed = TRUE; + else + s->packed = FALSE; + s->band[0].det = 32; + s->band[1].det = 8; + return s; +} +/*- End of function --------------------------------------------------------*/ + +int g722_encode_release(g722_encode_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len) +{ + static const int q6[32] = + { + 0, 35, 72, 110, 150, 190, 233, 276, + 323, 370, 422, 473, 530, 587, 650, 714, + 786, 858, 940, 1023, 1121, 1219, 1339, 1458, + 1612, 1765, 1980, 2195, 2557, 2919, 0, 0 + }; + static const int iln[32] = + { + 0, 63, 62, 31, 30, 29, 28, 27, + 26, 25, 24, 23, 22, 21, 20, 19, + 18, 17, 16, 15, 14, 13, 12, 11, + 10, 9, 8, 7, 6, 5, 4, 0 + }; + static const int ilp[32] = + { + 0, 61, 60, 59, 58, 57, 56, 55, + 54, 53, 52, 51, 50, 49, 48, 47, + 46, 45, 44, 43, 42, 41, 40, 39, + 38, 37, 36, 35, 34, 33, 32, 0 + }; + static const int wl[8] = + { + -60, -30, 58, 172, 334, 538, 1198, 3042 + }; + static const int rl42[16] = + { + 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 + }; + static const int ilb[32] = + { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, + 2383, 2435, 2489, 2543, 2599, 2656, 2714, + 2774, 2834, 2896, 2960, 3025, 3091, 3158, + 3228, 3298, 3371, 3444, 3520, 3597, 3676, + 3756, 3838, 3922, 4008 + }; + static const int qm4[16] = + { + 0, -20456, -12896, -8968, + -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, + 4240, 2584, 1200, 0 + }; + static const int qm2[4] = + { + -7408, -1616, 7408, 1616 + }; + static const int qmf_coeffs[12] = + { + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, + }; + static const int ihn[3] = {0, 1, 0}; + static const int ihp[3] = {0, 3, 2}; + static const int wh[3] = {0, -214, 798}; + static const int rh2[4] = {2, 1, 2, 1}; + + int dlow; + int dhigh; + int el; + int wd; + int wd1; + int ril; + int wd2; + int il4; + int ih2; + int wd3; + int eh; + int mih; + int i; + int j; + /* Low and high band PCM from the QMF */ + int xlow; + int xhigh; + int g722_bytes; + /* Even and odd tap accumulators */ + int sumeven; + int sumodd; + int ihigh; + int ilow; + int code; + + g722_bytes = 0; + xhigh = 0; + for (j = 0; j < len; ) + { + if (s->itu_test_mode) + { + xlow = + xhigh = amp[j++] >> 1; + } + else + { + if (s->eight_k) + { + xlow = amp[j++]; + } + else + { + /* Apply the transmit QMF */ + /* Shuffle the buffer down */ + for (i = 0; i < 22; i++) + s->x[i] = s->x[i + 2]; + s->x[22] = amp[j++]; + s->x[23] = amp[j++]; + + /* Discard every other QMF output */ + sumeven = 0; + sumodd = 0; + for (i = 0; i < 12; i++) + { + sumodd += s->x[2*i]*qmf_coeffs[i]; + sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i]; + } + xlow = (sumeven + sumodd) >> 13; + xhigh = (sumeven - sumodd) >> 13; + } + } + /* Block 1L, SUBTRA */ + el = saturate(xlow - s->band[0].s); + + /* Block 1L, QUANTL */ + wd = (el >= 0) ? el : -(el + 1); + + for (i = 1; i < 30; i++) + { + wd1 = (q6[i]*s->band[0].det) >> 12; + if (wd < wd1) + break; + } + ilow = (el < 0) ? iln[i] : ilp[i]; + + /* Block 2L, INVQAL */ + ril = ilow >> 2; + wd2 = qm4[ril]; + dlow = (s->band[0].det*wd2) >> 15; + + /* Block 3L, LOGSCL */ + il4 = rl42[ril]; + wd = (s->band[0].nb*127) >> 7; + s->band[0].nb = wd + wl[il4]; + if (s->band[0].nb < 0) + s->band[0].nb = 0; + else if (s->band[0].nb > 18432) + s->band[0].nb = 18432; + + /* Block 3L, SCALEL */ + wd1 = (s->band[0].nb >> 6) & 31; + wd2 = 8 - (s->band[0].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[0].det = wd3 << 2; + + block4(s, 0, dlow); + + if (s->eight_k) + { + /* Just leave the high bits as zero */ + code = (0xC0 | ilow) >> (8 - s->bits_per_sample); + } + else + { + /* Block 1H, SUBTRA */ + eh = saturate(xhigh - s->band[1].s); + + /* Block 1H, QUANTH */ + wd = (eh >= 0) ? eh : -(eh + 1); + wd1 = (564*s->band[1].det) >> 12; + mih = (wd >= wd1) ? 2 : 1; + ihigh = (eh < 0) ? ihn[mih] : ihp[mih]; + + /* Block 2H, INVQAH */ + wd2 = qm2[ihigh]; + dhigh = (s->band[1].det*wd2) >> 15; + + /* Block 3H, LOGSCH */ + ih2 = rh2[ihigh]; + wd = (s->band[1].nb*127) >> 7; + s->band[1].nb = wd + wh[ih2]; + if (s->band[1].nb < 0) + s->band[1].nb = 0; + else if (s->band[1].nb > 22528) + s->band[1].nb = 22528; + + /* Block 3H, SCALEH */ + wd1 = (s->band[1].nb >> 6) & 31; + wd2 = 10 - (s->band[1].nb >> 11); + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); + s->band[1].det = wd3 << 2; + + block4(s, 1, dhigh); + code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample); + } + + if (s->packed) + { + /* Pack the code bits */ + s->out_buffer |= (code << s->out_bits); + s->out_bits += s->bits_per_sample; + if (s->out_bits >= 8) + { + g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF); + s->out_bits -= 8; + s->out_buffer >>= 8; + } + } + else + { + g722_data[g722_bytes++] = (uint8_t) code; + } + } + return g722_bytes; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff -r e29937c5670c -r f703b3e14f9a jni/g722/g722_jni.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/g722/g722_jni.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,80 @@ +/** + +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options); +int g722_encode_release(g722_encode_state_t *s); +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len); + +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options); +int g722_decode_release(g722_decode_state_t *s); +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len); + +*/ + +#include +#include "g722.h" + +jlong +Java_org_sipdroid_media_codecs_G722JNI_encodeInit(JNIEnv *env, jlong jg722State, jint rate, jint options) +{ + return g722_encode_init((void *) jg722State, rate, options); +} + +jint +Java_org_sipdroid_media_codecs_G722JNI_encodeRelease(JNIEnv *env, jlong jg722State) +{ + return g722_encode_release((void *) jg722State); +} + +jint +Java_org_sipdroid_media_codecs_G722JNI_encode(JNIEnv *env, jlong jg722State, jshortArray jsignal, jlong jsrcPos, jbyteArray jg722Byte, jlong jdestPos, jint len) +{ + jshort *signal; + jbyte *g722Byte; + jboolean isCopyByte; + jboolean isCopySignal; + void *ctx = (void *) jg722State; + jint res; + + g722Byte = (*env)->GetByteArrayElements(env, jg722Byte, &isCopyByte); + signal = (*env)->GetShortArrayElements(env, jsignal, &isCopySignal); + + res = g722_encode(ctx, g722Byte + jdestPos, signal + jsrcPos, len); + if (isCopyByte == JNI_TRUE) + (*env)->ReleaseByteArrayElements(env, jg722Byte, g722Byte, 0); + if (isCopySignal == JNI_TRUE) + (*env)->ReleaseShortArrayElements(env, jsignal, signal, 0); + return res; +} + +jlong +Java_org_sipdroid_media_codecs_G722JNI_decodeInit(JNIEnv *env, jlong jg722State, jint rate, jint options) +{ + return g722_decode_init((void *) jg722State, rate, options); +} + +jint +Java_org_sipdroid_media_codecs_G722JNI_decodeRelease(JNIEnv *env, jlong jg722State) +{ + return g722_decode_release((void *) jg722State); +} + +jint +Java_org_sipdroid_media_codecs_G722JNI_decode(JNIEnv *env, jlong jg722State, jbyteArray jg722Byte, jlong jsrcPos, jshortArray jsignal, jlong jdestPos, jint len) +{ + jshort *signal; + jbyte *g722Byte; + jboolean isCopyByte; + jboolean isCopySignal; + void *ctx = (void *) jg722State; + jint res; + + g722Byte = (*env)->GetByteArrayElements(env, jg722Byte, &isCopyByte); + signal = (*env)->GetShortArrayElements(env, jsignal, &isCopySignal); + + res = g722_decode(ctx, signal + jdestPos, g722Byte + jsrcPos, len); + if (isCopyByte == JNI_TRUE) + (*env)->ReleaseByteArrayElements(env, jg722Byte, g722Byte, 0); + if (isCopySignal == JNI_TRUE) + (*env)->ReleaseShortArrayElements(env, jsignal, signal, 0); + return res; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/Android.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/Android.mk Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,19 @@ +SRC_FILES := add.c\ + code.c\ + debug.c\ + decode.c\ + gsm_create.c\ + gsm_decode.c\ + gsm_destroy.c\ + gsm_encode.c\ + gsm_explode.c\ + gsm_implode.c\ + gsm_option.c\ + gsm_print.c\ + long_term.c\ + lpc.c\ + preprocess.c\ + rpe.c\ + short_term.c\ + table.c\ + gsm_jni.c diff -r e29937c5670c -r f703b3e14f9a jni/gsm/add.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/add.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,235 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/add.c,v 1.6 1996/07/02 09:57:33 jutta Exp $ */ + +/* + * See private.h for the more commonly used macro versions. + */ + +#include +#include + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +#define saturate(x) \ + ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) + +word gsm_add P2((a,b), word a, word b) +{ + longword sum = (longword)a + (longword)b; + return saturate(sum); +} + +word gsm_sub P2((a,b), word a, word b) +{ + longword diff = (longword)a - (longword)b; + return saturate(diff); +} + +word gsm_mult P2((a,b), word a, word b) +{ + if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD; + else return SASR( (longword)a * (longword)b, 15 ); +} + +word gsm_mult_r P2((a,b), word a, word b) +{ + if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD; + else { + longword prod = (longword)a * (longword)b + 16384; + prod >>= 15; + return prod & 0xFFFF; + } +} + +word gsm_abs P1((a), word a) +{ + return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; +} + +longword gsm_L_mult P2((a,b),word a, word b) +{ + assert( a != MIN_WORD || b != MIN_WORD ); + return ((longword)a * (longword)b) << 1; +} + +longword gsm_L_add P2((a,b), longword a, longword b) +{ + if (a < 0) { + if (b >= 0) return a + b; + else { + ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1); + return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2; + } + } + else if (b <= 0) return a + b; + else { + ulongword A = (ulongword)a + (ulongword)b; + return A > MAX_LONGWORD ? MAX_LONGWORD : A; + } +} + +longword gsm_L_sub P2((a,b), longword a, longword b) +{ + if (a >= 0) { + if (b >= 0) return a - b; + else { + /* a>=0, b<0 */ + + ulongword A = (ulongword)a + -(b + 1); + return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1); + } + } + else if (b <= 0) return a - b; + else { + /* a<0, b>0 */ + + ulongword A = (ulongword)-(a + 1) + b; + return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1; + } +} + +static unsigned char const bitoff[ 256 ] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +word gsm_norm P1((a), longword a ) +/* + * the number of left shifts needed to normalize the 32 bit + * variable L_var1 for positive values on the interval + * + * with minimum of + * minimum of 1073741824 (01000000000000000000000000000000) and + * maximum of 2147483647 (01111111111111111111111111111111) + * + * + * and for negative values on the interval with + * minimum of -2147483648 (-10000000000000000000000000000000) and + * maximum of -1073741824 ( -1000000000000000000000000000000). + * + * in order to normalize the result, the following + * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); + * + * (That's 'ffs', only from the left, not the right..) + */ +{ + assert(a != 0); + + if (a < 0) { + if (a <= -1073741824) return 0; + a = ~a; + } + + return a & 0xffff0000 + ? ( a & 0xff000000 + ? -1 + bitoff[ 0xFF & (a >> 24) ] + : 7 + bitoff[ 0xFF & (a >> 16) ] ) + : ( a & 0xff00 + ? 15 + bitoff[ 0xFF & (a >> 8) ] + : 23 + bitoff[ 0xFF & a ] ); +} + +longword gsm_L_asl P2((a,n), longword a, int n) +{ + if (n >= 32) return 0; + if (n <= -32) return -(a < 0); + if (n < 0) return gsm_L_asr(a, -n); + return a << n; +} + +word gsm_asl P2((a,n), word a, int n) +{ + if (n >= 16) return 0; + if (n <= -16) return -(a < 0); + if (n < 0) return gsm_asr(a, -n); + return a << n; +} + +longword gsm_L_asr P2((a,n), longword a, int n) +{ + if (n >= 32) return -(a < 0); + if (n <= -32) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(longword)( -(ulongword)a >> n ); +# endif +} + +word gsm_asr P2((a,n), word a, int n) +{ + if (n >= 16) return -(a < 0); + if (n <= -16) return 0; + if (n < 0) return a << -n; + +# ifdef SASR + return a >> n; +# else + if (a >= 0) return a >> n; + else return -(word)( -(uword)a >> n ); +# endif +} + +/* + * (From p. 46, end of section 4.2.5) + * + * NOTE: The following lines gives [sic] one correct implementation + * of the div(num, denum) arithmetic operation. Compute div + * which is the integer division of num by denum: with denum + * >= num > 0 + */ + +word gsm_div P2((num,denum), word num, word denum) +{ + longword L_num = num; + longword L_denum = denum; + word div = 0; + int k = 15; + + /* The parameter num sometimes becomes zero. + * Although this is explicitly guarded against in 4.2.5, + * we assume that the result should then be zero as well. + */ + + /* assert(num != 0); */ + + assert(num >= 0 && denum >= num); + if (num == 0) + return 0; + + while (k--) { + div <<= 1; + L_num <<= 1; + + if (L_num >= L_denum) { + L_num -= L_denum; + div++; + } + } + + return div; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/code.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/code.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,104 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/code.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */ + +#include "config.h" + +#include + +#ifdef HAS_STDLIB_H +#include +#else +# include "proto.h" + extern char * memcpy P((char *, char *, int)); +#endif + +#include "private.h" +#include "gsm.h" +#include "proto.h" + + +/* + * 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER + */ + +void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc), + + struct gsm_state * S, + + word * s, /* [0..159] samples IN */ + +/* + * The RPE-LTD coder works on a frame by frame basis. The length of + * the frame is equal to 160 samples. Some computations are done + * once per frame to produce at the output of the coder the + * LARc[1..8] parameters which are the coded LAR coefficients and + * also to realize the inverse filtering operation for the entire + * frame (160 samples of signal d[0..159]). These parts produce at + * the output of the coder: + */ + + word * LARc, /* [0..7] LAR coefficients OUT */ + +/* + * Procedure 4.2.11 to 4.2.18 are to be executed four times per + * frame. That means once for each sub-segment RPE-LTP analysis of + * 40 samples. These parts produce at the output of the coder: + */ + + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */ +) +{ + int k; + word * dp = S->dp0 + 120; /* [ -120...-1 ] */ + word * dpp = dp; /* [ 0...39 ] */ + + static word e[50]; + + word so[160]; + + Gsm_Preprocess (S, s, so); + Gsm_LPC_Analysis (S, so, LARc); + Gsm_Short_Term_Analysis_Filter (S, LARc, so); + + for (k = 0; k <= 3; k++, xMc += 13) { + + Gsm_Long_Term_Predictor ( S, + so+k*40, /* d [0..39] IN */ + dp, /* dp [-120..-1] IN */ + e + 5, /* e [0..39] OUT */ + dpp, /* dpp [0..39] OUT */ + Nc++, + bc++); + + Gsm_RPE_Encoding ( S, + e + 5, /* e ][0..39][ IN/OUT */ + xmaxc++, Mc++, xMc ); + /* + * Gsm_Update_of_reconstructed_short_time_residual_signal + * ( dpp, e + 5, dp ); + */ + + { register int i; + register longword ltmp; + for (i = 0; i <= 39; i++) + dp[ i ] = GSM_ADD( e[5 + i], dpp[i] ); + } + dp += 40; + dpp += 40; + + } + + (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), + 120 * sizeof(*S->dp0) ); + + +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/config.h Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/ + +#ifndef CONFIG_H +#define CONFIG_H + +//efine SIGHANDLER_T int /* signal handlers are void */ +//efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */ + +#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */ +//efine HAS_LIMITS_H 1 /* /usr/include/limits.h */ +#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */ +//efine HAS_ERRNO_DECL 1 /* errno.h declares errno */ + +#define HAS_FSTAT 1 /* fstat syscall */ +#define HAS_FCHMOD 1 /* fchmod syscall */ +#define HAS_CHMOD 1 /* chmod syscall */ +#define HAS_FCHOWN 1 /* fchown syscall */ +#define HAS_CHOWN 1 /* chown syscall */ +//efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */ + +#define HAS_STRING_H 1 /* /usr/include/string.h */ +//efine HAS_STRINGS_H 1 /* /usr/include/strings.h */ + +#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */ +#define HAS_UTIME 1 /* POSIX utime(path, times) */ +//efine HAS_UTIMES 1 /* use utimes() syscall instead */ +#define HAS_UTIME_H 1 /* UTIME header file */ +//efine HAS_UTIMBUF 1 /* struct utimbuf */ +//efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */ + +#endif /* CONFIG_H */ diff -r e29937c5670c -r f703b3e14f9a jni/gsm/debug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/debug.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,76 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/debug.c,v 1.2 1993/01/29 18:22:20 jutta Exp $ */ + +#include "private.h" + +#ifndef NDEBUG + +/* If NDEBUG _is_ defined and no debugging should be performed, + * calls to functions in this module are #defined to nothing + * in private.h. + */ + +#include +#include "proto.h" + +void gsm_debug_words P4( (name, from, to, ptr), + char * name, + int from, + int to, + word * ptr) +{ + int nprinted = 0; + + fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); + while (from <= to) { + fprintf(stderr, "%d ", ptr[ from ] ); + from++; + if (nprinted++ >= 7) { + nprinted = 0; + if (from < to) putc('\n', stderr); + } + } + putc('\n', stderr); +} + +void gsm_debug_longwords P4( (name, from, to, ptr), + char * name, + int from, + int to, + longword * ptr) +{ + int nprinted = 0; + + fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); + while (from <= to) { + + fprintf(stderr, "%ld ", ptr[ from ] ); + from++; + if (nprinted++ >= 7) { + nprinted = 0; + if (from < to) putc('\n', stderr); + } + } + putc('\n', stderr); +} + +void gsm_debug_longword P2( (name, value), + char * name, + longword value ) +{ + fprintf(stderr, "%s: %ld\n", name, (long)value ); +} + +void gsm_debug_word P2( (name, value), + char * name, + word value ) +{ + fprintf(stderr, "%s: %ld\n", name, (long)value); +} + +#endif diff -r e29937c5670c -r f703b3e14f9a jni/gsm/decode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/decode.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/decode.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */ + +#include + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +/* + * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER + */ + +static void Postprocessing P2((S,s), + struct gsm_state * S, + register word * s) +{ + register int k; + register word msr = S->msr; + register longword ltmp; /* for GSM_ADD */ + register word tmp; + + for (k = 160; k--; s++) { + tmp = GSM_MULT_R( msr, 28180 ); + msr = GSM_ADD(*s, tmp); /* Deemphasis */ + *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ + } + S->msr = msr; +} + +void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s), + struct gsm_state * S, + + word * LARcr, /* [0..7] IN */ + + word * Ncr, /* [0..3] IN */ + word * bcr, /* [0..3] IN */ + word * Mcr, /* [0..3] IN */ + word * xmaxcr, /* [0..3] IN */ + word * xMcr, /* [0..13*4] IN */ + + word * s) /* [0..159] OUT */ +{ + int j, k; + word erp[40], wt[160]; + word * drp = S->dp0 + 120; + + for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { + + Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); + Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); + + for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; + } + + Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); + Postprocessing(S, s); +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm.h Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,71 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /home/kbs/jutta/src/gsm/gsm-1.0/inc/RCS/gsm.h,v 1.11 1996/07/05 18:02:56 jutta Exp $*/ + +#ifndef GSM_H +#define GSM_H + +#ifdef __cplusplus +# define NeedFunctionPrototypes 1 +#endif + +#if __STDC__ +# define NeedFunctionPrototypes 1 +#endif + +#ifdef _NO_PROTO +# undef NeedFunctionPrototypes +#endif + +#ifdef NeedFunctionPrototypes +# include /* for FILE * */ +#endif + +#undef GSM_P +#if NeedFunctionPrototypes +# define GSM_P( protos ) protos +#else +# define GSM_P( protos ) ( /* protos */ ) +#endif + +/* + * Interface + */ + +typedef struct gsm_state * gsm; +typedef short gsm_signal; /* signed 16 bit */ +typedef unsigned char gsm_byte; +typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ + +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +#define GSM_PATCHLEVEL 10 +#define GSM_MINOR 0 +#define GSM_MAJOR 1 + +#define GSM_OPT_VERBOSE 1 +#define GSM_OPT_FAST 2 +#define GSM_OPT_LTP_CUT 3 +#define GSM_OPT_WAV49 4 +#define GSM_OPT_FRAME_INDEX 5 +#define GSM_OPT_FRAME_CHAIN 6 + +extern gsm gsm_create GSM_P((void)); +extern void gsm_destroy GSM_P((gsm)); + +extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); +extern int gsm_option GSM_P((gsm, int, int *)); + +extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); +extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); + +extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); +extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); + +#undef GSM_P + +#endif /* GSM_H */ diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_create.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_create.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +static char const ident[] = "$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_create.c,v 1.4 1996/07/02 09:59:05 jutta Exp $"; + +#include "config.h" + +#ifdef HAS_STRING_H +#include +#else +# include "proto.h" + extern char * memset P((char *, int, int)); +#endif + +#ifdef HAS_STDLIB_H +# include +#else +# ifdef HAS_MALLOC_H +# include +# else + extern char * malloc(); +# endif +#endif + +#include + +#include "gsm.h" +#include "private.h" +#include "proto.h" + +gsm gsm_create P0() +{ + gsm r; + + r = (gsm)malloc(sizeof(struct gsm_state)); + if (!r) return r; + + memset((char *)r, 0, sizeof(*r)); + r->nrp = 40; + + return r; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_decode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_decode.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,361 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_decode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */ + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + +#ifdef WAV49 + if (s->wav_fmt) { + + uword sr = 0; + + s->frame_index = !s->frame_index; + if (s->frame_index) { + + sr = *c++; + LARc[0] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 2; + LARc[1] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 4; + LARc[2] = sr & 0x1f; sr >>= 5; + LARc[3] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 2; + LARc[4] = sr & 0xf; sr >>= 4; + LARc[5] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; /* 5 */ + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[0] = sr & 0x7f; sr >>= 7; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[0] = sr & 0x3f; sr >>= 6; + xmc[0] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[1] = sr & 0x7; sr >>= 3; + xmc[2] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + xmc[5] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 10 */ + xmc[6] = sr & 0x7; sr >>= 3; + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[9] = sr & 0x7; sr >>= 3; + xmc[10] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[1] = sr & 0x7f; sr >>= 7; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[1] = sr & 0x3f; sr >>= 6; + xmc[13] = sr & 0x7; sr >>= 3; + sr = *c++; /* 15 */ + xmc[14] = sr & 0x7; sr >>= 3; + xmc[15] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + xmc[18] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[19] = sr & 0x7; sr >>= 3; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[22] = sr & 0x7; sr >>= 3; + xmc[23] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; /* 20 */ + Nc[2] = sr & 0x7f; sr >>= 7; + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[2] = sr & 0x3f; sr >>= 6; + xmc[26] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[27] = sr & 0x7; sr >>= 3; + xmc[28] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + xmc[31] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[32] = sr & 0x7; sr >>= 3; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + sr = *c++; /* 25 */ + xmc[35] = sr & 0x7; sr >>= 3; + xmc[36] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[3] = sr & 0x7f; sr >>= 7; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[3] = sr & 0x3f; sr >>= 6; + xmc[39] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[40] = sr & 0x7; sr >>= 3; + xmc[41] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 30 */ + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + xmc[44] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[45] = sr & 0x7; sr >>= 3; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[48] = sr & 0x7; sr >>= 3; + xmc[49] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + + s->frame_chain = sr & 0xf; + } + else { + sr = s->frame_chain; + sr |= (uword)*c++ << 4; /* 1 */ + LARc[0] = sr & 0x3f; sr >>= 6; + LARc[1] = sr & 0x3f; sr >>= 6; + sr = *c++; + LARc[2] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 3; + LARc[3] = sr & 0x1f; sr >>= 5; + LARc[4] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; + LARc[5] = sr & 0xf; sr >>= 4; + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr = *c++; /* 5 */ + Nc[0] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[0] = sr & 0x3f; sr >>= 6; + xmc[0] = sr & 0x7; sr >>= 3; + xmc[1] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[2] = sr & 0x7; sr >>= 3; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[5] = sr & 0x7; sr >>= 3; + xmc[6] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 10 */ + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + xmc[9] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[10] = sr & 0x7; sr >>= 3; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[1] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[1] = sr & 0x3f; sr >>= 6; + xmc[13] = sr & 0x7; sr >>= 3; + xmc[14] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 15 */ + xmc[15] = sr & 0x7; sr >>= 3; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[18] = sr & 0x7; sr >>= 3; + xmc[19] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + xmc[22] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[23] = sr & 0x7; sr >>= 3; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[2] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; /* 20 */ + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[2] = sr & 0x3f; sr >>= 6; + xmc[26] = sr & 0x7; sr >>= 3; + xmc[27] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[28] = sr & 0x7; sr >>= 3; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[31] = sr & 0x7; sr >>= 3; + xmc[32] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + xmc[35] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 25 */ + xmc[36] = sr & 0x7; sr >>= 3; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[3] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[3] = sr & 0x3f; sr >>= 6; + xmc[39] = sr & 0x7; sr >>= 3; + xmc[40] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[41] = sr & 0x7; sr >>= 3; + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + sr = *c++; /* 30 */ + xmc[44] = sr & 0x7; sr >>= 3; + xmc[45] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + xmc[48] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[49] = sr & 0x7; sr >>= 3; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + } + } + else +#endif + { + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; + + LARc[0] = (*c++ & 0xF) << 2; /* 1 */ + LARc[0] |= (*c >> 6) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = (*c >> 3) & 0x1F; + LARc[3] = (*c++ & 0x7) << 2; + LARc[3] |= (*c >> 6) & 0x3; + LARc[4] = (*c >> 2) & 0xF; + LARc[5] = (*c++ & 0x3) << 2; + LARc[5] |= (*c >> 6) & 0x3; + LARc[6] = (*c >> 3) & 0x7; + LARc[7] = *c++ & 0x7; + Nc[0] = (*c >> 1) & 0x7F; + bc[0] = (*c++ & 0x1) << 1; + bc[0] |= (*c >> 7) & 0x1; + Mc[0] = (*c >> 5) & 0x3; + xmaxc[0] = (*c++ & 0x1F) << 1; + xmaxc[0] |= (*c >> 7) & 0x1; + xmc[0] = (*c >> 4) & 0x7; + xmc[1] = (*c >> 1) & 0x7; + xmc[2] = (*c++ & 0x1) << 2; + xmc[2] |= (*c >> 6) & 0x3; + xmc[3] = (*c >> 3) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = (*c >> 5) & 0x7; + xmc[6] = (*c >> 2) & 0x7; + xmc[7] = (*c++ & 0x3) << 1; /* 10 */ + xmc[7] |= (*c >> 7) & 0x1; + xmc[8] = (*c >> 4) & 0x7; + xmc[9] = (*c >> 1) & 0x7; + xmc[10] = (*c++ & 0x1) << 2; + xmc[10] |= (*c >> 6) & 0x3; + xmc[11] = (*c >> 3) & 0x7; + xmc[12] = *c++ & 0x7; + Nc[1] = (*c >> 1) & 0x7F; + bc[1] = (*c++ & 0x1) << 1; + bc[1] |= (*c >> 7) & 0x1; + Mc[1] = (*c >> 5) & 0x3; + xmaxc[1] = (*c++ & 0x1F) << 1; + xmaxc[1] |= (*c >> 7) & 0x1; + xmc[13] = (*c >> 4) & 0x7; + xmc[14] = (*c >> 1) & 0x7; + xmc[15] = (*c++ & 0x1) << 2; + xmc[15] |= (*c >> 6) & 0x3; + xmc[16] = (*c >> 3) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = (*c >> 5) & 0x7; + xmc[19] = (*c >> 2) & 0x7; + xmc[20] = (*c++ & 0x3) << 1; + xmc[20] |= (*c >> 7) & 0x1; + xmc[21] = (*c >> 4) & 0x7; + xmc[22] = (*c >> 1) & 0x7; + xmc[23] = (*c++ & 0x1) << 2; + xmc[23] |= (*c >> 6) & 0x3; + xmc[24] = (*c >> 3) & 0x7; + xmc[25] = *c++ & 0x7; + Nc[2] = (*c >> 1) & 0x7F; + bc[2] = (*c++ & 0x1) << 1; /* 20 */ + bc[2] |= (*c >> 7) & 0x1; + Mc[2] = (*c >> 5) & 0x3; + xmaxc[2] = (*c++ & 0x1F) << 1; + xmaxc[2] |= (*c >> 7) & 0x1; + xmc[26] = (*c >> 4) & 0x7; + xmc[27] = (*c >> 1) & 0x7; + xmc[28] = (*c++ & 0x1) << 2; + xmc[28] |= (*c >> 6) & 0x3; + xmc[29] = (*c >> 3) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = (*c >> 5) & 0x7; + xmc[32] = (*c >> 2) & 0x7; + xmc[33] = (*c++ & 0x3) << 1; + xmc[33] |= (*c >> 7) & 0x1; + xmc[34] = (*c >> 4) & 0x7; + xmc[35] = (*c >> 1) & 0x7; + xmc[36] = (*c++ & 0x1) << 2; + xmc[36] |= (*c >> 6) & 0x3; + xmc[37] = (*c >> 3) & 0x7; + xmc[38] = *c++ & 0x7; + Nc[3] = (*c >> 1) & 0x7F; + bc[3] = (*c++ & 0x1) << 1; + bc[3] |= (*c >> 7) & 0x1; + Mc[3] = (*c >> 5) & 0x3; + xmaxc[3] = (*c++ & 0x1F) << 1; + xmaxc[3] |= (*c >> 7) & 0x1; + xmc[39] = (*c >> 4) & 0x7; + xmc[40] = (*c >> 1) & 0x7; + xmc[41] = (*c++ & 0x1) << 2; + xmc[41] |= (*c >> 6) & 0x3; + xmc[42] = (*c >> 3) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = (*c >> 5) & 0x7; + xmc[45] = (*c >> 2) & 0x7; + xmc[46] = (*c++ & 0x3) << 1; + xmc[46] |= (*c >> 7) & 0x1; + xmc[47] = (*c >> 4) & 0x7; + xmc[48] = (*c >> 1) & 0x7; + xmc[49] = (*c++ & 0x1) << 2; + xmc[49] |= (*c >> 6) & 0x3; + xmc[50] = (*c >> 3) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + } + + Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); + + return 0; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_destroy.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_destroy.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,26 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_destroy.c,v 1.3 1994/11/28 19:52:25 jutta Exp $ */ + +#include "gsm.h" +#include "config.h" +#include "proto.h" + +#ifdef HAS_STDLIB_H +# include +#else +# ifdef HAS_MALLOC_H +# include +# else + extern void free(); +# endif +#endif + +void gsm_destroy P1((S), gsm S) +{ + if (S) free((char *)S); +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_encode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_encode.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,451 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_encode.c,v 1.2 1996/07/02 09:59:05 jutta Exp $ */ + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); + + + /* variable size + + GSM_MAGIC 4 + + LARc[0] 6 + LARc[1] 6 + LARc[2] 5 + LARc[3] 5 + LARc[4] 4 + LARc[5] 4 + LARc[6] 3 + LARc[7] 3 + + Nc[0] 7 + bc[0] 2 + Mc[0] 2 + xmaxc[0] 6 + xmc[0] 3 + xmc[1] 3 + xmc[2] 3 + xmc[3] 3 + xmc[4] 3 + xmc[5] 3 + xmc[6] 3 + xmc[7] 3 + xmc[8] 3 + xmc[9] 3 + xmc[10] 3 + xmc[11] 3 + xmc[12] 3 + + Nc[1] 7 + bc[1] 2 + Mc[1] 2 + xmaxc[1] 6 + xmc[13] 3 + xmc[14] 3 + xmc[15] 3 + xmc[16] 3 + xmc[17] 3 + xmc[18] 3 + xmc[19] 3 + xmc[20] 3 + xmc[21] 3 + xmc[22] 3 + xmc[23] 3 + xmc[24] 3 + xmc[25] 3 + + Nc[2] 7 + bc[2] 2 + Mc[2] 2 + xmaxc[2] 6 + xmc[26] 3 + xmc[27] 3 + xmc[28] 3 + xmc[29] 3 + xmc[30] 3 + xmc[31] 3 + xmc[32] 3 + xmc[33] 3 + xmc[34] 3 + xmc[35] 3 + xmc[36] 3 + xmc[37] 3 + xmc[38] 3 + + Nc[3] 7 + bc[3] 2 + Mc[3] 2 + xmaxc[3] 6 + xmc[39] 3 + xmc[40] 3 + xmc[41] 3 + xmc[42] 3 + xmc[43] 3 + xmc[44] 3 + xmc[45] 3 + xmc[46] 3 + xmc[47] 3 + xmc[48] 3 + xmc[49] 3 + xmc[50] 3 + xmc[51] 3 + */ + +#ifdef WAV49 + + if (s->wav_fmt) { + s->frame_index = !s->frame_index; + if (s->frame_index) { + + uword sr; + + sr = 0; + sr = sr >> 6 | LARc[0] << 10; + sr = sr >> 6 | LARc[1] << 10; + *c++ = sr >> 4; + sr = sr >> 5 | LARc[2] << 11; + *c++ = sr >> 7; + sr = sr >> 5 | LARc[3] << 11; + sr = sr >> 4 | LARc[4] << 12; + *c++ = sr >> 6; + sr = sr >> 4 | LARc[5] << 12; + sr = sr >> 3 | LARc[6] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | LARc[7] << 13; + sr = sr >> 7 | Nc[0] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[0] << 14; + sr = sr >> 2 | Mc[0] << 14; + sr = sr >> 6 | xmaxc[0] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[0] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[1] << 13; + sr = sr >> 3 | xmc[2] << 13; + sr = sr >> 3 | xmc[3] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[4] << 13; + sr = sr >> 3 | xmc[5] << 13; + sr = sr >> 3 | xmc[6] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[7] << 13; + sr = sr >> 3 | xmc[8] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[9] << 13; + sr = sr >> 3 | xmc[10] << 13; + sr = sr >> 3 | xmc[11] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[12] << 13; + sr = sr >> 7 | Nc[1] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[1] << 14; + sr = sr >> 2 | Mc[1] << 14; + sr = sr >> 6 | xmaxc[1] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[13] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[14] << 13; + sr = sr >> 3 | xmc[15] << 13; + sr = sr >> 3 | xmc[16] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[17] << 13; + sr = sr >> 3 | xmc[18] << 13; + sr = sr >> 3 | xmc[19] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[20] << 13; + sr = sr >> 3 | xmc[21] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[22] << 13; + sr = sr >> 3 | xmc[23] << 13; + sr = sr >> 3 | xmc[24] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[25] << 13; + sr = sr >> 7 | Nc[2] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[2] << 14; + sr = sr >> 2 | Mc[2] << 14; + sr = sr >> 6 | xmaxc[2] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[26] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[27] << 13; + sr = sr >> 3 | xmc[28] << 13; + sr = sr >> 3 | xmc[29] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[30] << 13; + sr = sr >> 3 | xmc[31] << 13; + sr = sr >> 3 | xmc[32] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[33] << 13; + sr = sr >> 3 | xmc[34] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[35] << 13; + sr = sr >> 3 | xmc[36] << 13; + sr = sr >> 3 | xmc[37] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[38] << 13; + sr = sr >> 7 | Nc[3] << 9; + *c++ = sr >> 5; + sr = sr >> 2 | bc[3] << 14; + sr = sr >> 2 | Mc[3] << 14; + sr = sr >> 6 | xmaxc[3] << 10; + *c++ = sr >> 3; + sr = sr >> 3 | xmc[39] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[40] << 13; + sr = sr >> 3 | xmc[41] << 13; + sr = sr >> 3 | xmc[42] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[43] << 13; + sr = sr >> 3 | xmc[44] << 13; + sr = sr >> 3 | xmc[45] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[46] << 13; + sr = sr >> 3 | xmc[47] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[48] << 13; + sr = sr >> 3 | xmc[49] << 13; + sr = sr >> 3 | xmc[50] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[51] << 13; + sr = sr >> 4; + *c = sr >> 8; + s->frame_chain = *c; + } + else { + uword sr; + + sr = 0; + sr = sr >> 4 | s->frame_chain << 12; + sr = sr >> 6 | LARc[0] << 10; + *c++ = sr >> 6; + sr = sr >> 6 | LARc[1] << 10; + *c++ = sr >> 8; + sr = sr >> 5 | LARc[2] << 11; + sr = sr >> 5 | LARc[3] << 11; + *c++ = sr >> 6; + sr = sr >> 4 | LARc[4] << 12; + sr = sr >> 4 | LARc[5] << 12; + *c++ = sr >> 6; + sr = sr >> 3 | LARc[6] << 13; + sr = sr >> 3 | LARc[7] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[0] << 9; + sr = sr >> 2 | bc[0] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[0] << 14; + sr = sr >> 6 | xmaxc[0] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[0] << 13; + sr = sr >> 3 | xmc[1] << 13; + sr = sr >> 3 | xmc[2] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[3] << 13; + sr = sr >> 3 | xmc[4] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[5] << 13; + sr = sr >> 3 | xmc[6] << 13; + sr = sr >> 3 | xmc[7] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[8] << 13; + sr = sr >> 3 | xmc[9] << 13; + sr = sr >> 3 | xmc[10] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[11] << 13; + sr = sr >> 3 | xmc[12] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[1] << 9; + sr = sr >> 2 | bc[1] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[1] << 14; + sr = sr >> 6 | xmaxc[1] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[13] << 13; + sr = sr >> 3 | xmc[14] << 13; + sr = sr >> 3 | xmc[15] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[16] << 13; + sr = sr >> 3 | xmc[17] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[18] << 13; + sr = sr >> 3 | xmc[19] << 13; + sr = sr >> 3 | xmc[20] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[21] << 13; + sr = sr >> 3 | xmc[22] << 13; + sr = sr >> 3 | xmc[23] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[24] << 13; + sr = sr >> 3 | xmc[25] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[2] << 9; + sr = sr >> 2 | bc[2] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[2] << 14; + sr = sr >> 6 | xmaxc[2] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[26] << 13; + sr = sr >> 3 | xmc[27] << 13; + sr = sr >> 3 | xmc[28] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[29] << 13; + sr = sr >> 3 | xmc[30] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[31] << 13; + sr = sr >> 3 | xmc[32] << 13; + sr = sr >> 3 | xmc[33] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[34] << 13; + sr = sr >> 3 | xmc[35] << 13; + sr = sr >> 3 | xmc[36] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[37] << 13; + sr = sr >> 3 | xmc[38] << 13; + *c++ = sr >> 8; + sr = sr >> 7 | Nc[3] << 9; + sr = sr >> 2 | bc[3] << 14; + *c++ = sr >> 7; + sr = sr >> 2 | Mc[3] << 14; + sr = sr >> 6 | xmaxc[3] << 10; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[39] << 13; + sr = sr >> 3 | xmc[40] << 13; + sr = sr >> 3 | xmc[41] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[42] << 13; + sr = sr >> 3 | xmc[43] << 13; + *c++ = sr >> 8; + sr = sr >> 3 | xmc[44] << 13; + sr = sr >> 3 | xmc[45] << 13; + sr = sr >> 3 | xmc[46] << 13; + *c++ = sr >> 7; + sr = sr >> 3 | xmc[47] << 13; + sr = sr >> 3 | xmc[48] << 13; + sr = sr >> 3 | xmc[49] << 13; + *c++ = sr >> 6; + sr = sr >> 3 | xmc[50] << 13; + sr = sr >> 3 | xmc[51] << 13; + *c++ = sr >> 8; + } + } + + else + +#endif /* WAV49 */ + { + + *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF); + *c++ = ((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F); + *c++ = ((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7); + *c++ = ((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3); + *c++ = ((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7); + *c++ = ((Nc[0] & 0x7F) << 1) + | ((bc[0] >> 1) & 0x1); + *c++ = ((bc[0] & 0x1) << 7) + | ((Mc[0] & 0x3) << 5) + | ((xmaxc[0] >> 1) & 0x1F); + *c++ = ((xmaxc[0] & 0x1) << 7) + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1); + *c++ = ((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7); + *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3); + *c++ = ((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1); + *c++ = ((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7); + *c++ = ((Nc[1] & 0x7F) << 1) + | ((bc[1] >> 1) & 0x1); + *c++ = ((bc[1] & 0x1) << 7) + | ((Mc[1] & 0x3) << 5) + | ((xmaxc[1] >> 1) & 0x1F); + *c++ = ((xmaxc[1] & 0x1) << 7) + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1); + *c++ = ((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7); + *c++ = ((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3); + *c++ = ((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1); + *c++ = ((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7); + *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ + | ((bc[2] >> 1) & 0x1); + *c++ = ((bc[2] & 0x1) << 7) + | ((Mc[2] & 0x3) << 5) + | ((xmaxc[2] >> 1) & 0x1F); + *c++ = ((xmaxc[2] & 0x1) << 7) + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1); + *c++ = ((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7); + *c++ = ((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3); + *c++ = ((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1); + *c++ = ((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7); + *c++ = ((Nc[3] & 0x7F) << 1) + | ((bc[3] >> 1) & 0x1); + *c++ = ((bc[3] & 0x1) << 7) + | ((Mc[3] & 0x3) << 5) + | ((xmaxc[3] >> 1) & 0x1F); + *c++ = ((xmaxc[3] & 0x1) << 7) + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1); + *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7); + *c++ = ((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3); + *c++ = ((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1); + *c++ = ((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7); + + } +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_explode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_explode.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,419 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_explode.c,v 1.2 1996/07/02 14:32:42 jutta Exp jutta $ */ + +#include "private.h" +#include "gsm.h" +#include "proto.h" + +int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) +{ +# define LARc target +# define Nc *((gsm_signal (*) [17])(target + 8)) +# define bc *((gsm_signal (*) [17])(target + 9)) +# define Mc *((gsm_signal (*) [17])(target + 10)) +# define xmaxc *((gsm_signal (*) [17])(target + 11)) + +// Wirlab + (void)s; + +#ifdef WAV49 + if (s->wav_fmt) { + + uword sr = 0; + + if (s->frame_index == 1) { + + sr = *c++; + LARc[0] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 2; + LARc[1] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 4; + LARc[2] = sr & 0x1f; sr >>= 5; + LARc[3] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 2; + LARc[4] = sr & 0xf; sr >>= 4; + LARc[5] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; /* 5 */ + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[0] = sr & 0x7f; sr >>= 7; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 12) + xmc[0] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[1] = sr & 0x7; sr >>= 3; + xmc[2] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + xmc[5] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 10 */ + xmc[6] = sr & 0x7; sr >>= 3; + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[9] = sr & 0x7; sr >>= 3; + xmc[10] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[1] = sr & 0x7f; sr >>= 7; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 29 - 13) + + xmc[13] = sr & 0x7; sr >>= 3; + sr = *c++; /* 15 */ + xmc[14] = sr & 0x7; sr >>= 3; + xmc[15] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + xmc[18] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[19] = sr & 0x7; sr >>= 3; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[22] = sr & 0x7; sr >>= 3; + xmc[23] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; /* 20 */ + Nc[2] = sr & 0x7f; sr >>= 7; + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[2] = sr & 0x3f; sr >>= 6; + +#undef xmc +#define xmc (target + 46 - 26) + + xmc[26] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[27] = sr & 0x7; sr >>= 3; + xmc[28] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + xmc[31] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[32] = sr & 0x7; sr >>= 3; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + sr = *c++; /* 25 */ + xmc[35] = sr & 0x7; sr >>= 3; + xmc[36] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[3] = sr & 0x7f; sr >>= 7; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[3] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[40] = sr & 0x7; sr >>= 3; + xmc[41] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 30 */ + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + xmc[44] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[45] = sr & 0x7; sr >>= 3; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[48] = sr & 0x7; sr >>= 3; + xmc[49] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + + s->frame_chain = sr & 0xf; + } + else { + sr = s->frame_chain; + sr |= (uword)*c++ << 4; /* 1 */ + LARc[0] = sr & 0x3f; sr >>= 6; + LARc[1] = sr & 0x3f; sr >>= 6; + sr = *c++; + LARc[2] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 3; + LARc[3] = sr & 0x1f; sr >>= 5; + LARc[4] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; + LARc[5] = sr & 0xf; sr >>= 4; + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr = *c++; /* 5 */ + Nc[0] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 12) + xmc[0] = sr & 0x7; sr >>= 3; + xmc[1] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[2] = sr & 0x7; sr >>= 3; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[5] = sr & 0x7; sr >>= 3; + xmc[6] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 10 */ + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + xmc[9] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[10] = sr & 0x7; sr >>= 3; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[1] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 29 - 13) + + xmc[13] = sr & 0x7; sr >>= 3; + xmc[14] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 15 */ + xmc[15] = sr & 0x7; sr >>= 3; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[18] = sr & 0x7; sr >>= 3; + xmc[19] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + xmc[22] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[23] = sr & 0x7; sr >>= 3; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[2] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; /* 20 */ + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[2] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (target + 46 - 26) + xmc[26] = sr & 0x7; sr >>= 3; + xmc[27] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[28] = sr & 0x7; sr >>= 3; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[31] = sr & 0x7; sr >>= 3; + xmc[32] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + xmc[35] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 25 */ + xmc[36] = sr & 0x7; sr >>= 3; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[3] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[3] = sr & 0x3f; sr >>= 6; + +#undef xmc +#define xmc (target + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + xmc[40] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[41] = sr & 0x7; sr >>= 3; + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + sr = *c++; /* 30 */ + xmc[44] = sr & 0x7; sr >>= 3; + xmc[45] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + xmc[48] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[49] = sr & 0x7; sr >>= 3; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + } + } + else +#endif + { + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; + + LARc[0] = (*c++ & 0xF) << 2; /* 1 */ + LARc[0] |= (*c >> 6) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = (*c >> 3) & 0x1F; + LARc[3] = (*c++ & 0x7) << 2; + LARc[3] |= (*c >> 6) & 0x3; + LARc[4] = (*c >> 2) & 0xF; + LARc[5] = (*c++ & 0x3) << 2; + LARc[5] |= (*c >> 6) & 0x3; + LARc[6] = (*c >> 3) & 0x7; + LARc[7] = *c++ & 0x7; + + Nc[0] = (*c >> 1) & 0x7F; + + bc[0] = (*c++ & 0x1) << 1; + bc[0] |= (*c >> 7) & 0x1; + + Mc[0] = (*c >> 5) & 0x3; + + xmaxc[0] = (*c++ & 0x1F) << 1; + xmaxc[0] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 12) + + xmc[0] = (*c >> 4) & 0x7; + xmc[1] = (*c >> 1) & 0x7; + xmc[2] = (*c++ & 0x1) << 2; + xmc[2] |= (*c >> 6) & 0x3; + xmc[3] = (*c >> 3) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = (*c >> 5) & 0x7; + xmc[6] = (*c >> 2) & 0x7; + xmc[7] = (*c++ & 0x3) << 1; /* 10 */ + xmc[7] |= (*c >> 7) & 0x1; + xmc[8] = (*c >> 4) & 0x7; + xmc[9] = (*c >> 1) & 0x7; + xmc[10] = (*c++ & 0x1) << 2; + xmc[10] |= (*c >> 6) & 0x3; + xmc[11] = (*c >> 3) & 0x7; + xmc[12] = *c++ & 0x7; + + Nc[1] = (*c >> 1) & 0x7F; + + bc[1] = (*c++ & 0x1) << 1; + bc[1] |= (*c >> 7) & 0x1; + + Mc[1] = (*c >> 5) & 0x3; + + xmaxc[1] = (*c++ & 0x1F) << 1; + xmaxc[1] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 29 - 13) + + xmc[13] = (*c >> 4) & 0x7; + xmc[14] = (*c >> 1) & 0x7; + xmc[15] = (*c++ & 0x1) << 2; + xmc[15] |= (*c >> 6) & 0x3; + xmc[16] = (*c >> 3) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = (*c >> 5) & 0x7; + xmc[19] = (*c >> 2) & 0x7; + xmc[20] = (*c++ & 0x3) << 1; + xmc[20] |= (*c >> 7) & 0x1; + xmc[21] = (*c >> 4) & 0x7; + xmc[22] = (*c >> 1) & 0x7; + xmc[23] = (*c++ & 0x1) << 2; + xmc[23] |= (*c >> 6) & 0x3; + xmc[24] = (*c >> 3) & 0x7; + xmc[25] = *c++ & 0x7; + + Nc[2] = (*c >> 1) & 0x7F; + + bc[2] = (*c++ & 0x1) << 1; /* 20 */ + bc[2] |= (*c >> 7) & 0x1; + + Mc[2] = (*c >> 5) & 0x3; + + xmaxc[2] = (*c++ & 0x1F) << 1; + xmaxc[2] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 46 - 26) + + xmc[26] = (*c >> 4) & 0x7; + xmc[27] = (*c >> 1) & 0x7; + xmc[28] = (*c++ & 0x1) << 2; + xmc[28] |= (*c >> 6) & 0x3; + xmc[29] = (*c >> 3) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = (*c >> 5) & 0x7; + xmc[32] = (*c >> 2) & 0x7; + xmc[33] = (*c++ & 0x3) << 1; + xmc[33] |= (*c >> 7) & 0x1; + xmc[34] = (*c >> 4) & 0x7; + xmc[35] = (*c >> 1) & 0x7; + xmc[36] = (*c++ & 0x1) << 2; + xmc[36] |= (*c >> 6) & 0x3; + xmc[37] = (*c >> 3) & 0x7; + xmc[38] = *c++ & 0x7; + + Nc[3] = (*c >> 1) & 0x7F; + + bc[3] = (*c++ & 0x1) << 1; + bc[3] |= (*c >> 7) & 0x1; + + Mc[3] = (*c >> 5) & 0x3; + + xmaxc[3] = (*c++ & 0x1F) << 1; + xmaxc[3] |= (*c >> 7) & 0x1; + +#undef xmc +#define xmc (target + 63 - 39) + + xmc[39] = (*c >> 4) & 0x7; + xmc[40] = (*c >> 1) & 0x7; + xmc[41] = (*c++ & 0x1) << 2; + xmc[41] |= (*c >> 6) & 0x3; + xmc[42] = (*c >> 3) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = (*c >> 5) & 0x7; + xmc[45] = (*c >> 2) & 0x7; + xmc[46] = (*c++ & 0x3) << 1; + xmc[46] |= (*c >> 7) & 0x1; + xmc[47] = (*c >> 4) & 0x7; + xmc[48] = (*c >> 1) & 0x7; + xmc[49] = (*c++ & 0x1) << 2; + xmc[49] |= (*c >> 6) & 0x3; + xmc[50] = (*c >> 3) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + } + + return 0; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_implode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_implode.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,518 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_implode.c,v 1.2 1996/07/02 14:32:43 jutta Exp jutta $ */ + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) +{ + /* variable size index + + GSM_MAGIC 4 - + + LARc[0] 6 0 + LARc[1] 6 1 + LARc[2] 5 2 + LARc[3] 5 3 + LARc[4] 4 4 + LARc[5] 4 5 + LARc[6] 3 6 + LARc[7] 3 7 + + Nc[0] 7 8 + bc[0] 2 9 + Mc[0] 2 10 + xmaxc[0] 6 11 + xmc[0] 3 12 + xmc[1] 3 13 + xmc[2] 3 14 + xmc[3] 3 15 + xmc[4] 3 16 + xmc[5] 3 17 + xmc[6] 3 18 + xmc[7] 3 19 + xmc[8] 3 20 + xmc[9] 3 21 + xmc[10] 3 22 + xmc[11] 3 23 + xmc[12] 3 24 + + Nc[1] 7 25 + bc[1] 2 26 + Mc[1] 2 27 + xmaxc[1] 6 28 + xmc[13] 3 29 + xmc[14] 3 30 + xmc[15] 3 31 + xmc[16] 3 32 + xmc[17] 3 33 + xmc[18] 3 34 + xmc[19] 3 35 + xmc[20] 3 36 + xmc[21] 3 37 + xmc[22] 3 38 + xmc[23] 3 39 + xmc[24] 3 40 + xmc[25] 3 41 + + Nc[2] 7 42 + bc[2] 2 43 + Mc[2] 2 44 + xmaxc[2] 6 45 + xmc[26] 3 46 + xmc[27] 3 47 + xmc[28] 3 48 + xmc[29] 3 49 + xmc[30] 3 50 + xmc[31] 3 51 + xmc[32] 3 52 + xmc[33] 3 53 + xmc[34] 3 54 + xmc[35] 3 55 + xmc[36] 3 56 + xmc[37] 3 57 + xmc[38] 3 58 + + Nc[3] 7 59 + bc[3] 2 60 + Mc[3] 2 61 + xmaxc[3] 6 62 + xmc[39] 3 63 + xmc[40] 3 64 + xmc[41] 3 65 + xmc[42] 3 66 + xmc[43] 3 67 + xmc[44] 3 68 + xmc[45] 3 69 + xmc[46] 3 70 + xmc[47] 3 71 + xmc[48] 3 72 + xmc[49] 3 73 + xmc[50] 3 74 + xmc[51] 3 75 + */ + + /* There are 76 parameters per frame. The first eight are + * unique. The remaining 68 are four identical subframes of + * 17 parameters each. gsm_implode converts from a representation + * of these parameters as values in one array of signed words + * to the "packed" version of a GSM frame. + */ + +# define LARc source +# define Nc *((gsm_signal (*) [17])(source + 8)) +# define bc *((gsm_signal (*) [17])(source + 9)) +# define Mc *((gsm_signal (*) [17])(source + 10)) +# define xmaxc *((gsm_signal (*) [17])(source + 11)) + +// Wirlab + (void)s; + +#ifdef WAV49 + if (s->wav_fmt) { + + uword sr = 0; + if (s->frame_index == 0) { + + sr = *c++; + LARc[0] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 2; + LARc[1] = sr & 0x3f; sr >>= 6; + sr |= (uword)*c++ << 4; + LARc[2] = sr & 0x1f; sr >>= 5; + LARc[3] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 2; + LARc[4] = sr & 0xf; sr >>= 4; + LARc[5] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; /* 5 */ + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[0] = sr & 0x7f; sr >>= 7; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 12) + xmc[0] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[1] = sr & 0x7; sr >>= 3; + xmc[2] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + xmc[5] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 10 */ + xmc[6] = sr & 0x7; sr >>= 3; + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[9] = sr & 0x7; sr >>= 3; + xmc[10] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[1] = sr & 0x7f; sr >>= 7; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 29 - 13) + xmc[13] = sr & 0x7; sr >>= 3; + sr = *c++; /* 15 */ + xmc[14] = sr & 0x7; sr >>= 3; + xmc[15] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + xmc[18] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[19] = sr & 0x7; sr >>= 3; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[22] = sr & 0x7; sr >>= 3; + xmc[23] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; /* 20 */ + Nc[2] = sr & 0x7f; sr >>= 7; + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[2] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 46 - 26) + xmc[26] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[27] = sr & 0x7; sr >>= 3; + xmc[28] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + xmc[31] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[32] = sr & 0x7; sr >>= 3; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + sr = *c++; /* 25 */ + xmc[35] = sr & 0x7; sr >>= 3; + xmc[36] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 4; + Nc[3] = sr & 0x7f; sr >>= 7; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 1; + xmaxc[3] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[40] = sr & 0x7; sr >>= 3; + xmc[41] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 30 */ + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + xmc[44] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[45] = sr & 0x7; sr >>= 3; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[48] = sr & 0x7; sr >>= 3; + xmc[49] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + + s->frame_chain = sr & 0xf; + } + else { + sr = s->frame_chain; + sr |= (uword)*c++ << 4; /* 1 */ + LARc[0] = sr & 0x3f; sr >>= 6; + LARc[1] = sr & 0x3f; sr >>= 6; + sr = *c++; + LARc[2] = sr & 0x1f; sr >>= 5; + sr |= (uword)*c++ << 3; + LARc[3] = sr & 0x1f; sr >>= 5; + LARc[4] = sr & 0xf; sr >>= 4; + sr |= (uword)*c++ << 2; + LARc[5] = sr & 0xf; sr >>= 4; + LARc[6] = sr & 0x7; sr >>= 3; + LARc[7] = sr & 0x7; sr >>= 3; + sr = *c++; /* 5 */ + Nc[0] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[0] = sr & 0x3; sr >>= 2; + Mc[0] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[0] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 12) + xmc[0] = sr & 0x7; sr >>= 3; + xmc[1] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[2] = sr & 0x7; sr >>= 3; + xmc[3] = sr & 0x7; sr >>= 3; + xmc[4] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[5] = sr & 0x7; sr >>= 3; + xmc[6] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; /* 10 */ + xmc[7] = sr & 0x7; sr >>= 3; + xmc[8] = sr & 0x7; sr >>= 3; + xmc[9] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[10] = sr & 0x7; sr >>= 3; + xmc[11] = sr & 0x7; sr >>= 3; + xmc[12] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[1] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[1] = sr & 0x3; sr >>= 2; + Mc[1] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[1] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 29 - 13) + xmc[13] = sr & 0x7; sr >>= 3; + xmc[14] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 15 */ + xmc[15] = sr & 0x7; sr >>= 3; + xmc[16] = sr & 0x7; sr >>= 3; + xmc[17] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[18] = sr & 0x7; sr >>= 3; + xmc[19] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[20] = sr & 0x7; sr >>= 3; + xmc[21] = sr & 0x7; sr >>= 3; + xmc[22] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[23] = sr & 0x7; sr >>= 3; + xmc[24] = sr & 0x7; sr >>= 3; + xmc[25] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[2] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; /* 20 */ + bc[2] = sr & 0x3; sr >>= 2; + Mc[2] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[2] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 46 - 26) + xmc[26] = sr & 0x7; sr >>= 3; + xmc[27] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[28] = sr & 0x7; sr >>= 3; + xmc[29] = sr & 0x7; sr >>= 3; + xmc[30] = sr & 0x7; sr >>= 3; + sr = *c++; + xmc[31] = sr & 0x7; sr >>= 3; + xmc[32] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[33] = sr & 0x7; sr >>= 3; + xmc[34] = sr & 0x7; sr >>= 3; + xmc[35] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; /* 25 */ + xmc[36] = sr & 0x7; sr >>= 3; + xmc[37] = sr & 0x7; sr >>= 3; + xmc[38] = sr & 0x7; sr >>= 3; + sr = *c++; + Nc[3] = sr & 0x7f; sr >>= 7; + sr |= (uword)*c++ << 1; + bc[3] = sr & 0x3; sr >>= 2; + Mc[3] = sr & 0x3; sr >>= 2; + sr |= (uword)*c++ << 5; + xmaxc[3] = sr & 0x3f; sr >>= 6; +#undef xmc +#define xmc (source + 63 - 39) + + xmc[39] = sr & 0x7; sr >>= 3; + xmc[40] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[41] = sr & 0x7; sr >>= 3; + xmc[42] = sr & 0x7; sr >>= 3; + xmc[43] = sr & 0x7; sr >>= 3; + sr = *c++; /* 30 */ + xmc[44] = sr & 0x7; sr >>= 3; + xmc[45] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 2; + xmc[46] = sr & 0x7; sr >>= 3; + xmc[47] = sr & 0x7; sr >>= 3; + xmc[48] = sr & 0x7; sr >>= 3; + sr |= (uword)*c++ << 1; + xmc[49] = sr & 0x7; sr >>= 3; + xmc[50] = sr & 0x7; sr >>= 3; + xmc[51] = sr & 0x7; sr >>= 3; + } + } + else +#endif + { + + *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF); + *c++ = ((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F); + *c++ = ((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7); + *c++ = ((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3); + *c++ = ((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7); + + + *c++ = ((Nc[0] & 0x7F) << 1) + + + | ((bc[0] >> 1) & 0x1); + *c++ = ((bc[0] & 0x1) << 7) + + + | ((Mc[0] & 0x3) << 5) + + | ((xmaxc[0] >> 1) & 0x1F); + *c++ = ((xmaxc[0] & 0x1) << 7) + +#undef xmc +#define xmc (source + 12) + + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1); + *c++ = ((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7); + *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3); + *c++ = ((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1); + *c++ = ((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7); + + + *c++ = ((Nc[1] & 0x7F) << 1) + + + | ((bc[1] >> 1) & 0x1); + *c++ = ((bc[1] & 0x1) << 7) + + + | ((Mc[1] & 0x3) << 5) + + + | ((xmaxc[1] >> 1) & 0x1F); + *c++ = ((xmaxc[1] & 0x1) << 7) + +#undef xmc +#define xmc (source + 29 - 13) + + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1); + *c++ = ((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7); + *c++ = ((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3); + *c++ = ((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1); + *c++ = ((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7); + + + *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ + + + | ((bc[2] >> 1) & 0x1); + *c++ = ((bc[2] & 0x1) << 7) + + + | ((Mc[2] & 0x3) << 5) + + + | ((xmaxc[2] >> 1) & 0x1F); + *c++ = ((xmaxc[2] & 0x1) << 7) + +#undef xmc +#define xmc (source + 46 - 26) + + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1); + *c++ = ((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7); + *c++ = ((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3); + *c++ = ((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1); + *c++ = ((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7); + + + *c++ = ((Nc[3] & 0x7F) << 1) + + + | ((bc[3] >> 1) & 0x1); + *c++ = ((bc[3] & 0x1) << 7) + + + | ((Mc[3] & 0x3) << 5) + + + | ((xmaxc[3] >> 1) & 0x1F); + *c++ = ((xmaxc[3] & 0x1) << 7) + +#undef xmc +#define xmc (source + 63 - 39) + + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1); + *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7); + *c++ = ((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3); + *c++ = ((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1); + *c++ = ((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7); + } +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_jni.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_jni.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,87 @@ + + +/** +extern gsm gsm_create GSMJNI_P((void)); +extern void gsm_destroy GSMJNI_P((gsm)); + +extern int gsm_print GSMJNI_P((FILE *, gsm, gsm_byte *)); +extern int gsm_option GSMJNI_P((gsm, int, int *)); + +extern void gsm_encode GSMJNI_P((gsm, gsm_signal *, gsm_byte *)); +extern int gsm_decode GSMJNI_P((gsm, gsm_byte *, gsm_signal *)); + +extern int gsm_explode GSMJNI_P((gsm, gsm_byte *, gsm_signal *)); +extern void gsm_implode GSMJNI_P((gsm, gsm_signal *, gsm_byte *)); +*/ + + +#include + + +#include "gsm.h" +#include "private.h" +#include "proto.h" + +jlong +Java_org_sipdroid_media_codecs_GSMJNI_create(JNIEnv *env) +{ + return gsm_create(); +} + +void +Java_org_sipdroid_media_codecs_GSMJNI_destroy(JNIEnv *env, jlong jgsm) +{ + gsm_destroy((void *)jgsm); +} + +void +Java_org_sipdroid_media_codecs_GSMJNI_encode(JNIEnv *env, jlong jgsm, jshortArray jgsmSignal, jlong jsrcPos, jbyteArray jgsmByte, jlong jdestPos) +{ + jshort *gsmSignal; + jbyte *gsmByte; + jboolean isCopyByte; + jboolean isCopySignal; + void *ctx = (void *) jgsm; + + gsmByte = (*env)->GetByteArrayElements( env, jgsmByte, &isCopyByte); + gsmSignal = (*env)->GetShortArrayElements( env, jgsmSignal, &isCopySignal); + + gsm_encode(ctx, gsmSignal + jsrcPos, gsmByte + jdestPos); + if (isCopyByte == JNI_TRUE) + (*env)->ReleaseByteArrayElements(env, jgsmByte, gsmByte,0); + if (isCopySignal == JNI_TRUE) + (*env)->ReleaseShortArrayElements(env, jgsmSignal, gsmSignal,0); +} + +jint +Java_org_sipdroid_media_codecs_GSMJNI_decode(JNIEnv *env, jlong jgsm, jbyteArray jgsmByte, jlong jdestPos, jshortArray jgsmSignal, jlong jsrcPos) +{ + jshort *gsmSignal; + jbyte *gsmByte; + jboolean isCopyByte; + jboolean isCopySignal; + jint res; + + gsmSignal = (*env)->GetShortArrayElements( env, jgsmSignal, &isCopySignal); + gsmByte = (*env)->GetByteArrayElements( env, jgsmByte, &isCopyByte); + res = gsm_decode((void *)jgsm, gsmByte + jdestPos, gsmSignal + jsrcPos); + if (isCopyByte == JNI_TRUE) + (*env)->ReleaseByteArrayElements(env, jgsmByte, gsmByte,0); + if (isCopySignal == JNI_TRUE) + (*env)->ReleaseShortArrayElements(env, jgsmSignal, gsmSignal,0); + return res; +} + +jint +Java_org_sipdroid_media_codecs_GSMJNI_option(JNIEnv *env, jlong jgsm, jint jopt, jintArray jval) +{ + jint *val; + jboolean isCopyVal; + jint res; + + val = (*env)->GetIntArrayElements( env, jval, &isCopyVal); + res = gsm_option((void *)jgsm, jopt, val); + if (isCopyVal == JNI_TRUE) + (*env)->ReleaseIntArrayElements(env, jval, val,0); + return res; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_option.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_option.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,69 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_option.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */ + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +int gsm_option P3((r, opt, val), gsm r, int opt, int * val) +{ + int result = -1; + + switch (opt) { + case GSM_OPT_LTP_CUT: +#ifdef LTP_CUT + result = r->ltp_cut; + if (val) r->ltp_cut = *val; +#endif + break; + + case GSM_OPT_VERBOSE: +#ifndef NDEBUG + result = r->verbose; + if (val) r->verbose = *val; +#endif + break; + + case GSM_OPT_FAST: + +#if defined(FAST) && defined(USE_FLOAT_MUL) + result = r->fast; + if (val) r->fast = !!*val; +#endif + break; + + case GSM_OPT_FRAME_CHAIN: + +#ifdef WAV49 + result = r->frame_chain; + if (val) r->frame_chain = *val; +#endif + break; + + case GSM_OPT_FRAME_INDEX: + +#ifdef WAV49 + result = r->frame_index; + if (val) r->frame_index = *val; +#endif + break; + + case GSM_OPT_WAV49: + +#ifdef WAV49 + result = r->wav_fmt; + if (val) r->wav_fmt = !!*val; +#endif + break; + + default: + break; + } + return result; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/gsm_print.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/gsm_print.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,170 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_print.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */ + +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c) +{ + word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; +// Wirlab + (void)s; + + + /* GSM_MAGIC = (*c >> 4) & 0xF; */ + + if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; + + LARc[0] = (*c++ & 0xF) << 2; /* 1 */ + LARc[0] |= (*c >> 6) & 0x3; + LARc[1] = *c++ & 0x3F; + LARc[2] = (*c >> 3) & 0x1F; + LARc[3] = (*c++ & 0x7) << 2; + LARc[3] |= (*c >> 6) & 0x3; + LARc[4] = (*c >> 2) & 0xF; + LARc[5] = (*c++ & 0x3) << 2; + LARc[5] |= (*c >> 6) & 0x3; + LARc[6] = (*c >> 3) & 0x7; + LARc[7] = *c++ & 0x7; + + + Nc[0] = (*c >> 1) & 0x7F; + bc[0] = (*c++ & 0x1) << 1; + bc[0] |= (*c >> 7) & 0x1; + Mc[0] = (*c >> 5) & 0x3; + xmaxc[0] = (*c++ & 0x1F) << 1; + xmaxc[0] |= (*c >> 7) & 0x1; + xmc[0] = (*c >> 4) & 0x7; + xmc[1] = (*c >> 1) & 0x7; + xmc[2] = (*c++ & 0x1) << 2; + xmc[2] |= (*c >> 6) & 0x3; + xmc[3] = (*c >> 3) & 0x7; + xmc[4] = *c++ & 0x7; + xmc[5] = (*c >> 5) & 0x7; + xmc[6] = (*c >> 2) & 0x7; + xmc[7] = (*c++ & 0x3) << 1; /* 10 */ + xmc[7] |= (*c >> 7) & 0x1; + xmc[8] = (*c >> 4) & 0x7; + xmc[9] = (*c >> 1) & 0x7; + xmc[10] = (*c++ & 0x1) << 2; + xmc[10] |= (*c >> 6) & 0x3; + xmc[11] = (*c >> 3) & 0x7; + xmc[12] = *c++ & 0x7; + + Nc[1] = (*c >> 1) & 0x7F; + bc[1] = (*c++ & 0x1) << 1; + bc[1] |= (*c >> 7) & 0x1; + Mc[1] = (*c >> 5) & 0x3; + xmaxc[1] = (*c++ & 0x1F) << 1; + xmaxc[1] |= (*c >> 7) & 0x1; + xmc[13] = (*c >> 4) & 0x7; + xmc[14] = (*c >> 1) & 0x7; + xmc[15] = (*c++ & 0x1) << 2; + xmc[15] |= (*c >> 6) & 0x3; + xmc[16] = (*c >> 3) & 0x7; + xmc[17] = *c++ & 0x7; + xmc[18] = (*c >> 5) & 0x7; + xmc[19] = (*c >> 2) & 0x7; + xmc[20] = (*c++ & 0x3) << 1; + xmc[20] |= (*c >> 7) & 0x1; + xmc[21] = (*c >> 4) & 0x7; + xmc[22] = (*c >> 1) & 0x7; + xmc[23] = (*c++ & 0x1) << 2; + xmc[23] |= (*c >> 6) & 0x3; + xmc[24] = (*c >> 3) & 0x7; + xmc[25] = *c++ & 0x7; + + + Nc[2] = (*c >> 1) & 0x7F; + bc[2] = (*c++ & 0x1) << 1; /* 20 */ + bc[2] |= (*c >> 7) & 0x1; + Mc[2] = (*c >> 5) & 0x3; + xmaxc[2] = (*c++ & 0x1F) << 1; + xmaxc[2] |= (*c >> 7) & 0x1; + xmc[26] = (*c >> 4) & 0x7; + xmc[27] = (*c >> 1) & 0x7; + xmc[28] = (*c++ & 0x1) << 2; + xmc[28] |= (*c >> 6) & 0x3; + xmc[29] = (*c >> 3) & 0x7; + xmc[30] = *c++ & 0x7; + xmc[31] = (*c >> 5) & 0x7; + xmc[32] = (*c >> 2) & 0x7; + xmc[33] = (*c++ & 0x3) << 1; + xmc[33] |= (*c >> 7) & 0x1; + xmc[34] = (*c >> 4) & 0x7; + xmc[35] = (*c >> 1) & 0x7; + xmc[36] = (*c++ & 0x1) << 2; + xmc[36] |= (*c >> 6) & 0x3; + xmc[37] = (*c >> 3) & 0x7; + xmc[38] = *c++ & 0x7; + + Nc[3] = (*c >> 1) & 0x7F; + bc[3] = (*c++ & 0x1) << 1; + bc[3] |= (*c >> 7) & 0x1; + Mc[3] = (*c >> 5) & 0x3; + xmaxc[3] = (*c++ & 0x1F) << 1; + xmaxc[3] |= (*c >> 7) & 0x1; + + xmc[39] = (*c >> 4) & 0x7; + xmc[40] = (*c >> 1) & 0x7; + xmc[41] = (*c++ & 0x1) << 2; + xmc[41] |= (*c >> 6) & 0x3; + xmc[42] = (*c >> 3) & 0x7; + xmc[43] = *c++ & 0x7; /* 30 */ + xmc[44] = (*c >> 5) & 0x7; + xmc[45] = (*c >> 2) & 0x7; + xmc[46] = (*c++ & 0x3) << 1; + xmc[46] |= (*c >> 7) & 0x1; + xmc[47] = (*c >> 4) & 0x7; + xmc[48] = (*c >> 1) & 0x7; + xmc[49] = (*c++ & 0x1) << 2; + xmc[49] |= (*c >> 6) & 0x3; + xmc[50] = (*c >> 3) & 0x7; + xmc[51] = *c & 0x7; /* 33 */ + + fprintf(f, + "LARc:\t%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d\n", + LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]); + + fprintf(f, "#1: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[0], bc[0], Mc[0], xmaxc[0]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6], + xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] ); + + fprintf(f, "#2: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[1], bc[1], Mc[1], xmaxc[1]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5], + xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11], + xmc[13+12] ); + + fprintf(f, "#3: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[2], bc[2], Mc[2], xmaxc[2]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5], + xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11], + xmc[26+12] ); + + fprintf(f, "#4: Nc %4.4d bc %d Mc %d xmaxc %d\n", + Nc[3], bc[3], Mc[3], xmaxc[3]); + fprintf(f, +"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", + xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5], + xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11], + xmc[39+12] ); + + return 0; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/long_term.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/long_term.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,954 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/long_term.c,v 1.6 1996/07/02 12:33:19 jutta Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* + * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION + */ + + +/* + * This module computes the LTP gain (bc) and the LTP lag (Nc) + * for the long term analysis filter. This is done by calculating a + * maximum of the cross-correlation function between the current + * sub-segment short term residual signal d[0..39] (output of + * the short term analysis filter; for simplification the index + * of this array begins at 0 and ends at 39 for each sub-segment of the + * RPE-LTP analysis) and the previous reconstructed short term + * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be + * performed to avoid overflow. + */ + + /* The next procedure exists in six versions. First two integer + * version (if USE_FLOAT_MUL is not defined); then four floating + * point versions, twice with proper scaling (USE_FLOAT_MUL defined), + * once without (USE_FLOAT_MUL and FAST defined, and fast run-time + * option used). Every pair has first a Cut version (see the -C + * option to toast or the LTP_CUT option to gsm_option()), then the + * uncut one. (For a detailed explanation of why this is altogether + * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered + * Harmful''.) + */ + +#ifndef USE_FLOAT_MUL + +#ifdef LTP_CUT + +static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), + + struct gsm_state * st, + + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_result; + longword L_max, L_power; + word R, S, dmax, scal, best_k; + word ltp_cut; + + register word temp, wt_k; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) { + dmax = temp; + best_k = k; + } + } + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + if (temp > 6) scal = 0; + else scal = 6 - temp; + assert(scal >= 0); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + wt_k = SASR(d[best_k], scal); + + for (lambda = 40; lambda <= 120; lambda++) { + L_result = (longword)wt_k * dp[best_k - lambda]; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + *Nc_out = Nc; + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word wt[40]; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + + /* Initialization of a working array wt + */ + + for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) { + +# undef STEP +# define STEP(k) (longword)wt[k] * dp[k - lambda] + + register longword L_result; + + L_result = STEP(0) ; L_result += STEP(1) ; + L_result += STEP(2) ; L_result += STEP(3) ; + L_result += STEP(4) ; L_result += STEP(5) ; + L_result += STEP(6) ; L_result += STEP(7) ; + L_result += STEP(8) ; L_result += STEP(9) ; + L_result += STEP(10) ; L_result += STEP(11) ; + L_result += STEP(12) ; L_result += STEP(13) ; + L_result += STEP(14) ; L_result += STEP(15) ; + L_result += STEP(16) ; L_result += STEP(17) ; + L_result += STEP(18) ; L_result += STEP(19) ; + L_result += STEP(20) ; L_result += STEP(21) ; + L_result += STEP(22) ; L_result += STEP(23) ; + L_result += STEP(24) ; L_result += STEP(25) ; + L_result += STEP(26) ; L_result += STEP(27) ; + L_result += STEP(28) ; L_result += STEP(29) ; + L_result += STEP(30) ; L_result += STEP(31) ; + L_result += STEP(32) ; L_result += STEP(33) ; + L_result += STEP(34) ; L_result += STEP(35) ; + L_result += STEP(36) ; L_result += STEP(37) ; + L_result += STEP(38) ; L_result += STEP(39) ; + + if (L_result > L_max) { + + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#else /* USE_FLOAT_MUL */ + +#ifdef LTP_CUT + +static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), + struct gsm_state * st, /* IN */ + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + word ltp_cut; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; + + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) { + register word w = SASR( d[k], scal ); + if (w < 0 ? w > -ltp_cut : w < ltp_cut) { + wt_float[k] = 0.0; + } + else { + wt_float[k] = w; + } + } + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + if ((W = wt_float[K]) != 0.0) { \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E; } else (a = lp[K]) + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + longword L_max, L_power; + word R, S, dmax, scal; + register word temp; + + /* Search of the optimum scaling of d[0..39]. + */ + dmax = 0; + + for (k = 0; k <= 39; k++) { + temp = d[k]; + temp = GSM_ABS( temp ); + if (temp > dmax) dmax = temp; + } + + temp = 0; + if (dmax == 0) scal = 0; + else { + assert(dmax > 0); + temp = gsm_norm( (longword)dmax << 16 ); + } + + if (temp > 6) scal = 0; + else scal = 6 - temp; + + assert(scal >= 0); + + /* Initialization of a working array wt + */ + + for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); + for (k = -120; k < 0; k++) dp_float[k] = dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + L_max <<= 1; + + /* Rescaling of L_max + */ + assert(scal <= 100 && scal >= -100); + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + assert( Nc <= 120 && Nc >= 40); + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + L_power = 0; + for (k = 0; k <= 39; k++) { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; /* from L_MULT */ + + /* Normalization of L_max and L_power + */ + + if (L_max <= 0) { + *bc_out = 0; + return; + } + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = SASR( L_max << temp, 16 ); + S = SASR( L_power << temp, 16 ); + + /* Coding of the LTP gain + */ + + /* Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; + *bc_out = bc; +} + +#ifdef FAST +#ifdef LTP_CUT + +static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st, + d,dp,bc_out,Nc_out), + struct gsm_state * st, /* IN */ + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + register float wt_float; + word Nc, bc; + word wt_max, best_k, ltp_cut; + + float dp_float_base[120], * dp_float = dp_float_base + 120; + + register float L_result, L_max, L_power; + + wt_max = 0; + + for (k = 0; k < 40; ++k) { + if ( d[k] > wt_max) wt_max = d[best_k = k]; + else if (-d[k] > wt_max) wt_max = -d[best_k = k]; + } + + assert(wt_max >= 0); + wt_float = (float)wt_max; + + for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) { + L_result = wt_float * dp_float[best_k - lambda]; + if (L_result > L_max) { + Nc = lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + if (L_max <= 0.) { + *bc_out = 0; + return; + } + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + dp_float -= Nc; + L_power = 0; + for (k = 0; k < 40; ++k) { + register float f = dp_float[k]; + L_power += f * f; + } + + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + /* Coding of the LTP gain + * Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + lambda = L_max / L_power * 32768.; + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + *bc_out = bc; +} + +#endif /* LTP_CUT */ + +static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), + register word * d, /* [0..39] IN */ + register word * dp, /* [-120..-1] IN */ + word * bc_out, /* OUT */ + word * Nc_out /* OUT */ +) +{ + register int k, lambda; + word Nc, bc; + + float wt_float[40]; + float dp_float_base[120], * dp_float = dp_float_base + 120; + + register float L_max, L_power; + + for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k]; + for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; + + /* Search for the maximum cross-correlation and coding of the LTP lag + */ + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda += 9) { + + /* Calculate L_result for l = lambda .. lambda + 9. + */ + register float *lp = dp_float - lambda; + + register float W; + register float a = lp[-8], b = lp[-7], c = lp[-6], + d = lp[-5], e = lp[-4], f = lp[-3], + g = lp[-2], h = lp[-1]; + register float E; + register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, + S5 = 0, S6 = 0, S7 = 0, S8 = 0; + +# undef STEP +# define STEP(K, a, b, c, d, e, f, g, h) \ + W = wt_float[K]; \ + E = W * a; S8 += E; \ + E = W * b; S7 += E; \ + E = W * c; S6 += E; \ + E = W * d; S5 += E; \ + E = W * e; S4 += E; \ + E = W * f; S3 += E; \ + E = W * g; S2 += E; \ + E = W * h; S1 += E; \ + a = lp[K]; \ + E = W * a; S0 += E + +# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) +# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) +# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) +# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) +# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) +# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) +# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) +# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) + + STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); + STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); + + STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); + STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); + + STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); + STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); + + STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); + STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); + + STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); + STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); + + if (S0 > L_max) { L_max = S0; Nc = lambda; } + if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } + if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } + if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } + if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } + if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } + if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } + if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } + if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } + } + *Nc_out = Nc; + + if (L_max <= 0.) { + *bc_out = 0; + return; + } + + /* Compute the power of the reconstructed short term residual + * signal dp[..] + */ + dp_float -= Nc; + L_power = 0; + for (k = 0; k < 40; ++k) { + register float f = dp_float[k]; + L_power += f * f; + } + + if (L_max >= L_power) { + *bc_out = 3; + return; + } + + /* Coding of the LTP gain + * Table 4.3a must be used to obtain the level DLB[i] for the + * quantization of the LTP gain b to get the coded version bc. + */ + lambda = L_max / L_power * 32768.; + for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; + *bc_out = bc; +} + +#endif /* FAST */ +#endif /* USE_FLOAT_MUL */ + + +/* 4.2.12 */ + +static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e), + word bc, /* IN */ + word Nc, /* IN */ + register word * dp, /* previous d [-120..-1] IN */ + register word * d, /* d [0..39] IN */ + register word * dpp, /* estimate [0..39] OUT */ + register word * e /* long term res. signal [0..39] OUT */ +) +/* + * In this part, we have to decode the bc parameter to compute + * the samples of the estimate dpp[0..39]. The decoding of bc needs the + * use of table 4.3b. The long term residual signal e[0..39] + * is then calculated to be fed to the RPE encoding section. + */ +{ + register int k; + register longword ltmp; + +# undef STEP +# define STEP(BP) \ + for (k = 0; k <= 39; k++) { \ + dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ + e[k] = GSM_SUB( d[k], dpp[k] ); \ + } + + switch (bc) { + case 0: STEP( 3277 ); break; + case 1: STEP( 11469 ); break; + case 2: STEP( 21299 ); break; + case 3: STEP( 32767 ); break; + } +} + +void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */ + + struct gsm_state * S, + + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + + word * e, /* [0..39] OUT */ + word * dpp, /* [0..39] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */ +) +{ + +// Wirlab + (void)S; + + assert( d ); assert( dp ); assert( e ); + assert( dpp); assert( Nc ); assert( bc ); + +#if defined(FAST) && defined(USE_FLOAT_MUL) + if (S->fast) +#if defined (LTP_CUT) + if (S->ltp_cut) + Cut_Fast_Calculation_of_the_LTP_parameters(S, + d, dp, bc, Nc); + else +#endif /* LTP_CUT */ + Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc ); + else +#endif /* FAST & USE_FLOAT_MUL */ +#ifdef LTP_CUT + if (S->ltp_cut) + Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); + else +#endif + Calculation_of_the_LTP_parameters(d, dp, bc, Nc); + + Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); +} + +/* 4.3.2 */ +void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp), + struct gsm_state * S, + + word Ncr, + word bcr, + register word * erp, /* [0..39] IN */ + register word * drp /* [-120..-1] IN, [-120..40] OUT */ +) +/* + * This procedure uses the bcr and Ncr parameter to realize the + * long term synthesis filtering. The decoding of bcr needs + * table 4.3b. + */ +{ + + register longword ltmp; /* for ADD */ + register int k; + word brp, drpp, Nr; + + /* Check the limits of Nr. + */ + Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; + S->nrp = Nr; + assert(Nr >= 40 && Nr <= 120); + + /* Decoding of the LTP gain bcr + */ + brp = gsm_QLB[ bcr ]; + + /* Computation of the reconstructed short term residual + * signal drp[0..39] + */ + assert(brp != MIN_WORD); + + for (k = 0; k <= 39; k++) { + drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); + drp[k] = GSM_ADD( erp[k], drpp ); + } + + /* + * Update of the reconstructed short term residual signal + * drp[ -1..-120 ] + */ + + for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/lpc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/lpc.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,345 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lpc.c,v 1.5 1994/12/30 23:14:54 jutta Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +#undef P + +/* + * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION + */ + +/* 4.2.4 */ + + +static void Autocorrelation P2((s, L_ACF), + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +/* + * The goal is to compute the array L_ACF[k]. The signal s[i] must + * be scaled in order to avoid an overflow situation. + */ +{ + register int k, i; + + word temp, smax, scalauto; + +#ifdef USE_FLOAT_MUL + float float_s[160]; +#endif + + /* Dynamic scaling of the array s[0..159] + */ + + /* Search for the maximum. + */ + smax = 0; + for (k = 0; k <= 159; k++) { + temp = GSM_ABS( s[k] ); + if (temp > smax) smax = temp; + } + + /* Computation of the scaling factor. + */ + if (smax == 0) scalauto = 0; + else { + assert(smax > 0); + scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ + } + + /* Scaling of the array s[0...159] + */ + + if (scalauto > 0) { + +# ifdef USE_FLOAT_MUL +# define SCALE(n) \ + case n: for (k = 0; k <= 159; k++) \ + float_s[k] = (float) \ + (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ + break; +# else +# define SCALE(n) \ + case n: for (k = 0; k <= 159; k++) \ + s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ + break; +# endif /* USE_FLOAT_MUL */ + + switch (scalauto) { + SCALE(1) + SCALE(2) + SCALE(3) + SCALE(4) + } +# undef SCALE + } +# ifdef USE_FLOAT_MUL + else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; +# endif + + /* Compute the L_ACF[..]. + */ + { +# ifdef USE_FLOAT_MUL + register float * sp = float_s; + register float sl = *sp; + +# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); +# else + word * sp = s; + word sl = *sp; + +# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); +# endif + +# define NEXTI sl = *++sp + + + for (k = 9; k--; L_ACF[k] = 0) ; + + STEP (0); + NEXTI; + STEP(0); STEP(1); + NEXTI; + STEP(0); STEP(1); STEP(2); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); + + for (i = 8; i <= 159; i++) { + + NEXTI; + + STEP(0); + STEP(1); STEP(2); STEP(3); STEP(4); + STEP(5); STEP(6); STEP(7); STEP(8); + } + + for (k = 9; k--; L_ACF[k] <<= 1) ; + + } + /* Rescaling of the array s[0..159] + */ + if (scalauto > 0) { + assert(scalauto <= 4); + for (k = 160; k--; *s++ <<= scalauto) ; + } +} + +#if defined(USE_FLOAT_MUL) && defined(FAST) + +static void Fast_Autocorrelation P2((s, L_ACF), + word * s, /* [0..159] IN/OUT */ + longword * L_ACF) /* [0..8] OUT */ +{ + register int k, i; + float f_L_ACF[9]; + float scale; + + float s_f[160]; + register float *sf = s_f; + + for (i = 0; i < 160; ++i) sf[i] = s[i]; + for (k = 0; k <= 8; k++) { + register float L_temp2 = 0; + register float *sfl = sf - k; + for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; + f_L_ACF[k] = L_temp2; + } + scale = MAX_LONGWORD / f_L_ACF[0]; + + for (k = 0; k <= 8; k++) { + L_ACF[k] = f_L_ACF[k] * scale; + } +} +#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ + +/* 4.2.5 */ + +static void Reflection_coefficients P2( (L_ACF, r), + longword * L_ACF, /* 0...8 IN */ + register word * r /* 0...7 OUT */ +) +{ + register int i, m, n; + register word temp; + register longword ltmp; + word ACF[9]; /* 0..8 */ + word P[ 9]; /* 0..8 */ + word K[ 9]; /* 2..8 */ + + /* Schur recursion with 16 bits arithmetic. + */ + + if (L_ACF[0] == 0) { + for (i = 8; i--; *r++ = 0) ; + return; + } + + assert( L_ACF[0] != 0 ); + temp = gsm_norm( L_ACF[0] ); + + assert(temp >= 0 && temp < 32); + + /* ? overflow ? */ + for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); + + /* Initialize array P[..] and K[..] for the recursion. + */ + + for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; + for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; + + /* Compute reflection coefficients + */ + for (n = 1; n <= 8; n++, r++) { + + temp = P[1]; + temp = GSM_ABS(temp); + if (P[0] < temp) { + for (i = n; i <= 8; i++) *r++ = 0; + return; + } + + *r = gsm_div( temp, P[0] ); + + assert(*r >= 0); + if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ + assert (*r != MIN_WORD); + if (n == 8) return; + + /* Schur recursion + */ + temp = GSM_MULT_R( P[1], *r ); + P[0] = GSM_ADD( P[0], temp ); + + for (m = 1; m <= 8 - n; m++) { + temp = GSM_MULT_R( K[ m ], *r ); + P[m] = GSM_ADD( P[ m+1 ], temp ); + + temp = GSM_MULT_R( P[ m+1 ], *r ); + K[m] = GSM_ADD( K[ m ], temp ); + } + } +} + +/* 4.2.6 */ + +static void Transformation_to_Log_Area_Ratios P1((r), + register word * r /* 0..7 IN/OUT */ +) +/* + * The following scaling for r[..] and LAR[..] has been used: + * + * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. + * LAR[..] = integer( real_LAR[..] * 16384 ); + * with -1.625 <= real_LAR <= 1.625 + */ +{ + register word temp; + register int i; + + + /* Computation of the LAR[0..7] from the r[0..7] + */ + for (i = 1; i <= 8; i++, r++) { + + temp = *r; + temp = GSM_ABS(temp); + assert(temp >= 0); + + if (temp < 22118) { + temp >>= 1; + } else if (temp < 31130) { + assert( temp >= 11059 ); + temp -= 11059; + } else { + assert( temp >= 26112 ); + temp -= 26112; + temp <<= 2; + } + + *r = *r < 0 ? -temp : temp; + assert( *r != MIN_WORD ); + } +} + +/* 4.2.7 */ + +static void Quantization_and_coding P1((LAR), + register word * LAR /* [0..7] IN/OUT */ +) +{ + register word temp; + longword ltmp; + + + /* This procedure needs four tables; the following equations + * give the optimum scaling for the constants: + * + * A[0..7] = integer( real_A[0..7] * 1024 ) + * B[0..7] = integer( real_B[0..7] * 512 ) + * MAC[0..7] = maximum of the LARc[0..7] + * MIC[0..7] = minimum of the LARc[0..7] + */ + +# undef STEP +# define STEP( A, B, MAC, MIC ) \ + temp = GSM_MULT( A, *LAR ); \ + temp = GSM_ADD( temp, B ); \ + temp = GSM_ADD( temp, 256 ); \ + temp = SASR( temp, 9 ); \ + *LAR = temp>MAC ? MAC - MIC : (tempfast) Fast_Autocorrelation (s, L_ACF ); + else +#endif + Autocorrelation (s, L_ACF ); + Reflection_coefficients (L_ACF, LARc ); + Transformation_to_Log_Area_Ratios (LARc); + Quantization_and_coding (LARc); +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/preprocess.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/preprocess.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,113 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/preprocess.c,v 1.2 1994/05/10 20:18:45 jutta Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION + * + * After A-law to linear conversion (or directly from the + * Ato D converter) the following scaling is assumed for + * input to the RPE-LTP algorithm: + * + * in: 0.1.....................12 + * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* + * + * Where S is the sign bit, v a valid bit, and * a "don't care" bit. + * The original signal is called sop[..] + * + * out: 0.1................... 12 + * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 + */ + + +void Gsm_Preprocess P3((S, s, so), + struct gsm_state * S, + word * s, + word * so ) /* [0..159] IN/OUT */ +{ + + word z1 = S->z1; + longword L_z2 = S->L_z2; + word mp = S->mp; + + word s1; + longword L_s2; + + longword L_temp; + + word msp, lsp; + word SO; + + longword ltmp; /* for ADD */ + ulongword utmp; /* for L_ADD */ + + register int k = 160; + + while (k--) { + + /* 4.2.1 Downscaling of the input signal + */ + SO = SASR( *s, 3 ) << 2; + s++; + + assert (SO >= -0x4000); /* downscaled by */ + assert (SO <= 0x3FFC); /* previous routine. */ + + + /* 4.2.2 Offset compensation + * + * This part implements a high-pass filter and requires extended + * arithmetic precision for the recursive part of this filter. + * The input of this procedure is the array so[0...159] and the + * output the array sof[ 0...159 ]. + */ + /* Compute the non-recursive part + */ + + s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */ + z1 = SO; + + assert(s1 != MIN_WORD); + + /* Compute the recursive part + */ + L_s2 = s1; + L_s2 <<= 15; + + /* Execution of a 31 bv 16 bits multiplication + */ + + msp = SASR( L_z2, 15 ); + lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */ + + L_s2 += GSM_MULT_R( lsp, 32735 ); + L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ + L_z2 = GSM_L_ADD( L_temp, L_s2 ); + + /* Compute sof[k] with rounding + */ + L_temp = GSM_L_ADD( L_z2, 16384 ); + + /* 4.2.3 Preemphasis + */ + + msp = GSM_MULT_R( mp, -28180 ); + mp = SASR( L_temp, 15 ); + *so++ = GSM_ADD( mp, msp ); + } + + S->z1 = z1; + S->L_z2 = L_z2; + S->mp = mp; +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/private.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/private.h Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,268 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/private.h,v 1.6 1996/07/02 10:15:26 jutta Exp $*/ + +#ifndef PRIVATE_H +#define PRIVATE_H + +typedef short word; /* 16 bit signed int */ +typedef long longword; /* 32 bit signed int */ + +typedef unsigned short uword; /* unsigned word */ +typedef unsigned long ulongword; /* unsigned longword */ + +struct gsm_state { + + word dp0[ 280 ]; + + word z1; /* preprocessing.c, Offset_com. */ + longword L_z2; /* Offset_com. */ + int mp; /* Preemphasis */ + + word u[8]; /* short_term_aly_filter.c */ + word LARpp[2][8]; /* */ + word j; /* */ + + word ltp_cut; /* long_term.c, LTP crosscorr. */ + word nrp; /* 40 */ /* long_term.c, synthesis */ + word v[9]; /* short_term.c, synthesis */ + word msr; /* decoder.c, Postprocessing */ + + char verbose; /* only used if !NDEBUG */ + char fast; /* only used if FAST */ + + char wav_fmt; /* only used if WAV49 defined */ + unsigned char frame_index; /* odd/even chaining */ + unsigned char frame_chain; /* half-byte to carry forward */ +}; + + +#define MIN_WORD (-32767 - 1) +#define MAX_WORD 32767 + +#define MIN_LONGWORD (-2147483647 - 1) +#define MAX_LONGWORD 2147483647 + +#ifdef SASR /* flag: >> is a signed arithmetic shift right */ +#undef SASR +#define SASR(x, by) ((x) >> (by)) +#else +#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by)))) +#endif /* SASR */ + +#include "proto.h" + +/* + * Prototypes from add.c + */ +extern word gsm_mult P((word a, word b)); +extern longword gsm_L_mult P((word a, word b)); +extern word gsm_mult_r P((word a, word b)); + +extern word gsm_div P((word num, word denum)); + +extern word gsm_add P(( word a, word b )); +extern longword gsm_L_add P(( longword a, longword b )); + +extern word gsm_sub P((word a, word b)); +extern longword gsm_L_sub P((longword a, longword b)); + +extern word gsm_abs P((word a)); + +extern word gsm_norm P(( longword a )); + +extern longword gsm_L_asl P((longword a, int n)); +extern word gsm_asl P((word a, int n)); + +extern longword gsm_L_asr P((longword a, int n)); +extern word gsm_asr P((word a, int n)); + +/* + * Inlined functions from add.h + */ + +/* + * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ + * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) + */ +#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) + +# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_L_MULT(a, b) /* word a, word b */ \ + (((longword)(a) * (longword)(b)) << 1) + +# define GSM_L_ADD(a, b) \ + ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ + ? MAX_LONGWORD : utmp)) + +/* + * # define GSM_ADD(a, b) \ + * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ + * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + */ +/* Nonportable, but faster: */ + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +/* Use these if necessary: + +# define GSM_MULT_R(a, b) gsm_mult_r(a, b) +# define GSM_MULT(a, b) gsm_mult(a, b) +# define GSM_L_MULT(a, b) gsm_L_mult(a, b) + +# define GSM_L_ADD(a, b) gsm_L_add(a, b) +# define GSM_ADD(a, b) gsm_add(a, b) +# define GSM_SUB(a, b) gsm_sub(a, b) + +# define GSM_ABS(a) gsm_abs(a) + +*/ + +/* + * More prototypes from implementations.. + */ +extern void Gsm_Coder P(( + struct gsm_state * S, + word * s, /* [0..159] samples IN */ + word * LARc, /* [0..7] LAR coefficients OUT */ + word * Nc, /* [0..3] LTP lag OUT */ + word * bc, /* [0..3] coded LTP gain OUT */ + word * Mc, /* [0..3] RPE grid selection OUT */ + word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ + word * xMc /* [13*4] normalized RPE samples OUT */)); + +extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */ + struct gsm_state * S, + word * d, /* [0..39] residual signal IN */ + word * dp, /* [-120..-1] d' IN */ + word * e, /* [0..40] OUT */ + word * dpp, /* [0..40] OUT */ + word * Nc, /* correlation lag OUT */ + word * bc /* gain factor OUT */)); + +extern void Gsm_LPC_Analysis P(( + struct gsm_state * S, + word * s, /* 0..159 signals IN/OUT */ + word * LARc)); /* 0..7 LARc's OUT */ + +extern void Gsm_Preprocess P(( + struct gsm_state * S, + word * s, word * so)); + +extern void Gsm_Encoding P(( + struct gsm_state * S, + word * e, + word * ep, + word * xmaxc, + word * Mc, + word * xMc)); + +extern void Gsm_Short_Term_Analysis_Filter P(( + struct gsm_state * S, + word * LARc, /* coded log area ratio [0..7] IN */ + word * d /* st res. signal [0..159] IN/OUT */)); + +extern void Gsm_Decoder P(( + struct gsm_state * S, + word * LARcr, /* [0..7] IN */ + word * Ncr, /* [0..3] IN */ + word * bcr, /* [0..3] IN */ + word * Mcr, /* [0..3] IN */ + word * xmaxcr, /* [0..3] IN */ + word * xMcr, /* [0..13*4] IN */ + word * s)); /* [0..159] OUT */ + +extern void Gsm_Decoding P(( + struct gsm_state * S, + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12] IN */ + word * erp)); /* [0..39] OUT */ + +extern void Gsm_Long_Term_Synthesis_Filtering P(( + struct gsm_state* S, + word Ncr, + word bcr, + word * erp, /* [0..39] IN */ + word * drp)); /* [-120..-1] IN, [0..40] OUT */ + +void Gsm_RPE_Decoding P(( + struct gsm_state *S, + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12], 3 bits IN */ + word * erp)); /* [0..39] OUT */ + +void Gsm_RPE_Encoding P(( + struct gsm_state * S, + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc)); /* [0..12] OUT */ + +extern void Gsm_Short_Term_Synthesis_Filter P(( + struct gsm_state * S, + word * LARcr, /* log area ratios [0..7] IN */ + word * drp, /* received d [0...39] IN */ + word * s)); /* signal s [0..159] OUT */ + +extern void Gsm_Update_of_reconstructed_short_time_residual_signal P(( + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp)); /* [-120...-1] IN/OUT */ + +/* + * Tables from table.c + */ +#ifndef GSM_TABLE_C + +extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8]; +extern word gsm_INVA[8]; +extern word gsm_DLB[4], gsm_QLB[4]; +extern word gsm_H[11]; +extern word gsm_NRFAC[8]; +extern word gsm_FAC[8]; + +#endif /* GSM_TABLE_C */ + +/* + * Debugging + */ +#ifdef NDEBUG + +# define gsm_debug_words(a, b, c, d) /* nil */ +# define gsm_debug_longwords(a, b, c, d) /* nil */ +# define gsm_debug_word(a, b) /* nil */ +# define gsm_debug_longword(a, b) /* nil */ + +#else /* !NDEBUG => DEBUG */ + + extern void gsm_debug_words P((char * name, int, int, word *)); + extern void gsm_debug_longwords P((char * name, int, int, longword *)); + extern void gsm_debug_longword P((char * name, longword)); + extern void gsm_debug_word P((char * name, word)); + +#endif /* !NDEBUG */ + +#include "unproto.h" + +#endif /* PRIVATE_H */ diff -r e29937c5670c -r f703b3e14f9a jni/gsm/proto.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/proto.h Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,65 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/proto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/ + +#ifndef PROTO_H +#define PROTO_H + +#if __cplusplus +# define NeedFunctionPrototypes 1 +#endif + +#if __STDC__ +# define NeedFunctionPrototypes 1 +#endif + +#ifdef _NO_PROTO +# undef NeedFunctionPrototypes +#endif + +#undef P /* gnu stdio.h actually defines this... */ +#undef P0 +#undef P1 +#undef P2 +#undef P3 +#undef P4 +#undef P5 +#undef P6 +#undef P7 +#undef P8 + +#if NeedFunctionPrototypes + +# define P( protos ) protos + +# define P0() (void) +# define P1(x, a) (a) +# define P2(x, a, b) (a, b) +# define P3(x, a, b, c) (a, b, c) +# define P4(x, a, b, c, d) (a, b, c, d) +# define P5(x, a, b, c, d, e) (a, b, c, d, e) +# define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f) +# define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g) +# define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h) + +#else /* !NeedFunctionPrototypes */ + +# define P( protos ) ( /* protos */ ) + +# define P0() () +# define P1(x, a) x a; +# define P2(x, a, b) x a; b; +# define P3(x, a, b, c) x a; b; c; +# define P4(x, a, b, c, d) x a; b; c; d; +# define P5(x, a, b, c, d, e) x a; b; c; d; e; +# define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f; +# define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g; +# define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h; + +#endif /* !NeedFunctionPrototypes */ + +#endif /* PROTO_H */ diff -r e29937c5670c -r f703b3e14f9a jni/gsm/rpe.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/rpe.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,496 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/rpe.c,v 1.3 1994/05/10 20:18:46 jutta Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION + */ + +/* 4.2.13 */ + +static void Weighting_filter P2((e, x), + register word * e, /* signal [-5..0.39.44] IN */ + word * x /* signal [0..39] OUT */ +) +/* + * The coefficients of the weighting filter are stored in a table + * (see table 4.4). The following scaling is used: + * + * H[0..10] = integer( real_H[ 0..10] * 8192 ); + */ +{ + /* word wt[ 50 ]; */ + + register longword L_result; + register int k /* , i */ ; + + /* Initialization of a temporary working array wt[0...49] + */ + + /* for (k = 0; k <= 4; k++) wt[k] = 0; + * for (k = 5; k <= 44; k++) wt[k] = *e++; + * for (k = 45; k <= 49; k++) wt[k] = 0; + * + * (e[-5..-1] and e[40..44] are allocated by the caller, + * are initially zero and are not written anywhere.) + */ + e -= 5; + + /* Compute the signal x[0..39] + */ + for (k = 0; k <= 39; k++) { + + L_result = 8192 >> 1; + + /* for (i = 0; i <= 10; i++) { + * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); + * L_result = GSM_L_ADD( L_result, L_temp ); + * } + */ + +#undef STEP +#define STEP( i, H ) (e[ k + i ] * (longword)H) + + /* Every one of these multiplications is done twice -- + * but I don't see an elegant way to optimize this. + * Do you? + */ + +#ifdef STUPID_COMPILER + L_result += STEP( 0, -134 ) ; + L_result += STEP( 1, -374 ) ; + /* + STEP( 2, 0 ) */ + L_result += STEP( 3, 2054 ) ; + L_result += STEP( 4, 5741 ) ; + L_result += STEP( 5, 8192 ) ; + L_result += STEP( 6, 5741 ) ; + L_result += STEP( 7, 2054 ) ; + /* + STEP( 8, 0 ) */ + L_result += STEP( 9, -374 ) ; + L_result += STEP( 10, -134 ) ; +#else + L_result += + STEP( 0, -134 ) + + STEP( 1, -374 ) + /* + STEP( 2, 0 ) */ + + STEP( 3, 2054 ) + + STEP( 4, 5741 ) + + STEP( 5, 8192 ) + + STEP( 6, 5741 ) + + STEP( 7, 2054 ) + /* + STEP( 8, 0 ) */ + + STEP( 9, -374 ) + + STEP(10, -134 ) + ; +#endif + + /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) + * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) + * + * x[k] = SASR( L_result, 16 ); + */ + + /* 2 adds vs. >>16 => 14, minus one shift to compensate for + * those we lost when replacing L_MULT by '*'. + */ + + L_result = SASR( L_result, 13 ); + x[k] = ( L_result < MIN_WORD ? MIN_WORD + : (L_result > MAX_WORD ? MAX_WORD : L_result )); + } +} + +/* 4.2.14 */ + +static void RPE_grid_selection P3((x,xM,Mc_out), + word * x, /* [0..39] IN */ + word * xM, /* [0..12] OUT */ + word * Mc_out /* OUT */ +) +/* + * The signal x[0..39] is used to select the RPE grid which is + * represented by Mc. + */ +{ + /* register word temp1; */ + register int /* m, */ i; + register longword L_result, L_temp; + longword EM; /* xxx should be L_EM? */ + word Mc; + + longword L_common_0_3; + + EM = 0; + Mc = 0; + + /* for (m = 0; m <= 3; m++) { + * L_result = 0; + * + * + * for (i = 0; i <= 12; i++) { + * + * temp1 = SASR( x[m + 3*i], 2 ); + * + * assert(temp1 != MIN_WORD); + * + * L_temp = GSM_L_MULT( temp1, temp1 ); + * L_result = GSM_L_ADD( L_temp, L_result ); + * } + * + * if (L_result > EM) { + * Mc = m; + * EM = L_result; + * } + * } + */ + +#undef STEP +#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ + L_result += L_temp * L_temp; + + /* common part of 0 and 3 */ + + L_result = 0; + STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); + STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); + STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); + L_common_0_3 = L_result; + + /* i = 0 */ + + STEP( 0, 0 ); + L_result <<= 1; /* implicit in L_MULT */ + EM = L_result; + + /* i = 1 */ + + L_result = 0; + STEP( 1, 0 ); + STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); + STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); + STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 1; + EM = L_result; + } + + /* i = 2 */ + + L_result = 0; + STEP( 2, 0 ); + STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); + STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); + STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); + L_result <<= 1; + if (L_result > EM) { + Mc = 2; + EM = L_result; + } + + /* i = 3 */ + + L_result = L_common_0_3; + STEP( 3, 12 ); + L_result <<= 1; + if (L_result > EM) { + Mc = 3; + EM = L_result; + } + + /**/ + + /* Down-sampling by a factor 3 to get the selected xM[0..12] + * RPE sequence. + */ + for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; + *Mc_out = Mc; +} + +/* 4.12.15 */ + +static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), + word xmaxc, /* IN */ + word * exp_out, /* OUT */ + word * mant_out ) /* OUT */ +{ + word exp, mant; + + /* Compute exponent and mantissa of the decoded version of xmaxc + */ + + exp = 0; + if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; + mant = xmaxc - (exp << 3); + + if (mant == 0) { + exp = -4; + mant = 7; + } + else { + while (mant <= 7) { + mant = mant << 1 | 1; + exp--; + } + mant -= 8; + } + + assert( exp >= -4 && exp <= 6 ); + assert( mant >= 0 && mant <= 7 ); + + *exp_out = exp; + *mant_out = mant; +} + +static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), + word * xM, /* [0..12] IN */ + + word * xMc, /* [0..12] OUT */ + word * mant_out, /* OUT */ + word * exp_out, /* OUT */ + word * xmaxc_out /* OUT */ +) +{ + int i, itest; + + word xmax, xmaxc, temp, temp1, temp2; + word exp, mant; + + + /* Find the maximum absolute value xmax of xM[0..12]. + */ + + xmax = 0; + for (i = 0; i <= 12; i++) { + temp = xM[i]; + temp = GSM_ABS(temp); + if (temp > xmax) xmax = temp; + } + + /* Qantizing and coding of xmax to get xmaxc. + */ + + exp = 0; + temp = SASR( xmax, 9 ); + itest = 0; + + for (i = 0; i <= 5; i++) { + + itest |= (temp <= 0); + temp = SASR( temp, 1 ); + + assert(exp <= 5); + if (itest == 0) exp++; /* exp = add (exp, 1) */ + } + + assert(exp <= 6 && exp >= 0); + temp = exp + 5; + + assert(temp <= 11 && temp >= 0); + xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); + + /* Quantizing and coding of the xM[0..12] RPE sequence + * to get the xMc[0..12] + */ + + APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); + + /* This computation uses the fact that the decoded version of xmaxc + * can be calculated by using the exponent and the mantissa part of + * xmaxc (logarithmic table). + * So, this method avoids any division and uses only a scaling + * of the RPE samples by a function of the exponent. A direct + * multiplication by the inverse of the mantissa (NRFAC[0..7] + * found in table 4.5) gives the 3 bit coded version xMc[0..12] + * of the RPE samples. + */ + + + /* Direct computation of xMc[0..12] using table 4.5 + */ + + assert( exp <= 4096 && exp >= -4096); + assert( mant >= 0 && mant <= 7 ); + + temp1 = 6 - exp; /* normalization by the exponent */ + temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ + + for (i = 0; i <= 12; i++) { + + assert(temp1 >= 0 && temp1 < 16); + + temp = xM[i] << temp1; + temp = GSM_MULT( temp, temp2 ); + temp = SASR(temp, 12); + xMc[i] = temp + 4; /* see note below */ + } + + /* NOTE: This equation is used to make all the xMc[i] positive. + */ + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; +} + +/* 4.2.16 */ + +static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), + register word * xMc, /* [0..12] IN */ + word mant, + word exp, + register word * xMp) /* [0..12] OUT */ +/* + * This part is for decoding the RPE sequence of coded xMc[0..12] + * samples to obtain the xMp[0..12] array. Table 4.6 is used to get + * the mantissa of xmaxc (FAC[0..7]). + */ +{ + int i; + word temp, temp1, temp2, temp3; + longword ltmp; + + assert( mant >= 0 && mant <= 7 ); + + temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ + temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ + temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); + + for (i = 13; i--;) { + + assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */ + + /* temp = gsm_sub( *xMc++ << 1, 7 ); */ + temp = (*xMc++ << 1) - 7; /* restore sign */ + assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */ + + temp <<= 12; /* 16 bit signed */ + temp = GSM_MULT_R( temp1, temp ); + temp = GSM_ADD( temp, temp3 ); + *xMp++ = gsm_asr( temp, temp2 ); + } +} + +/* 4.2.17 */ + +static void RPE_grid_positioning P3((Mc,xMp,ep), + word Mc, /* grid position IN */ + register word * xMp, /* [0..12] IN */ + register word * ep /* [0..39] OUT */ +) +/* + * This procedure computes the reconstructed long term residual signal + * ep[0..39] for the LTP analysis filter. The inputs are the Mc + * which is the grid position selection and the xMp[0..12] decoded + * RPE samples which are upsampled by a factor of 3 by inserting zero + * values. + */ +{ + int i = 13; + + assert(0 <= Mc && Mc <= 3); + + switch (Mc) { + case 3: *ep++ = 0; + case 2: do { + *ep++ = 0; + case 1: *ep++ = 0; + case 0: *ep++ = *xMp++; + } while (--i); + } + while (++Mc < 4) *ep++ = 0; + + /* + + int i, k; + for (k = 0; k <= 39; k++) ep[k] = 0; + for (i = 0; i <= 12; i++) { + ep[ Mc + (3*i) ] = xMp[i]; + } + */ +} + +/* 4.2.18 */ + +/* This procedure adds the reconstructed long term residual signal + * ep[0..39] to the estimated signal dpp[0..39] from the long term + * analysis filter to compute the reconstructed short term residual + * signal dp[-40..-1]; also the reconstructed short term residual + * array dp[-120..-41] is updated. + */ + +#if 0 /* Has been inlined in code.c */ +void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), + word * dpp, /* [0...39] IN */ + word * ep, /* [0...39] IN */ + word * dp) /* [-120...-1] IN/OUT */ +{ + int k; + + for (k = 0; k <= 79; k++) + dp[ -120 + k ] = dp[ -80 + k ]; + + for (k = 0; k <= 39; k++) + dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); +} +#endif /* Has been inlined in code.c */ + +void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), + + struct gsm_state * S, + + word * e, /* -5..-1][0..39][40..44 IN/OUT */ + word * xmaxc, /* OUT */ + word * Mc, /* OUT */ + word * xMc) /* [0..12] OUT */ +{ + word x[40]; + word xM[13], xMp[13]; + word mant, exp; +// Wirlab + (void)S; + + + + Weighting_filter(e, x); + RPE_grid_selection(x, xM, Mc); + + APCM_quantization( xM, xMc, &mant, &exp, xmaxc); + APCM_inverse_quantization( xMc, mant, exp, xMp); + + RPE_grid_positioning( *Mc, xMp, e ); + +} + +void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), + struct gsm_state * S, + + word xmaxcr, + word Mcr, + word * xMcr, /* [0..12], 3 bits IN */ + word * erp /* [0..39] OUT */ +) +{ + word exp, mant; + word xMp[ 13 ]; +// Wirlab + (void)S; + + + + APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); + APCM_inverse_quantization( xMcr, mant, exp, xMp ); + RPE_grid_positioning( Mcr, xMp, erp ); + +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/short_term.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/short_term.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,429 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/short_term.c,v 1.2 1994/05/10 20:18:47 jutta Exp $ */ + +#include +#include + +#include "private.h" + +#include "gsm.h" +#include "proto.h" + +/* + * SHORT TERM ANALYSIS FILTERING SECTION + */ + +/* 4.2.8 */ + +static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp), + word * LARc, /* coded log area ratio [0..7] IN */ + word * LARpp) /* out: decoded .. */ +{ + register word temp1 /* , temp2 */; + register long ltmp; /* for GSM_ADD */ + + /* This procedure requires for efficient implementation + * two tables. + * + * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) + * MIC[1..8] = minimum value of the LARc[1..8] + */ + + /* Compute the LARpp[1..8] + */ + + /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { + * + * temp1 = GSM_ADD( *LARc, *MIC ) << 10; + * temp2 = *B << 1; + * temp1 = GSM_SUB( temp1, temp2 ); + * + * assert(*INVA != MIN_WORD); + * + * temp1 = GSM_MULT_R( *INVA, temp1 ); + * *LARpp = GSM_ADD( temp1, temp1 ); + * } + */ + +#undef STEP +#define STEP( B, MIC, INVA ) \ + temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ + temp1 = GSM_SUB( temp1, B << 1 ); \ + temp1 = GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = GSM_ADD( temp1, temp1 ); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( -2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( -1792, -8, 17476 ); + STEP( -341, -4, 31454 ); + STEP( -1144, -4, 29708 ); + + /* NOTE: the addition of *MIC is used to restore + * the sign of *LARc. + */ +} + +/* 4.2.9 */ +/* Computation of the quantized reflection coefficients + */ + +/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] + */ + +/* + * Within each frame of 160 analyzed speech samples the short term + * analysis and synthesis filters operate with four different sets of + * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) + * and the actual set of decoded LARs (LARpp(j)) + * + * (Initial value: LARpp(j-1)[1..8] = 0.) + */ + +static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); + } +} + +static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); + } +} + +static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), + register word * LARpp_j_1, + register word * LARpp_j, + register word * LARp) +{ + register int i; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { + *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); + *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); + } +} + + +static void Coefficients_40_159 P2((LARpp_j, LARp), + register word * LARpp_j, + register word * LARp) +{ + register int i; + + for (i = 1; i <= 8; i++, LARp++, LARpp_j++) + *LARp = *LARpp_j; +} + +/* 4.2.9.2 */ + +static void LARp_to_rp P1((LARp), + register word * LARp) /* [0..7] IN/OUT */ +/* + * The input of this procedure is the interpolated LARp[0..7] array. + * The reflection coefficients, rp[i], are used in the analysis + * filter and in the synthesis filter. + */ +{ + register int i; + register word temp; + register longword ltmp; + + for (i = 1; i <= 8; i++, LARp++) { + + /* temp = GSM_ABS( *LARp ); + * + * if (temp < 11059) temp <<= 1; + * else if (temp < 20070) temp += 11059; + * else temp = GSM_ADD( temp >> 2, 26112 ); + * + * *LARp = *LARp < 0 ? -temp : temp; + */ + + if (*LARp < 0) { + temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); + *LARp = - ((temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 ))); + } else { + temp = *LARp; + *LARp = (temp < 11059) ? temp << 1 + : ((temp < 20070) ? temp + 11059 + : GSM_ADD( temp >> 2, 26112 )); + } + } +} + + +/* 4.2.10 */ +static void Short_term_analysis_filtering P4((S,rp,k_n,s), + struct gsm_state * S, + register word * rp, /* [0..7] IN */ + register int k_n, /* k_end - k_start */ + register word * s /* [0..n-1] IN/OUT */ +) +/* + * This procedure computes the short term residual signal d[..] to be fed + * to the RPE-LTP loop from the s[..] signal and from the local rp[..] + * array (quantized reflection coefficients). As the call of this + * procedure can be done in many ways (see the interpolation of the LAR + * coefficient), it is assumed that the computation begins with index + * k_start (for arrays d[..] and s[..]) and stops with index k_end + * (k_start and k_end are defined in 4.2.9.1). This procedure also + * needs to keep the array u[0..7] in memory for each call. + */ +{ + register word * u = S->u; + register int i; + register word di, zzz, ui, sav, rpi; + register longword ltmp; + + for (; k_n--; s++) { + + di = sav = *s; + + for (i = 0; i < 8; i++) { /* YYY */ + + ui = u[i]; + rpi = rp[i]; + u[i] = sav; + + zzz = GSM_MULT_R(rpi, di); + sav = GSM_ADD( ui, zzz); + + zzz = GSM_MULT_R(rpi, ui); + di = GSM_ADD( di, zzz ); + } + + *s = di; + } +} + +#if defined(USE_FLOAT_MUL) && defined(FAST) + +static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s), + struct gsm_state * S, + register word * rp, /* [0..7] IN */ + register int k_n, /* k_end - k_start */ + register word * s /* [0..n-1] IN/OUT */ +) +{ + register word * u = S->u; + register int i; + + float uf[8], + rpf[8]; + + register float scalef = 3.0517578125e-5; + register float sav, di, temp; + + for (i = 0; i < 8; ++i) { + uf[i] = u[i]; + rpf[i] = rp[i] * scalef; + } + for (; k_n--; s++) { + sav = di = *s; + for (i = 0; i < 8; ++i) { + register float rpfi = rpf[i]; + register float ufi = uf[i]; + + uf[i] = sav; + temp = rpfi * di + ufi; + di += rpfi * ufi; + sav = temp; + } + *s = di; + } + for (i = 0; i < 8; ++i) u[i] = uf[i]; +} +#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ + +static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), + struct gsm_state * S, + register word * rrp, /* [0..7] IN */ + register int k, /* k_end - k_start */ + register word * wt, /* [0..k-1] IN */ + register word * sr /* [0..k-1] OUT */ +) +{ + register word * v = S->v; + register int i; + register word sri, tmp1, tmp2; + register longword ltmp; /* for GSM_ADD & GSM_SUB */ + + while (k--) { + sri = *wt++; + for (i = 8; i--;) { + + /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); + */ + tmp1 = rrp[i]; + tmp2 = v[i]; + tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD + ? MAX_WORD + : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 + + 16384) >> 15)) ; + + sri = GSM_SUB( sri, tmp2 ); + + /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); + */ + tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD + ? MAX_WORD + : 0x0FFFF & (( (longword)tmp1 * (longword)sri + + 16384) >> 15)) ; + + v[i+1] = GSM_ADD( v[i], tmp1); + } + *sr++ = v[0] = sri; + } +} + + +#if defined(FAST) && defined(USE_FLOAT_MUL) + +static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), + struct gsm_state * S, + register word * rrp, /* [0..7] IN */ + register int k, /* k_end - k_start */ + register word * wt, /* [0..k-1] IN */ + register word * sr /* [0..k-1] OUT */ +) +{ + register word * v = S->v; + register int i; + + float va[9], rrpa[8]; + register float scalef = 3.0517578125e-5, temp; + + for (i = 0; i < 8; ++i) { + va[i] = v[i]; + rrpa[i] = (float)rrp[i] * scalef; + } + while (k--) { + register float sri = *wt++; + for (i = 8; i--;) { + sri -= rrpa[i] * va[i]; + if (sri < -32768.) sri = -32768.; + else if (sri > 32767.) sri = 32767.; + + temp = va[i] + rrpa[i] * sri; + if (temp < -32768.) temp = -32768.; + else if (temp > 32767.) temp = 32767.; + va[i+1] = temp; + } + *sr++ = va[0] = sri; + } + for (i = 0; i < 9; ++i) v[i] = va[i]; +} + +#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ + +void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s), + + struct gsm_state * S, + + word * LARc, /* coded log area ratio [0..7] IN */ + word * s /* signal [0..159] IN/OUT */ +) +{ + word * LARpp_j = S->LARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; + + word LARp[8]; + +#undef FILTER +#if defined(FAST) && defined(USE_FLOAT_MUL) +# define FILTER (* (S->fast \ + ? Fast_Short_term_analysis_filtering \ + : Short_term_analysis_filtering )) + +#else +# define FILTER Short_term_analysis_filtering +#endif + + Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); + + Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s); + + Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 14, s + 13); + + Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, s + 27); + + Coefficients_40_159( LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 120, s + 40); +} + +void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), + struct gsm_state * S, + + word * LARcr, /* received log area ratios [0..7] IN */ + word * wt, /* received d [0..159] IN */ + + word * s /* signal s [0..159] OUT */ +) +{ + word * LARpp_j = S->LARpp[ S->j ]; + word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; + + word LARp[8]; + +#undef FILTER +#if defined(FAST) && defined(USE_FLOAT_MUL) + +# define FILTER (* (S->fast \ + ? Fast_Short_term_synthesis_filtering \ + : Short_term_synthesis_filtering )) +#else +# define FILTER Short_term_synthesis_filtering +#endif + + Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); + + Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, wt, s ); + + Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 14, wt + 13, s + 13 ); + + Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); + LARp_to_rp( LARp ); + FILTER( S, LARp, 13, wt + 27, s + 27 ); + + Coefficients_40_159( LARpp_j, LARp ); + LARp_to_rp( LARp ); + FILTER(S, LARp, 120, wt + 40, s + 40); +} diff -r e29937c5670c -r f703b3e14f9a jni/gsm/table.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/table.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/table.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */ + +/* Most of these tables are inlined at their point of use. + */ + +/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP + * CODER AND DECODER + * + * (Most of them inlined, so watch out.) + */ + +#define GSM_TABLE_C +#include "private.h" +#include "gsm.h" + +/* Table 4.1 Quantization of the Log.-Area Ratios + */ +/* i 1 2 3 4 5 6 7 8 */ +word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; +word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144}; +word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 }; +word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 }; + + +/* Table 4.2 Tabulation of 1/A[1..8] + */ +word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 }; + + +/* Table 4.3a Decision level of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; + + +/* Table 4.3b Quantization levels of the LTP gain quantizer + */ +/* bc 0 1 2 3 */ +word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; + + +/* Table 4.4 Coefficients of the weighting filter + */ +/* i 0 1 2 3 4 5 6 7 8 9 10 */ +word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; + + +/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; + + +/* Table 4.6 Normalized direct mantissa used to compute xM/xmax + */ +/* i 0 1 2 3 4 5 6 7 */ +word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; diff -r e29937c5670c -r f703b3e14f9a jni/gsm/toast_alaw.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/toast_alaw.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,334 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/toast_alaw.c,v 1.2 1996/07/05 17:23:46 jutta Exp $ */ + +#include "toast.h" + +/* toast_alaw.c -- manipulate A-law encoded sound. + */ + +extern FILE * in, * out; + +#define A2S(x) (a2s[ (unsigned char )(x) ]) +#define S2A(x) (s2a[ ((unsigned short)(x)) >> 4 ]) + +static unsigned short a2s[] = { + + 60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, + 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, + 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, + 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, + 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, + 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, + 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, + 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, + 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, + 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, + 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, + 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, + 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, + 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, + 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, + 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, + 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, + 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, + 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, + 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, + 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, + 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, + 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, + 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, + 344, 328, 376, 360, 280, 264, 312, 296, + 472, 456, 504, 488, 408, 392, 440, 424, + 88, 72, 120, 104, 24, 8, 56, 40, + 216, 200, 248, 232, 152, 136, 184, 168, + 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, + 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, + 688, 656, 752, 720, 560, 528, 624, 592, + 944, 912, 1008, 976, 816, 784, 880, 848 + +}; + + +static unsigned char s2a[] = { + + 213,212,215,214,209,208,211,210,221,220,223,222,217,216,219,218, + 197,196,199,198,193,192,195,194,205,204,207,206,201,200,203,202, + 245,245,244,244,247,247,246,246,241,241,240,240,243,243,242,242, + 253,253,252,252,255,255,254,254,249,249,248,248,251,251,250,250, + 229,229,229,229,228,228,228,228,231,231,231,231,230,230,230,230, + 225,225,225,225,224,224,224,224,227,227,227,227,226,226,226,226, + 237,237,237,237,236,236,236,236,239,239,239,239,238,238,238,238, + 233,233,233,233,232,232,232,232,235,235,235,235,234,234,234,234, + 149,149,149,149,149,149,149,149,148,148,148,148,148,148,148,148, + 151,151,151,151,151,151,151,151,150,150,150,150,150,150,150,150, + 145,145,145,145,145,145,145,145,144,144,144,144,144,144,144,144, + 147,147,147,147,147,147,147,147,146,146,146,146,146,146,146,146, + 157,157,157,157,157,157,157,157,156,156,156,156,156,156,156,156, + 159,159,159,159,159,159,159,159,158,158,158,158,158,158,158,158, + 153,153,153,153,153,153,153,153,152,152,152,152,152,152,152,152, + 155,155,155,155,155,155,155,155,154,154,154,154,154,154,154,154, + 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, + 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, + 135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, + 134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, + 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, + 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, + 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, + 130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, + 141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, + 140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, + 143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, + 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, + 137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, + 136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, + 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, + 138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, + 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, + 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, + 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, + 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, + 183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, + 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, + 177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, + 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, + 176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, + 179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, + 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, + 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, + 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, + 191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, + 190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, + 190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, + 185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, + 185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, + 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, + 184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, + 187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, + 187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, + 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, + 186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, + 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, + 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, + 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, + 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, + 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, + 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, + 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, + 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, + 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, + 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, + 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, + 167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, + 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, + 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, + 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, + 166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, + 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, + 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, + 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, + 161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, + 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, + 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, + 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, + 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, + 162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, + 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, + 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, + 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, + 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, + 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, + 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, + 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, + 172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, + 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, + 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, + 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, + 175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, + 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, + 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, + 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, + 174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, + 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, + 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, + 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, + 169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, + 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, + 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, + 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, + 168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, + 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, + 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, + 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, + 171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 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, + 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, + 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, + 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, + 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, + 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, + 106,106,106,106,107,107,107,107,104,104,104,104,105,105,105,105, + 110,110,110,110,111,111,111,111,108,108,108,108,109,109,109,109, + 98, 98, 98, 98, 99, 99, 99, 99, 96, 96, 96, 96, 97, 97, 97, 97, + 102,102,102,102,103,103,103,103,100,100,100,100,101,101,101,101, + 122,122,123,123,120,120,121,121,126,126,127,127,124,124,125,125, + 114,114,115,115,112,112,113,113,118,118,119,119,116,116,117,117, + 74, 75, 72, 73, 78, 79, 76, 77, 66, 67, 64, 65, 70, 71, 68, 69, + 90, 91, 88, 89, 94, 95, 92, 93, 82, 83, 80, 81, 86, 87, 84, 85 +}; + +int alaw_input P1((buf), gsm_signal * buf) +{ + int i, c; + + for (i = 0; i < 160 && (c = fgetc(in)) != EOF; i++) buf[i] = A2S( c ); + if (c == EOF && ferror(in)) return -1; + return i; +} + +int alaw_output P1((buf), gsm_signal * buf) +{ + int i; + + for (i = 0; i < 160; i++, buf++) + if (fputc( S2A( *buf ), out) == EOF) return -1; + return 0; +} + diff -r e29937c5670c -r f703b3e14f9a jni/gsm/toast_audio.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/toast_audio.c Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,113 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/toast_audio.c,v 1.6 1995/03/07 21:21:24 jutta Exp $ */ + +#include "toast.h" + +/* toast_audio -- functions to manipulate SunOS audio files. + * + * This is reverse engineered from our present soundfiles + * and in no way portable, durable or aesthetically pleasing. + */ + +extern FILE * in, * out; +extern char * inname; +extern char * progname; + +extern int (*output) P((gsm_signal *)), + (*input ) P((gsm_signal *)); + +extern int alaw_input P((gsm_signal *)), + ulaw_input P((gsm_signal *)), + linear_input P((gsm_signal *)); + +extern int ulaw_output P((gsm_signal *)); + +static int put_u32 P2((f, u), FILE * f, unsigned long u) +{ + /* Write a 32-bit unsigned value msb first. + */ + if ( putc( (char)((u>>24) & 0x0FF), f) == EOF + || putc( (char)((u>>16) & 0x0FF), f) == EOF + || putc( (char)((u>> 8) & 0x0FF), f) == EOF + || putc( (char)( u & 0x0FF), f) == EOF) return -1; + + return 0; +} + +static int get_u32 P2((f, up), FILE * f, unsigned long * up) +{ + /* Read a 32-bit unsigned value msb first. + */ + int i; + unsigned long u; + + if ( (i = getc(f)) == EOF + || ((u = (unsigned char)i), (i = getc(f)) == EOF) + || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF) + || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF)) return -1; + *up = (u<<8)|(unsigned char)i; + return 0; +} + +int audio_init_input P0() +{ + unsigned long len, enc; /* unsigned 32 bits */ + + if ( fgetc(in) != '.' + || fgetc(in) != 's' + || fgetc(in) != 'n' + || fgetc(in) != 'd' + || get_u32( in, &len ) + || get_u32( in, &enc ) /* skip this */ + || get_u32( in, &enc )) { + fprintf(stderr, + "%s: bad (missing?) header in Sun audio file \"%s\";\n\ + Try one of -u, -a, -l instead (%s -h for help).\n", + progname, inname ? inname : "stdin", progname); + return -1; + } + + switch (enc) { + case 1: input = ulaw_input; break; + case 2: input = alaw_input; break; + case 3: input = linear_input; break; + default: + fprintf(stderr, +"%s: warning: file format #%lu for %s not implemented, defaulting to u-law.\n", + progname, enc, inname); + input = ulaw_input; + break; + } + + while (len > 4*4) + if (getc(in) == EOF) { + fprintf(stderr, + "%s: EOF in header of Sun audio file \"%s\";\n\ + Try one of -u, -a, -l instead (%s -h for help).\n", + progname, inname ? inname : "stdin", progname); + return -1; + } + else len--; + + return 0; +} + +int audio_init_output P0() +{ + if ( fputs(".snd", out) == EOF + || put_u32(out, 32) + || put_u32(out, ~(unsigned long)0) + || put_u32(out, 1) + || put_u32(out, 8000) + || put_u32(out, 1) + || put_u32(out, 0) + || put_u32(out, 0)) return -1; + + return 0; +} + diff -r e29937c5670c -r f703b3e14f9a jni/gsm/unproto.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jni/gsm/unproto.h Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,23 @@ +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/unproto.h,v 1.1 1992/10/28 00:11:08 jutta Exp $*/ + +#ifdef PROTO_H /* sic */ +#undef PROTO_H + +#undef P +#undef P0 +#undef P1 +#undef P2 +#undef P3 +#undef P4 +#undef P5 +#undef P6 +#undef P7 +#undef P8 + +#endif /* PROTO_H */ diff -r e29937c5670c -r f703b3e14f9a libs/armeabi/libOSNetworkSystem.so Binary file libs/armeabi/libOSNetworkSystem.so has changed diff -r e29937c5670c -r f703b3e14f9a libs/armeabi/libg722.so Binary file libs/armeabi/libg722.so has changed diff -r e29937c5670c -r f703b3e14f9a libs/armeabi/libgsm.so Binary file libs/armeabi/libgsm.so has changed diff -r e29937c5670c -r f703b3e14f9a res/layout/call.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/layout/call.xml Sat Jan 23 00:51:15 2010 +0100 @@ -0,0 +1,23 @@ + + + + + + +