src/org/sipdroid/media/RtpStreamSender.java
changeset 835 4e40f3481f23
parent 834 e8d6255306f8
child 836 2f2f5e24ac6a
equal deleted inserted replaced
834:e8d6255306f8 835:4e40f3481f23
    17  * You should have received a copy of the GNU General Public License
    17  * You should have received a copy of the GNU General Public License
    18  * along with this source code; if not, write to the Free Software
    18  * along with this source code; if not, write to the Free Software
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    20  */
    20  */
    21 
    21 
    22 package src.org.sipdroid.media;
    22 package org.sipdroid.media;
    23 
    23 
    24 import java.io.IOException;
    24 import java.io.IOException;
    25 import java.io.InputStream;
    25 import java.io.InputStream;
    26 import java.net.InetAddress;
    26 import java.net.InetAddress;
    27 import java.util.Random;
    27 import java.util.Random;
    28 
    28 
    29 import org.sipdroid.sipua.UserAgent;
    29 
    30 import org.sipdroid.sipua.ui.Receiver;
       
    31 import org.sipdroid.sipua.ui.Settings;
       
    32 import org.sipdroid.sipua.ui.Sipdroid;
       
    33 import org.sipdroid.pjlib.Codec;
    30 import org.sipdroid.pjlib.Codec;
    34 
    31 
    35 import src.org.sipdroid.net.RtpPacket;
    32 import org.sipdroid.media.RtpStreamReceiver;
    36 import src.org.sipdroid.net.RtpSocket;
    33 import org.sipdroid.net.RtpPacket;
    37 import src.org.sipdroid.net.SipdroidSocket;
    34 import org.sipdroid.net.RtpSocket;
       
    35 import org.sipdroid.net.SipdroidSocket;
       
    36 
       
    37 import com.beem.project.beem.ui.Call;
       
    38 import com.beem.project.beem.utils.BeemConnectivity;
    38 
    39 
    39 import android.content.Context;
    40 import android.content.Context;
    40 import android.media.AudioFormat;
    41 import android.media.AudioFormat;
    41 import android.media.AudioManager;
    42 import android.media.AudioManager;
    42 import android.media.AudioRecord;
    43 import android.media.AudioRecord;
    43 import android.media.MediaRecorder;
    44 import android.media.MediaRecorder;
    44 import android.preference.PreferenceManager;
    45 import android.preference.PreferenceManager;
       
    46 import android.provider.Settings;
    45 import android.telephony.TelephonyManager;
    47 import android.telephony.TelephonyManager;
    46 
    48 
    47 /**
    49 /**
    48  * RtpStreamSender is a generic stream sender. It takes an InputStream and sends
    50  * RtpStreamSender is a generic stream sender. It takes an InputStream and sends
    49  * it through RTP.
    51  * it through RTP.
    50  */
    52  */
    51 public class RtpStreamSender extends Thread {
    53 public class RtpStreamSender extends Thread {
    52 	/** Whether working in debug mode. */
    54     /** Whether working in debug mode. */
    53 	public static boolean DEBUG = true;
    55     public static boolean DEBUG = true;
    54 
    56 
    55 	/** The RtpSocket */
    57     /** The RtpSocket */
    56 	RtpSocket rtp_socket = null;
    58     RtpSocket rtp_socket = null;
    57 
    59 
    58 	/** Payload type */
    60     /** Payload type */
    59 	int p_type;
    61     int p_type;
    60 
    62 
    61 	/** Number of frame per second */
    63     /** Number of frame per second */
    62 	long frame_rate;
    64     long frame_rate;
    63 
    65 
    64 	/** Number of bytes per frame */
    66     /** Number of bytes per frame */
    65 	int frame_size;
    67     int frame_size;
    66 
    68 
    67 	/**
    69     /**
    68 	 * Whether it works synchronously with a local clock, or it it acts as slave
    70      * Whether it works synchronously with a local clock, or it it acts as slave
    69 	 * of the InputStream
    71      * of the InputStream
    70 	 */
    72      */
    71 	boolean do_sync = true;
    73     boolean do_sync = true;
    72 
    74 
    73 	/**
    75     /**
    74 	 * Synchronization correction value, in milliseconds. It accellarates the
    76      * Synchronization correction value, in milliseconds. It accellarates the
    75 	 * sending rate respect to the nominal value, in order to compensate program
    77      * sending rate respect to the nominal value, in order to compensate program
    76 	 * latencies.
    78      * latencies.
    77 	 */
    79      */
    78 	int sync_adj = 0;
    80     int sync_adj = 0;
    79 
    81 
    80 	/** Whether it is running */
    82     /** Whether it is running */
    81 	boolean running = false;
    83     boolean running = false;
    82 	boolean muted = false;
    84     boolean muted = false;
    83 
    85 
    84 	/**
    86     /**
    85 	 * Constructs a RtpStreamSender.
    87      * Constructs a RtpStreamSender.
    86 	 * 
    88      * 
    87 	 * @param input_stream
    89      * @param input_stream
    88 	 *            the stream to be sent
    90      *            the stream to be sent
    89 	 * @param do_sync
    91      * @param do_sync
    90 	 *            whether time synchronization must be performed by the
    92      *            whether time synchronization must be performed by the
    91 	 *            RtpStreamSender, or it is performed by the InputStream (e.g.
    93      *            RtpStreamSender, or it is performed by the InputStream (e.g.
    92 	 *            the system audio input)
    94      *            the system audio input)
    93 	 * @param payload_type
    95      * @param payload_type
    94 	 *            the payload type
    96      *            the payload type
    95 	 * @param frame_rate
    97      * @param frame_rate
    96 	 *            the frame rate, i.e. the number of frames that should be sent
    98      *            the frame rate, i.e. the number of frames that should be sent
    97 	 *            per second; it is used to calculate the nominal packet time
    99      *            per second; it is used to calculate the nominal packet time
    98 	 *            and,in case of do_sync==true, the next departure time
   100      *            and,in case of do_sync==true, the next departure time
    99 	 * @param frame_size
   101      * @param frame_size
   100 	 *            the size of the payload
   102      *            the size of the payload
   101 	 * @param src_socket
   103      * @param src_socket
   102 	 *            the socket used to send the RTP packet
   104      *            the socket used to send the RTP packet
   103 	 * @param dest_addr
   105      * @param dest_addr
   104 	 *            the destination address
   106      *            the destination address
   105 	 * @param dest_port
   107      * @param dest_port
   106 	 *            the destination port
   108      *            the destination port
   107 	 */
   109      */
   108 	public RtpStreamSender(boolean do_sync,
   110     public RtpStreamSender(boolean do_sync,
   109 			int payload_type, long frame_rate, int frame_size,
   111 	int payload_type, long frame_rate, int frame_size,
   110 			SipdroidSocket src_socket, String dest_addr, int dest_port) {
   112 	SipdroidSocket src_socket, String dest_addr, int dest_port) {
   111 		init(do_sync, payload_type, frame_rate, frame_size,
   113 	init(do_sync, payload_type, frame_rate, frame_size,
   112 				src_socket, dest_addr, dest_port);
   114 	    src_socket, dest_addr, dest_port);
   113 	}
   115     }
   114 
   116 
   115 	/** Inits the RtpStreamSender */
   117     /** Inits the RtpStreamSender */
   116 	private void init(boolean do_sync,
   118     private void init(boolean do_sync,
   117 			int payload_type, long frame_rate, int frame_size,
   119 	int payload_type, long frame_rate, int frame_size,
   118 			SipdroidSocket src_socket, String dest_addr,
   120 	SipdroidSocket src_socket, String dest_addr,
   119 			int dest_port) {
   121 	int dest_port) {
   120 		this.p_type = payload_type;
   122 	this.p_type = payload_type;
   121 		this.frame_rate = frame_rate;
   123 	this.frame_rate = frame_rate;
   122 		this.frame_size = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getString("server","").equals("pbxes.org")?
   124 	this.frame_size = frame_size;
   123 				(payload_type == 3?960:1024):frame_size; //15
   125 	this.do_sync = do_sync;
   124 		this.do_sync = do_sync;
   126 	try {
       
   127 	    rtp_socket = new RtpSocket(src_socket, InetAddress
       
   128 		.getByName(dest_addr), dest_port);
       
   129 	} catch (Exception e) {
       
   130 	    e.printStackTrace();
       
   131 	}
       
   132     }
       
   133 
       
   134     /** Sets the synchronization adjustment time (in milliseconds). */
       
   135     public void setSyncAdj(int millisecs) {
       
   136 	sync_adj = millisecs;
       
   137     }
       
   138 
       
   139     /** Whether is running */
       
   140     public boolean isRunning() {
       
   141 	return running;
       
   142     }
       
   143 
       
   144     public boolean mute() {
       
   145 	return muted = !muted;
       
   146     }
       
   147 
       
   148     public static int delay = 0;
       
   149 
       
   150     /** Stops running */
       
   151     public void halt() {
       
   152 	running = false;
       
   153     }
       
   154 
       
   155     Random random;
       
   156     double smin = 200,s;
       
   157     int nearend;
       
   158 
       
   159     void calc(short[] lin,int off,int len) {
       
   160 	int i,j;
       
   161 	double sm = 30000,r;
       
   162 
       
   163 	for (i = 0; i < len; i += 5) {
       
   164 	    j = lin[i+off];
       
   165 	    s = 0.03*Math.abs(j) + 0.97*s;
       
   166 	    if (s < sm) sm = s;
       
   167 	    if (s > smin) nearend = 3000/5;
       
   168 	    else if (nearend > 0) nearend--;
       
   169 	}
       
   170 	for (i = 0; i < len; i++) {
       
   171 	    j = lin[i+off];
       
   172 	    if (j > 6550)
       
   173 		lin[i+off] = 6550*5;
       
   174 	    else if (j < -6550)
       
   175 		lin[i+off] = -6550*5;
       
   176 	    else
       
   177 		lin[i+off] = (short)(j*5);
       
   178 	}
       
   179 	r = (double)len/100000;
       
   180 	smin = sm*r + smin*(1-r);
       
   181     }
       
   182 
       
   183     void calc1(short[] lin,int off,int len) {
       
   184 	int i,j;
       
   185 
       
   186 	for (i = 0; i < len; i++) {
       
   187 	    j = lin[i+off];
       
   188 	    lin[i+off] = (short)(j>>1);
       
   189 	}
       
   190     }
       
   191 
       
   192     void calc5(short[] lin,int off,int len) {
       
   193 	int i,j;
       
   194 
       
   195 	for (i = 0; i < len; i++) {
       
   196 	    j = lin[i+off];
       
   197 	    if (j > 16350)
       
   198 		lin[i+off] = 16350<<1;
       
   199 	    else if (j < -16350)
       
   200 		lin[i+off] = -16350<<1;
       
   201 	    else
       
   202 		lin[i+off] = (short)(j<<1);
       
   203 	}
       
   204     }
       
   205 
       
   206     void calc10(short[] lin,int off,int len) {
       
   207 	int i,j;
       
   208 
       
   209 	for (i = 0; i < len; i++) {
       
   210 	    j = lin[i+off];
       
   211 	    if (j > 8150)
       
   212 		lin[i+off] = 8150<<2;
       
   213 	    else if (j < -8150)
       
   214 		lin[i+off] = -8150<<2;
       
   215 	    else
       
   216 		lin[i+off] = (short)(j<<2);
       
   217 	}
       
   218     }
       
   219 
       
   220     void noise(short[] lin,int off,int len,double power) {
       
   221 	int i,r = (int)(power*2);
       
   222 	short ran;
       
   223 
       
   224 	if (r == 0) r = 1;
       
   225 	for (i = 0; i < len; i += 4) {
       
   226 	    ran = (short)(random.nextInt(r*2)-r);
       
   227 	    lin[i+off] = ran;
       
   228 	    lin[i+off+1] = ran;
       
   229 	    lin[i+off+2] = ran;
       
   230 	    lin[i+off+3] = ran;
       
   231 	}
       
   232     }
       
   233     public static float getMicGain() {
       
   234 	if (Call.headset > 0)
       
   235 	    return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("hmicgain", "1.0"));
       
   236 	return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("micgain", "0.25"));
       
   237     }
       
   238 
       
   239     /** Runs it in a new Thread. */
       
   240     public void run() {
       
   241 	if (rtp_socket == null)
       
   242 	    return;
       
   243 	byte[] buffer = new byte[frame_size + 12];
       
   244 	RtpPacket rtp_packet = new RtpPacket(buffer, 0);
       
   245 	rtp_packet.setPayloadType(p_type);
       
   246 	int seqn = 0;
       
   247 	long time = 0;
       
   248 	double p = 0;
       
   249 	TelephonyManager tm = (TelephonyManager) Call.mContext.getSystemService(Context.TELEPHONY_SERVICE);
       
   250 	boolean improve = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("improve",false);
       
   251 	boolean useGSM = !PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("compression","edge").equals("never");
       
   252 	int micgain = (int)(getMicGain()*10);
       
   253 	running = true;
       
   254 
       
   255 	if (DEBUG)
       
   256 	    println("Reading blocks of " + buffer.length + " bytes");
       
   257 
       
   258 	android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
       
   259 	AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, 
       
   260 	    AudioRecord.getMinBufferSize(8000, 
       
   261 		AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       
   262 		AudioFormat.ENCODING_PCM_16BIT)*3/2);
       
   263 	short[] lin = new short[frame_size*11];
       
   264 	int num,ring = 0;
       
   265 	random = new Random();
       
   266 	InputStream alerting = null;
       
   267 	try {
       
   268 	    alerting = Call.mContext.getAssets().open("alerting");
       
   269 	} catch (IOException e2) {
       
   270 	    e2.printStackTrace();
       
   271 	}
       
   272 	switch (p_type) {
       
   273 	    case 3:
       
   274 		Codec.init();
       
   275 		break;
       
   276 	    case 0:
       
   277 	    case 8:
       
   278 		G711.init();
       
   279 		break;
       
   280 	}
       
   281 	record.startRecording();
       
   282 	while (running) {
       
   283 	    if (muted || Call.call_state == Call.UA_STATE_HOLD) {
       
   284 		record.stop();
       
   285 		while (running && (muted || Call.call_state == Call.UA_STATE_HOLD)) {
       
   286 		    try {
       
   287 			sleep(1000);
       
   288 		    } catch (InterruptedException e1) {
       
   289 			e1.printStackTrace();
       
   290 		    }
       
   291 		}
       
   292 		record.startRecording();
       
   293 	    }
       
   294 	    num = record.read(lin,(ring+delay)%(frame_size*11),frame_size);
       
   295 
       
   296 	    if (RtpStreamReceiver.speakermode == AudioManager.MODE_NORMAL) {
       
   297 		calc(lin,(ring+delay)%(frame_size*11),num);
       
   298 		if (RtpStreamReceiver.nearend != 0)
       
   299 		    noise(lin,(ring+delay)%(frame_size*11),num,p);
       
   300 		else if (RtpStreamReceiver.nearend == 0)
       
   301 		    p = 0.9*p + 0.1*s;
       
   302 	    } else switch (micgain) {
       
   303 		case 1:
       
   304 		    calc1(lin,(ring+delay)%(frame_size*11),num);
       
   305 		    break;
       
   306 		case 5:
       
   307 		    calc5(lin,(ring+delay)%(frame_size*11),num);
       
   308 		    break;
       
   309 		case 10:
       
   310 		    calc10(lin,(ring+delay)%(frame_size*11),num);
       
   311 		    break;
       
   312 	    }
       
   313 	    if (Call.call_state != Call.UA_STATE_INCALL && alerting != null) {
   125 		try {
   314 		try {
   126 			rtp_socket = new RtpSocket(src_socket, InetAddress
   315 		    if (alerting.available() < num)
   127 					.getByName(dest_addr), dest_port);
   316 			alerting.reset();
   128 		} catch (Exception e) {
   317 		    alerting.read(buffer,12,num);
   129 			if (!Sipdroid.release) e.printStackTrace();
   318 		} catch (IOException e) {
   130 		}
   319 		    e.printStackTrace();
   131 	}
   320 		}
   132 
   321 		switch (p_type) {// have to add ulaw case?
   133 	/** Sets the synchronization adjustment time (in milliseconds). */
   322 		    case 3:
   134 	public void setSyncAdj(int millisecs) {
   323 			G711.alaw2linear(buffer, lin, num);
   135 		sync_adj = millisecs;
   324 			num = Codec.encode(lin, 0, buffer, num);
   136 	}
   325 			break;
   137 
   326 		    case 0:
   138 	/** Whether is running */
   327 			G711.alaw2linear(buffer, lin, num);
   139 	public boolean isRunning() {
   328 			G711.linear2ulaw(lin, 0, buffer, num);
   140 		return running;
   329 			break;
   141 	}
   330 		}
   142 	
   331 	    } else {
   143 	public boolean mute() {
       
   144 		return muted = !muted;
       
   145 	}
       
   146 
       
   147 	public static int delay = 0;
       
   148 	
       
   149 	/** Stops running */
       
   150 	public void halt() {
       
   151 		running = false;
       
   152 	}
       
   153 
       
   154 	Random random;
       
   155 	double smin = 200,s;
       
   156 	int nearend;
       
   157 	
       
   158 	void calc(short[] lin,int off,int len) {
       
   159 		int i,j;
       
   160 		double sm = 30000,r;
       
   161 		
       
   162 		for (i = 0; i < len; i += 5) {
       
   163 			j = lin[i+off];
       
   164 			s = 0.03*Math.abs(j) + 0.97*s;
       
   165 			if (s < sm) sm = s;
       
   166 			if (s > smin) nearend = 3000/5;
       
   167 			else if (nearend > 0) nearend--;
       
   168 		}
       
   169 		for (i = 0; i < len; i++) {
       
   170 			j = lin[i+off];
       
   171 			if (j > 6550)
       
   172 				lin[i+off] = 6550*5;
       
   173 			else if (j < -6550)
       
   174 				lin[i+off] = -6550*5;
       
   175 			else
       
   176 				lin[i+off] = (short)(j*5);
       
   177 		}
       
   178 		r = (double)len/100000;
       
   179 		smin = sm*r + smin*(1-r);
       
   180 	}
       
   181 
       
   182 	void calc1(short[] lin,int off,int len) {
       
   183 		int i,j;
       
   184 		
       
   185 		for (i = 0; i < len; i++) {
       
   186 			j = lin[i+off];
       
   187 			lin[i+off] = (short)(j>>1);
       
   188 		}
       
   189 	}
       
   190 
       
   191 	void calc5(short[] lin,int off,int len) {
       
   192 		int i,j;
       
   193 		
       
   194 		for (i = 0; i < len; i++) {
       
   195 			j = lin[i+off];
       
   196 			if (j > 16350)
       
   197 				lin[i+off] = 16350<<1;
       
   198 			else if (j < -16350)
       
   199 				lin[i+off] = -16350<<1;
       
   200 			else
       
   201 				lin[i+off] = (short)(j<<1);
       
   202 		}
       
   203 	}
       
   204 
       
   205 	void calc10(short[] lin,int off,int len) {
       
   206 		int i,j;
       
   207 		
       
   208 		for (i = 0; i < len; i++) {
       
   209 			j = lin[i+off];
       
   210 			if (j > 8150)
       
   211 				lin[i+off] = 8150<<2;
       
   212 			else if (j < -8150)
       
   213 				lin[i+off] = -8150<<2;
       
   214 			else
       
   215 				lin[i+off] = (short)(j<<2);
       
   216 		}
       
   217 	}
       
   218 
       
   219 	void noise(short[] lin,int off,int len,double power) {
       
   220 		int i,r = (int)(power*2);
       
   221 		short ran;
       
   222 
       
   223 		if (r == 0) r = 1;
       
   224 		for (i = 0; i < len; i += 4) {
       
   225 			ran = (short)(random.nextInt(r*2)-r);
       
   226 			lin[i+off] = ran;
       
   227 			lin[i+off+1] = ran;
       
   228 			lin[i+off+2] = ran;
       
   229 			lin[i+off+3] = ran;
       
   230 		}
       
   231 	}
       
   232 	
       
   233 	public static int m;
       
   234 	
       
   235 	/** Runs it in a new Thread. */
       
   236 	public void run() {
       
   237 		if (rtp_socket == null)
       
   238 			return;
       
   239 		byte[] buffer = new byte[frame_size + 12];
       
   240 		RtpPacket rtp_packet = new RtpPacket(buffer, 0);
       
   241 		rtp_packet.setPayloadType(p_type);
       
   242 		int seqn = 0;
       
   243 		long time = 0;
       
   244 		double p = 0;
       
   245 		TelephonyManager tm = (TelephonyManager) Receiver.mContext.getSystemService(Context.TELEPHONY_SERVICE);
       
   246 		boolean improve = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getBoolean("improve",false);
       
   247 		boolean useGSM = !PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getString("compression","edge").equals("never");
       
   248 		int micgain = (int)(Settings.getMicGain()*10);
       
   249 		running = true;
       
   250 		m = 1;
       
   251 
       
   252 		if (DEBUG)
       
   253 			println("Reading blocks of " + buffer.length + " bytes");
       
   254 
       
   255 		android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
       
   256 		AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, 
       
   257 				AudioRecord.getMinBufferSize(8000, 
       
   258 						AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       
   259 						AudioFormat.ENCODING_PCM_16BIT)*3/2);
       
   260 		short[] lin = new short[frame_size*11];
       
   261 		int num,ring = 0;
       
   262 		random = new Random();
       
   263 		InputStream alerting = null;
       
   264 		try {
       
   265 			alerting = Receiver.mContext.getAssets().open("alerting");
       
   266 		} catch (IOException e2) {
       
   267 			if (!Sipdroid.release) e2.printStackTrace();
       
   268 		}
       
   269 		switch (p_type) {
   332 		switch (p_type) {
   270 		case 3:
   333 		    case 3:
   271 			Codec.init();
   334 			num = Codec.encode(lin, ring%(frame_size*11), buffer, num);
   272 			break;
   335 			break;
   273 		case 0:
   336 		    case 0:
   274 		case 8:
   337 			G711.linear2ulaw(lin, ring%(frame_size*11), buffer, num);
   275 			G711.init();
   338 			break;
   276 			break;
   339 		    case 8:
   277 		}
   340 			G711.linear2alaw(lin, ring%(frame_size*11), buffer, num);
   278 		record.startRecording();
   341 			break;
   279 		while (running) {
   342 		}
   280 			 if (muted || Receiver.call_state == UserAgent.UA_STATE_HOLD) {
   343 	    }
   281 				record.stop();
   344 	    ring += frame_size;
   282 				while (running && (muted || Receiver.call_state == UserAgent.UA_STATE_HOLD)) {
   345 	    rtp_packet.setSequenceNumber(seqn++);
   283 					try {
   346 	    rtp_packet.setTimestamp(time);
   284 						sleep(1000);
   347 	    rtp_packet.setPayloadLength(num);
   285 					} catch (InterruptedException e1) {
   348 	    try {
   286 					}
   349 		rtp_socket.send(rtp_packet);
   287 				}
   350 	    } catch (IOException e) {
   288 				record.startRecording();
   351 		e.printStackTrace();
   289 			 }
   352 	    }
   290 			 num = record.read(lin,(ring+delay)%(frame_size*11),frame_size);
   353 	    time += frame_size;
   291 
   354 	    if (useGSM && p_type == 8 && !BeemConnectivity.isWifi(Call.mContext) && tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_EDGE) {
   292 			 if (RtpStreamReceiver.speakermode == AudioManager.MODE_NORMAL) {
   355 		rtp_packet.setPayloadType(p_type = 3);
   293  				 calc(lin,(ring+delay)%(frame_size*11),num);
   356 		if (frame_size == 1024) {
   294  	 			 if (RtpStreamReceiver.nearend != 0)
   357 		    frame_size = 960;
   295 	 				 noise(lin,(ring+delay)%(frame_size*11),num,p);
   358 		    ring = 0;
   296 	 			 else if (nearend == 0)
   359 		}
   297 	 				 p = 0.9*p + 0.1*s;
   360 	    }
   298  			 } else switch (micgain) {
   361 	}
   299  			 case 1:
   362 	record.stop();
   300  				 calc1(lin,(ring+delay)%(frame_size*11),num);
   363 
   301  				 break;
   364 	rtp_socket.close();
   302  			 case 5:
   365 	rtp_socket = null;
   303  				 calc5(lin,(ring+delay)%(frame_size*11),num);
   366 
   304  				 break;
   367 	if (DEBUG)
   305  			 case 10:
   368 	    println("rtp sender terminated");
   306  				 calc10(lin,(ring+delay)%(frame_size*11),num);
   369     }
   307  				 break;
   370 
   308  			 }
   371     /** Debug output */
   309 			 if (Receiver.call_state != UserAgent.UA_STATE_INCALL && alerting != null) {
   372     private static void println(String str) {
   310 				 try {
   373 	System.out.println("RtpStreamSender: " + str);
   311 					if (alerting.available() < num)
   374     }
   312 						alerting.reset();
       
   313 					alerting.read(buffer,12,num);
       
   314 				 } catch (IOException e) {
       
   315 					if (!Sipdroid.release) e.printStackTrace();
       
   316 				 }
       
   317 				 switch (p_type) {// have to add ulaw case?
       
   318 				 case 3:
       
   319 					 G711.alaw2linear(buffer, lin, num);
       
   320 					 num = Codec.encode(lin, 0, buffer, num);
       
   321 					 break;
       
   322 				 case 0:
       
   323 					 G711.alaw2linear(buffer, lin, num);
       
   324 					 G711.linear2ulaw(lin, 0, buffer, num);
       
   325 					 break;
       
   326 				 }
       
   327 			 } else {
       
   328 				 switch (p_type) {
       
   329 				 case 3:
       
   330 					 num = Codec.encode(lin, ring%(frame_size*11), buffer, num);
       
   331 					 break;
       
   332 				 case 0:
       
   333 					 G711.linear2ulaw(lin, ring%(frame_size*11), buffer, num);
       
   334 					 break;
       
   335 				 case 8:
       
   336 					 G711.linear2alaw(lin, ring%(frame_size*11), buffer, num);
       
   337 					 break;
       
   338 				 }
       
   339 			 }
       
   340  			 ring += frame_size;
       
   341  			 rtp_packet.setSequenceNumber(seqn++);
       
   342  			 rtp_packet.setTimestamp(time);
       
   343  			 rtp_packet.setPayloadLength(num);
       
   344  			 try {
       
   345  				 rtp_socket.send(rtp_packet);
       
   346  				 if (m == 2)
       
   347  					 rtp_socket.send(rtp_packet);
       
   348  			 } catch (IOException e) {
       
   349  			 }
       
   350 			 time += frame_size;
       
   351  			 if (improve && RtpStreamReceiver.good != 0 &&
       
   352  					 RtpStreamReceiver.loss/RtpStreamReceiver.good > 0.01 &&
       
   353  					 (Receiver.on_wlan || tm.getNetworkType() != TelephonyManager.NETWORK_TYPE_EDGE))        	
       
   354  				 m = 2;
       
   355  			 else
       
   356  				 m = 1;
       
   357  			 if (useGSM && p_type == 8 && !Receiver.on_wlan && tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_EDGE) {
       
   358  				 rtp_packet.setPayloadType(p_type = 3);
       
   359  				 if (frame_size == 1024) {
       
   360  					 frame_size = 960;
       
   361  					 ring = 0;
       
   362  				 }
       
   363  			 }
       
   364 		}
       
   365 		record.stop();
       
   366 		
       
   367 		rtp_socket.close();
       
   368 		rtp_socket = null;
       
   369 
       
   370 		if (DEBUG)
       
   371 			println("rtp sender terminated");
       
   372 	}
       
   373 
       
   374 	/** Debug output */
       
   375 	private static void println(String str) {
       
   376 		if (!Sipdroid.release) System.out.println("RtpStreamSender: " + str);
       
   377 	}
       
   378 
   375 
   379 }
   376 }