src/org/sipdroid/media/RtpStreamReceiver.java
changeset 835 4e40f3481f23
parent 834 e8d6255306f8
child 1005 a2cad81f348b
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.net.SocketException;
    25 import java.net.SocketException;
    26 
    26 
    27 import org.sipdroid.sipua.UserAgent;
    27 import com.beem.project.beem.jingle.JingleService;
    28 import org.sipdroid.sipua.ui.Receiver;
    28 import com.beem.project.beem.ui.Call;
    29 import org.sipdroid.sipua.ui.Sipdroid;
    29 import org.sipdroid.net.RtpPacket;
       
    30 import org.sipdroid.net.RtpSocket;
       
    31 import org.sipdroid.net.SipdroidSocket;
    30 import org.sipdroid.pjlib.Codec;
    32 import org.sipdroid.pjlib.Codec;
    31 
       
    32 import src.org.sipdroid.net.RtpPacket;
       
    33 import src.org.sipdroid.net.RtpSocket;
       
    34 import src.org.sipdroid.net.SipdroidSocket;
       
    35 
    33 
    36 import android.content.ContentResolver;
    34 import android.content.ContentResolver;
    37 import android.content.Context;
    35 import android.content.Context;
    38 import android.content.SharedPreferences.Editor;
    36 import android.content.SharedPreferences.Editor;
    39 import android.media.AudioFormat;
    37 import android.media.AudioFormat;
    40 import android.media.AudioManager;
    38 import android.media.AudioManager;
    41 import android.media.AudioTrack;
    39 import android.media.AudioTrack;
    42 import android.media.ToneGenerator;
    40 import android.media.ToneGenerator;
    43 import android.os.PowerManager;
    41 import android.os.PowerManager;
       
    42 import android.os.RemoteException;
    44 import android.preference.PreferenceManager;
    43 import android.preference.PreferenceManager;
    45 import android.provider.Settings;
    44 import android.provider.Settings;
    46 
    45 
    47 /**
    46 /**
    48  * RtpStreamReceiver is a generic stream receiver. It receives packets from RTP
    47  * RtpStreamReceiver is a generic stream receiver. It receives packets from RTP
    49  * and writes them into an OutputStream.
    48  * and writes them into an OutputStream.
    50  */
    49  */
    51 public class RtpStreamReceiver extends Thread {
    50 public class RtpStreamReceiver extends Thread {
    52 
    51 
    53 	/** Whether working in debug mode. */
    52     /** Whether working in debug mode. */
    54 	public static boolean DEBUG = true;
    53     public static boolean DEBUG = true;
    55 
    54 
    56 	/** Payload type */
    55     /** Payload type */
    57 	int p_type;
    56     int p_type;
    58 
    57 
    59 	/** Size of the read buffer */
    58     /** Size of the read buffer */
    60 	public static final int BUFFER_SIZE = 1024;
    59     public static final int BUFFER_SIZE = 1024;
    61 
    60 
    62 	/** Maximum blocking time, spent waiting for reading new bytes [milliseconds] */
    61     /** Maximum blocking time, spent waiting for reading new bytes [milliseconds] */
    63 	public static final int SO_TIMEOUT = 200;
    62     public static final int SO_TIMEOUT = 200;
    64 
    63 
    65 	/** The RtpSocket */
    64     /** The RtpSocket */
    66 	RtpSocket rtp_socket = null;
    65     private RtpSocket rtp_socket = null;
    67 
    66 
    68 	/** Whether it is running */
    67     /** Whether it is running */
    69 	boolean running;
    68     private boolean running;
    70 	AudioManager am;
    69     private AudioManager am;
    71 	ContentResolver cr;
    70     private ContentResolver cr;
    72 	public static int speakermode;
    71     public static int speakermode;
    73 	
    72     private JingleService mJingle;
    74 	/**
    73 
    75 	 * Constructs a RtpStreamReceiver.
    74     /**
    76 	 * 
    75      * Constructs a RtpStreamReceiver.
    77 	 * @param output_stream
    76      * 
    78 	 *            the stream sink
    77      * @param output_stream
    79 	 * @param socket
    78      *            the stream sink
    80 	 *            the local receiver SipdroidSocket
    79      * @param socket
    81 	 */
    80      *            the local receiver SipdroidSocket
    82 	public RtpStreamReceiver(SipdroidSocket socket, int payload_type) {
    81      */
    83 		init(socket);
    82     public RtpStreamReceiver(SipdroidSocket socket, int payload_type) {
    84 		p_type = payload_type;
    83 	init(socket);
    85 	}
    84 	p_type = payload_type;
    86 
    85     }
    87 	/** Inits the RtpStreamReceiver */
    86 
    88 	private void init(SipdroidSocket socket) {
    87     /** Inits the RtpStreamReceiver */
    89 		if (socket != null)
    88     private void init(SipdroidSocket socket) {
    90 			rtp_socket = new RtpSocket(socket);
    89 	if (socket != null)
    91 	}
    90 	    rtp_socket = new RtpSocket(socket);
    92 
    91     }
    93 	/** Whether is running */
    92 
    94 	public boolean isRunning() {
    93     /** Whether is running */
    95 		return running;
    94     public boolean isRunning() {
    96 	}
    95 	return running;
    97 
    96     }
    98 	/** Stops running */
    97 
    99 	public void halt() {
    98     /** Stops running */
   100 		running = false;
    99     public void halt() {
   101 	}
   100 	running = false;
   102 	
   101     }
   103 	public int speaker(int mode) {
   102 
   104 		int old = speakermode;
   103     public int speaker(int mode) {
   105 		
   104 	int old = speakermode;
   106 		if (Receiver.headset > 0 && mode == AudioManager.MODE_NORMAL)
   105 
   107 			return old;
   106 	if (Call.headset > 0 && mode == AudioManager.MODE_NORMAL)
   108 		saveVolume();
   107 	    return old;
   109 		setMode(speakermode = mode);
   108 	saveVolume();
   110 		restoreVolume();
   109 	setMode(speakermode = mode);
   111 		return old;
   110 	restoreVolume();
   112 	}
   111 	return old;
   113 
   112     }
   114 	double smin = 200,s;
   113 
   115 	public static int nearend;
   114     double smin = 200,s;
   116 	
   115     public static int nearend;
   117 	void calc(short[] lin,int off,int len) {
   116 
   118 		int i,j;
   117     void calc(short[] lin,int off,int len) {
   119 		double sm = 30000,r;
   118 	int i,j;
   120 		
   119 	double sm = 30000,r;
   121 		for (i = 0; i < len; i += 5) {
   120 
   122 			j = lin[i+off];
   121 	for (i = 0; i < len; i += 5) {
   123 			s = 0.03*Math.abs(j) + 0.97*s;
   122 	    j = lin[i+off];
   124 			if (s < sm) sm = s;
   123 	    s = 0.03*Math.abs(j) + 0.97*s;
   125 			if (s > smin) nearend = 3000/5;
   124 	    if (s < sm) sm = s;
   126 			else if (nearend > 0) nearend--;
   125 	    if (s > smin) nearend = 3000/5;
   127 		}
   126 	    else if (nearend > 0) nearend--;
   128 		for (i = 0; i < len; i++) {
   127 	}
   129 			j = lin[i+off];
   128 	for (i = 0; i < len; i++) {
   130 			if (j > 6550)
   129 	    j = lin[i+off];
   131 				lin[i+off] = 6550*5;
   130 	    if (j > 6550)
   132 			else if (j < -6550)
   131 		lin[i+off] = 6550*5;
   133 				lin[i+off] = -6550*5;
   132 	    else if (j < -6550)
   134 			else
   133 		lin[i+off] = -6550*5;
   135 				lin[i+off] = (short)(j*5);
   134 	    else
   136 		}
   135 		lin[i+off] = (short)(j*5);
   137 		r = (double)len/100000;
   136 	}
   138 		smin = sm*r + smin*(1-r);
   137 	r = (double)len/100000;
   139 	}
   138 	smin = sm*r + smin*(1-r);
   140 	
   139     }
   141 	static void setStreamVolume(final int stream,final int vol,final int flags) {
   140 
   142         (new Thread() {
   141     static void setStreamVolume(final int stream,final int vol,final int flags) {
   143 			public void run() {
   142 	(new Thread() {
   144 				AudioManager am = (AudioManager) Receiver.mContext.getSystemService(Context.AUDIO_SERVICE);
   143 	    public void run() {
   145 				am.setStreamVolume(stream, vol, flags);
   144 		AudioManager am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
   146 				if (stream == AudioManager.STREAM_MUSIC) restored = true;
   145 		am.setStreamVolume(stream, vol, flags);
   147 			}
   146 		if (stream == AudioManager.STREAM_MUSIC) restored = true;
   148         }).start();
   147 	    }
   149 	}
   148 	}).start();
   150 	
   149     }
   151 	static boolean restored;
   150 
   152 	
   151     static boolean restored;
   153 	void restoreVolume() {
   152 
   154 		switch (am.getMode()) {
   153     public static float getEarGain() {
   155 		case AudioManager.MODE_IN_CALL:
   154 	try {
   156 				setStreamVolume(AudioManager.STREAM_RING,(int)(
   155 	    return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString(Call.headset > 0?"heargain":"eargain", "0.25"));
   157 						am.getStreamMaxVolume(AudioManager.STREAM_RING)*
   156 	} catch (NumberFormatException i) {
   158 						org.sipdroid.sipua.ui.Settings.getEarGain()), 0);
   157 	    return (float)0.25;
   159 				track.setStereoVolume(AudioTrack.getMaxVolume()*
   158 	}			
   160 						org.sipdroid.sipua.ui.Settings.getEarGain()
   159     }
   161 						,AudioTrack.getMaxVolume()*
   160 
   162 						org.sipdroid.sipua.ui.Settings.getEarGain());
   161     void restoreVolume() {
   163 				break;
   162 	switch (am.getMode()) {
   164 		case AudioManager.MODE_NORMAL:
   163 	    case AudioManager.MODE_IN_CALL:
   165 				track.setStereoVolume(AudioTrack.getMaxVolume(),AudioTrack.getMaxVolume());
   164 		setStreamVolume(AudioManager.STREAM_RING,(int)(
   166 				break;
   165 		    am.getStreamMaxVolume(AudioManager.STREAM_RING)*
   167 		}
   166 		    getEarGain()), 0);
   168 		setStreamVolume(AudioManager.STREAM_MUSIC,
   167 		track.setStereoVolume(AudioTrack.getMaxVolume()*
   169 				PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getInt("volume"+speakermode, 
   168 		    getEarGain()
   170 				am.getStreamMaxVolume(AudioManager.STREAM_MUSIC)*
   169 		    ,AudioTrack.getMaxVolume()*
   171 				(speakermode == AudioManager.MODE_NORMAL?4:3)/4
   170 		    getEarGain());
   172 				),0);
   171 		break;
   173 	}
   172 	    case AudioManager.MODE_NORMAL:
   174 	
   173 		track.setStereoVolume(AudioTrack.getMaxVolume(),AudioTrack.getMaxVolume());
   175 	void saveVolume() {
   174 		break;
   176 		if (restored) {
   175 	}
   177 			Editor edit = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).edit();
   176 	setStreamVolume(AudioManager.STREAM_MUSIC,
   178 			edit.putInt("volume"+speakermode,am.getStreamVolume(AudioManager.STREAM_MUSIC));
   177 	    PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("volume"+speakermode, 
   179 			edit.commit();
   178 		am.getStreamMaxVolume(AudioManager.STREAM_MUSIC)*
   180 		}
   179 		(speakermode == AudioManager.MODE_NORMAL?4:3)/4
   181 	}
   180 	    ),0);
   182 	
   181     }
   183 	void saveSettings() {
   182 
   184 		if (!PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getBoolean("oldvalid",false)) {
   183     void saveVolume() {
   185 			int oldvibrate = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
   184 	if (restored) {
   186 			int oldvibrate2 = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
   185 	    Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
   187 			if (!PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).contains("oldvibrate2"))
   186 	    edit.putInt("volume"+speakermode,am.getStreamVolume(AudioManager.STREAM_MUSIC));
   188 				oldvibrate2 = AudioManager.VIBRATE_SETTING_ON;
   187 	    edit.commit();
   189 			int oldpolicy = android.provider.Settings.System.getInt(cr, android.provider.Settings.System.WIFI_SLEEP_POLICY, 
   188 	}
   190 					Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
   189     }
   191 			Editor edit = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).edit();
   190 
   192 			edit.putInt("oldvibrate", oldvibrate);
   191     void saveSettings() {
   193 			edit.putInt("oldvibrate2", oldvibrate2);
   192 	if (!PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("oldvalid",false)) {
   194 			edit.putInt("oldpolicy", oldpolicy);
   193 	    int oldvibrate = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
   195 			edit.putInt("oldring",am.getStreamVolume(AudioManager.STREAM_RING));
   194 	    int oldvibrate2 = am.getVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
   196 			edit.putBoolean("oldvalid", true);
   195 	    if (!PreferenceManager.getDefaultSharedPreferences(Call.mContext).contains("oldvibrate2"))
   197 			edit.commit();
   196 		oldvibrate2 = AudioManager.VIBRATE_SETTING_ON;
   198 		}
   197 	    int oldpolicy = android.provider.Settings.System.getInt(cr, android.provider.Settings.System.WIFI_SLEEP_POLICY, 
   199 	}
   198 		Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
   200 	
   199 	    Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
   201 	public static void setMode(int mode) {
   200 	    edit.putInt("oldvibrate", oldvibrate);
   202 		Editor edit = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).edit();
   201 	    edit.putInt("oldvibrate2", oldvibrate2);
   203 		edit.putBoolean("setmode", mode != AudioManager.MODE_NORMAL);
   202 	    edit.putInt("oldpolicy", oldpolicy);
   204 		edit.commit();
   203 	    edit.putInt("oldring",am.getStreamVolume(AudioManager.STREAM_RING));
   205 		AudioManager am = (AudioManager) Receiver.mContext.getSystemService(Context.AUDIO_SERVICE);
   204 	    edit.putBoolean("oldvalid", true);
   206 		am.setMode(mode);
   205 	    edit.commit();
   207 	}
   206 	}
   208 	
   207     }
   209 	public static void restoreMode() {
   208 
   210 		if (PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getBoolean("setmode",true)) {
   209     public static void setMode(int mode) {
   211 			if (Receiver.pstn_state == null || Receiver.pstn_state.equals("IDLE"))
   210 	Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
   212 				setMode(AudioManager.MODE_NORMAL);
   211 	edit.putBoolean("setmode", mode != AudioManager.MODE_NORMAL);
   213 			else {
   212 	edit.commit();
   214 				Editor edit = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).edit();
   213 	AudioManager am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
   215 				edit.putBoolean("setmode", false);
   214 	am.setMode(mode);
   216 				edit.commit();
   215     }
   217 			}
   216 
   218 		}
   217     public static void restoreMode() {
   219 	}
   218 	if (PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("setmode",true)) {
   220 
   219 	    setMode(AudioManager.MODE_NORMAL);
   221 	public static void restoreSettings() {
   220 	}
   222 		if (PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getBoolean("oldvalid",true)) {
   221     }
   223 			AudioManager am = (AudioManager) Receiver.mContext.getSystemService(Context.AUDIO_SERVICE);
   222 
   224 	        ContentResolver cr = Receiver.mContext.getContentResolver();
   223     public static void restoreSettings() {
   225 			int oldvibrate = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getInt("oldvibrate",0);
   224 	if (PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("oldvalid",true)) {
   226 			int oldvibrate2 = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getInt("oldvibrate2",0);
   225 	    AudioManager am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
   227 			int oldpolicy = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getInt("oldpolicy",0);
   226 	    ContentResolver cr = Call.mContext.getContentResolver();
   228 			am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,oldvibrate);
   227 	    int oldvibrate = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldvibrate",0);
   229 			am.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,oldvibrate2);
   228 	    int oldvibrate2 = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldvibrate2",0);
   230 			Settings.System.putInt(cr, Settings.System.WIFI_SLEEP_POLICY, oldpolicy);
   229 	    int oldpolicy = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldpolicy",0);
   231 			setStreamVolume(AudioManager.STREAM_RING, PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getInt("oldring",0), 0);
   230 	    am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,oldvibrate);
   232 			Editor edit = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).edit();
   231 	    am.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,oldvibrate2);
   233 			edit.putBoolean("oldvalid", false);
   232 	    Settings.System.putInt(cr, Settings.System.WIFI_SLEEP_POLICY, oldpolicy);
   234 			edit.commit();
   233 	    setStreamVolume(AudioManager.STREAM_RING, PreferenceManager.getDefaultSharedPreferences(Call.mContext).getInt("oldring",0), 0);
   235 			PowerManager pm = (PowerManager) Receiver.mContext.getSystemService(Context.POWER_SERVICE);
   234 	    Editor edit = PreferenceManager.getDefaultSharedPreferences(Call.mContext).edit();
   236 			PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
   235 	    edit.putBoolean("oldvalid", false);
   237 					PowerManager.ACQUIRE_CAUSES_WAKEUP, "Sipdroid.RtpStreamReceiver");
   236 	    edit.commit();
   238 			wl.acquire(1000);
   237 	    PowerManager pm = (PowerManager) Call.mContext.getSystemService(Context.POWER_SERVICE);
   239 		}
   238 	    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
   240 		restoreMode();
   239 		PowerManager.ACQUIRE_CAUSES_WAKEUP, "Sipdroid.RtpStreamReceiver");
   241 	}
   240 	    wl.acquire(1000);
   242 
   241 	}
   243 	public static float good, late, lost, loss;
   242 	restoreMode();
   244 	public static int timeout;
   243     }
   245 	
   244 
   246 	void empty() {
   245     public static float good, late, lost, loss;
   247 		try {
   246     public static int timeout;
   248 			rtp_socket.getDatagramSocket().setSoTimeout(1);
   247 
   249 			for (;;)
   248     void empty() {
   250 				rtp_socket.receive(rtp_packet);
   249 	try {
   251 		} catch (SocketException e2) {
   250 	    rtp_socket.getDatagramSocket().setSoTimeout(1);
   252 			if (!Sipdroid.release) e2.printStackTrace();
   251 	    for (;;)
   253 		} catch (IOException e) {
   252 		rtp_socket.receive(rtp_packet);
   254 		}
   253 	} catch (SocketException e2) {
   255 		try {
   254 	    e2.printStackTrace();
   256 			rtp_socket.getDatagramSocket().setSoTimeout(1000);
   255 	} catch (IOException e) {
   257 		} catch (SocketException e2) {
   256 	}
   258 			if (!Sipdroid.release) e2.printStackTrace();
   257 	try {
   259 		}
   258 	    rtp_socket.getDatagramSocket().setSoTimeout(1000);
   260 	}
   259 	} catch (SocketException e2) {
   261 	
   260 	    e2.printStackTrace();
   262 	RtpPacket rtp_packet;
   261 	}
   263 	AudioTrack track;
   262     }
   264 	
   263 
   265 	/** Runs it in a new Thread. */
   264     RtpPacket rtp_packet;
   266 	public void run() {
   265     AudioTrack track;
   267 		boolean nodata = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getBoolean("nodata",false);
   266 
   268 		
   267     /** Runs it in a new Thread. */
   269 		if (rtp_socket == null) {
   268     public void run() {
   270 			if (DEBUG)
   269 	boolean nodata = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("nodata",false);
   271 				println("ERROR: RTP socket is null");
   270 
   272 			return;
   271 	if (rtp_socket == null) {
   273 		}
   272 	    if (DEBUG)
   274 
   273 		println("ERROR: RTP socket is null");
   275 		byte[] buffer = new byte[BUFFER_SIZE+12];
   274 	    return;
   276 		byte[] buffer_gsm = new byte[33+12];
   275 	}
   277 		int i;
   276 
   278 		rtp_packet = new RtpPacket(buffer, 0);
   277 	byte[] buffer = new byte[BUFFER_SIZE+12];
   279 
   278 	byte[] buffer_gsm = new byte[33+12];
   280 		if (DEBUG)
   279 	int i;
   281 			println("Reading blocks of max " + buffer.length + " bytes");
   280 	rtp_packet = new RtpPacket(buffer, 0);
   282 
   281 
   283 		running = true;
   282 	if (DEBUG)
   284 		speakermode = Receiver.docked > 0?AudioManager.MODE_NORMAL:AudioManager.MODE_IN_CALL;
   283 	    println("Reading blocks of max " + buffer.length + " bytes");
   285 		restored = false;
   284 
   286 
   285 	running = true;
   287 		android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
   286 	speakermode = Call.docked > 0?AudioManager.MODE_NORMAL:AudioManager.MODE_IN_CALL;
   288 		am = (AudioManager) Receiver.mContext.getSystemService(Context.AUDIO_SERVICE);
   287 	restored = false;
   289         cr = Receiver.mContext.getContentResolver();
   288 
   290 		saveSettings();
   289 	android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
   291 		Settings.System.putInt(cr, Settings.System.WIFI_SLEEP_POLICY,Settings.System.WIFI_SLEEP_POLICY_NEVER);
   290 	am = (AudioManager) Call.mContext.getSystemService(Context.AUDIO_SERVICE);
   292 		am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
   291 	cr = Call.mContext.getContentResolver();
   293 		am.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,AudioManager.VIBRATE_SETTING_OFF);
   292 	saveSettings();
   294 		int oldvol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
   293 	Settings.System.putInt(cr, Settings.System.WIFI_SLEEP_POLICY,Settings.System.WIFI_SLEEP_POLICY_NEVER);
   295 		track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
   294 	am.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
   296 				BUFFER_SIZE*2*2, AudioTrack.MODE_STREAM);
   295 	am.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,AudioManager.VIBRATE_SETTING_OFF);
   297 		short lin[] = new short[BUFFER_SIZE];
   296 	int oldvol = am.getStreamVolume(AudioManager.STREAM_MUSIC);
   298 		short lin2[] = new short[BUFFER_SIZE];
   297 	track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
   299 		int user, server, lserver, luser, cnt, todo, headroom, len = 0, seq = 0, cnt2 = 0, m = 1,
   298 	    BUFFER_SIZE*2*2, AudioTrack.MODE_STREAM);
   300 			expseq, getseq, vm = 1, gap, gseq;
   299 	short lin[] = new short[BUFFER_SIZE];
       
   300 	short lin2[] = new short[BUFFER_SIZE];
       
   301 	int user, server, lserver, luser, cnt, todo, headroom, len = 0, seq = 0, cnt2 = 0, m = 1,
       
   302 	expseq, getseq, vm = 1, gap, gseq;
       
   303 	timeout = 1;
       
   304 	boolean islate;
       
   305 	user = 0;
       
   306 	lserver = 0;
       
   307 	luser = -8000;
       
   308 	cnt = 0;
       
   309 	switch (p_type) {
       
   310 	    case 3:
       
   311 		Codec.init();
       
   312 		break;
       
   313 	    case 0:
       
   314 	    case 8:
       
   315 		G711.init();
       
   316 		break;
       
   317 	}
       
   318 	ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_MUSIC,(int)(ToneGenerator.MAX_VOLUME*2*0.95));
       
   319 	track.play();
       
   320 	if (Call.headset > 0 && Call.oRingtone != null) {
       
   321 	    ToneGenerator tg2 = new ToneGenerator(AudioManager.STREAM_RING,(int)(ToneGenerator.MAX_VOLUME*2*0.95));
       
   322 	    tg2.startTone(ToneGenerator.TONE_SUP_RINGTONE);
       
   323 	    System.gc();
       
   324 	    tg2.stopTone();
       
   325 	} else
       
   326 	    System.gc();
       
   327 	while (running) {
       
   328 	    if (Call.call_state == Call.UA_STATE_HOLD) {
       
   329 		tg.stopTone();
       
   330 		track.pause();
       
   331 		while (running && Call.call_state == Call.UA_STATE_HOLD) {
       
   332 		    try {
       
   333 			sleep(1000);
       
   334 		    } catch (InterruptedException e1) {
       
   335 			e1.printStackTrace();
       
   336 		    }
       
   337 		}
       
   338 		track.play();
       
   339 		System.gc();
   301 		timeout = 1;
   340 		timeout = 1;
   302 		boolean islate;
   341 		seq = 0;
   303 		user = 0;
   342 	    }
   304 		lserver = 0;
   343 	    try {
   305 		luser = -8000;
   344 		rtp_socket.receive(rtp_packet);
   306 		cnt = 0;
   345 		if (timeout != 0) {
   307 		switch (p_type) {
   346 		    tg.stopTone();
   308 		case 3:
   347 		    track.pause();
   309 			Codec.init();
   348 		    user += track.write(lin2,0,BUFFER_SIZE);
   310 			break;
   349 		    user += track.write(lin2,0,BUFFER_SIZE);
   311 		case 0:
   350 		    track.play();
   312 		case 8:
   351 		    cnt += 2*BUFFER_SIZE;
   313 			G711.init();
   352 		    empty();
   314 			break;
   353 		}
   315 		}
   354 		timeout = 0;
   316 		ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_MUSIC,(int)(ToneGenerator.MAX_VOLUME*2*org.sipdroid.sipua.ui.Settings.getEarGain()));
   355 	    } catch (IOException e) {
   317 		track.play();
   356 		if (timeout == 0 && nodata) {
   318 		if (Receiver.headset > 0 && Receiver.oRingtone != null) {
   357 		    tg.startTone(ToneGenerator.TONE_SUP_RINGTONE);
   319 			ToneGenerator tg2 = new ToneGenerator(AudioManager.STREAM_RING,(int)(ToneGenerator.MAX_VOLUME*2*org.sipdroid.sipua.ui.Settings.getEarGain()));
   358 		}
   320 			tg2.startTone(ToneGenerator.TONE_SUP_RINGTONE);
   359 		rtp_socket.getDatagramSocket().disconnect();
   321 			System.gc();
   360 		if (++timeout > 22) {
   322 			tg2.stopTone();
   361 		    try {
       
   362 			mJingle.closeCall();
       
   363 		    } catch (RemoteException e1) {
       
   364 			e1.printStackTrace();
       
   365 		    }
       
   366 		    break;
       
   367 		}
       
   368 	    }
       
   369 	    if (running && timeout == 0) {		
       
   370 		gseq = rtp_packet.getSequenceNumber();
       
   371 		if (seq == gseq) {
       
   372 		    m++;
       
   373 		    continue;
       
   374 		}
       
   375 
       
   376 		server = track.getPlaybackHeadPosition();
       
   377 		headroom = user-server;
       
   378 
       
   379 		if (headroom > 1500)
       
   380 		    cnt += len;
       
   381 		else
       
   382 		    cnt = 0;
       
   383 
       
   384 		if (lserver == server)
       
   385 		    cnt2++;
       
   386 		else
       
   387 		    cnt2 = 0;
       
   388 
       
   389 		if (cnt <= 500 || cnt2 >= 2 || headroom - 875 < len) {
       
   390 		    switch (rtp_packet.getPayloadType()) {
       
   391 			case 0:
       
   392 			    len = rtp_packet.getPayloadLength();
       
   393 			    G711.ulaw2linear(buffer, lin, len);
       
   394 			    break;
       
   395 			case 8:
       
   396 			    len = rtp_packet.getPayloadLength();
       
   397 			    G711.alaw2linear(buffer, lin, len);
       
   398 			    break;
       
   399 			case 3:
       
   400 			    for (i = 12; i < 45; i++)
       
   401 				buffer_gsm[i] = buffer[i];
       
   402 			    len = Codec.decode(buffer_gsm, lin, 0);
       
   403 			    break;
       
   404 		    }
       
   405 
       
   406 		    if (speakermode == AudioManager.MODE_NORMAL)
       
   407 			calc(lin,0,len);
       
   408 		}
       
   409 
       
   410 		if (headroom < 250) { 
       
   411 		    todo = 875 - headroom;
       
   412 		    println("insert "+todo);
       
   413 		    islate = true;
       
   414 		    user += track.write(lin2,0,todo);
   323 		} else
   415 		} else
   324 			System.gc();
   416 		    islate = false;
   325 		while (running) {
   417 
   326 			if (Receiver.call_state == UserAgent.UA_STATE_HOLD) {
   418 		if (cnt > 500 && cnt2 < 2) {
   327 				tg.stopTone();
   419 		    todo = headroom - 875;
   328 				track.pause();
   420 		    println("cut "+todo);
   329 				while (running && Receiver.call_state == UserAgent.UA_STATE_HOLD) {
   421 		    if (todo < len)
   330 					try {
   422 			user += track.write(lin,todo,len-todo);
   331 						sleep(1000);
   423 		} else
   332 					} catch (InterruptedException e1) {
   424 		    user += track.write(lin,0,len);
   333 					}
   425 
   334 				}
   426 		seq = gseq;
   335 				track.play();
   427 
   336 				System.gc();
   428 		if (user >= luser + 8000 && Call.call_state == Call.UA_STATE_INCALL) {
   337 				timeout = 1;
   429 		    if (luser == -8000 || am.getMode() != speakermode) {
   338 				seq = 0;
   430 			saveVolume();
   339 			}
   431 			setMode(speakermode);
   340 			try {
   432 			restoreVolume();
   341 				rtp_socket.receive(rtp_packet);
   433 		    }
   342 				if (timeout != 0) {
   434 		    luser = user;
   343 					tg.stopTone();
   435 		}
   344 					track.pause();
   436 		lserver = server;
   345 					user += track.write(lin2,0,BUFFER_SIZE);
   437 	    }
   346 					user += track.write(lin2,0,BUFFER_SIZE);
   438 	}
   347 					track.play();
   439 	track.stop();
   348 					cnt += 2*BUFFER_SIZE;
   440 	saveVolume();
   349 					empty();
   441 	setStreamVolume(AudioManager.STREAM_MUSIC,oldvol,0);
   350 				}
   442 	restoreSettings();
   351 				timeout = 0;
   443 	setStreamVolume(AudioManager.STREAM_MUSIC,oldvol,0);
   352 			} catch (IOException e) {
   444 	tg.stopTone();
   353 				if (timeout == 0 && nodata) {
   445 	tg = new ToneGenerator(AudioManager.STREAM_RING,ToneGenerator.MAX_VOLUME/4*3);
   354 					tg.startTone(ToneGenerator.TONE_SUP_RINGTONE);
   446 	tg.startTone(ToneGenerator.TONE_PROP_PROMPT);
   355 				}
   447 	try {
   356 				rtp_socket.getDatagramSocket().disconnect();
   448 	    sleep(500);
   357 				if (++timeout > 22) {
   449 	} catch (InterruptedException e) {
   358 					Receiver.engine(Receiver.mContext).rejectcall();
   450 	    e.printStackTrace();
   359 					break;
   451 	}
   360 				}
   452 	tg.stopTone();
   361 			}
   453 
   362 			if (running && timeout == 0) {		
   454 	rtp_socket.close();
   363 				 gseq = rtp_packet.getSequenceNumber();
   455 	rtp_socket = null;
   364 				 if (seq == gseq) {
   456 
   365 					 m++;
   457 	if (DEBUG)
   366 					 continue;
   458 	    println("rtp receiver terminated");
   367 				 }
   459     }
   368 				 
   460 
   369 				 server = track.getPlaybackHeadPosition();
   461     /** Debug output */
   370 				 headroom = user-server;
   462     private static void println(String str) {
   371 				 
   463 	System.out.println("RtpStreamReceiver: " + str);
   372 				 if (headroom > 1500)
   464     }
   373 					 cnt += len;
   465 
   374 				 else
   466     public static int byte2int(byte b) { // return (b>=0)? b : -((b^0xFF)+1);
   375 					 cnt = 0;
   467 	// return (b>=0)? b : b+0x100;
   376 				 
   468 	return (b + 0x100) % 0x100;
   377 				 if (lserver == server)
   469     }
   378 					 cnt2++;
   470 
   379 				 else
   471     public static int byte2int(byte b1, byte b2) {
   380 					 cnt2 = 0;
   472 	return (((b1 + 0x100) % 0x100) << 8) + (b2 + 0x100) % 0x100;
   381 
   473     }
   382 				 if (cnt <= 500 || cnt2 >= 2 || headroom - 875 < len) {
       
   383 					 switch (rtp_packet.getPayloadType()) {
       
   384 					 case 0:
       
   385 						 len = rtp_packet.getPayloadLength();
       
   386 						 G711.ulaw2linear(buffer, lin, len);
       
   387 						 break;
       
   388 					 case 8:
       
   389 						 len = rtp_packet.getPayloadLength();
       
   390 						 G711.alaw2linear(buffer, lin, len);
       
   391 						 break;
       
   392 					 case 3:
       
   393 						 for (i = 12; i < 45; i++)
       
   394 							 buffer_gsm[i] = buffer[i];
       
   395 						 len = Codec.decode(buffer_gsm, lin, 0);
       
   396 						 break;
       
   397 					 }
       
   398 					 
       
   399 		 			 if (speakermode == AudioManager.MODE_NORMAL)
       
   400 		 				 calc(lin,0,len);
       
   401 				 }
       
   402 				 
       
   403 	 			 if (headroom < 250) { 
       
   404 					todo = 875 - headroom;
       
   405 					println("insert "+todo);
       
   406 					islate = true;
       
   407 					user += track.write(lin2,0,todo);
       
   408 				 } else
       
   409 					islate = false;
       
   410 
       
   411 				 if (cnt > 500 && cnt2 < 2) {
       
   412 					 todo = headroom - 875;
       
   413 					 println("cut "+todo);
       
   414 					 if (todo < len)
       
   415 						 user += track.write(lin,todo,len-todo);
       
   416 				 } else
       
   417 					 user += track.write(lin,0,len);
       
   418 				 
       
   419 				 if (seq != 0) {
       
   420 					 getseq = gseq&0xff;
       
   421 					 expseq = ++seq&0xff;
       
   422 					 if (m == RtpStreamSender.m) vm = m;
       
   423 					 gap = (getseq - expseq) & 0xff;
       
   424 					 if (gap > 0) {
       
   425 						 if (gap > 100) gap = 1;
       
   426 						 loss += gap;
       
   427 						 lost += gap;
       
   428 						 good += gap - 1;
       
   429 					 } else {
       
   430 						 if (m < vm)
       
   431 							 loss++;
       
   432 						 if (islate)
       
   433 							 late++;
       
   434 					 }
       
   435 					 good++;
       
   436 					 if (good > 100) {
       
   437 						 good *= 0.99;
       
   438 						 lost *= 0.99;
       
   439 						 loss *= 0.99;
       
   440 						 late *= 0.99;
       
   441 					 }
       
   442 				 }
       
   443 				 m = 1;
       
   444 				 seq = gseq;
       
   445 				 
       
   446 				 if (user >= luser + 8000 && Receiver.call_state == UserAgent.UA_STATE_INCALL) {
       
   447 					 if (luser == -8000 || am.getMode() != speakermode) {
       
   448 						 saveVolume();
       
   449 						 setMode(speakermode);
       
   450 						 restoreVolume();
       
   451 					 }
       
   452 					 luser = user;
       
   453 				 }
       
   454 				 lserver = server;
       
   455 			}
       
   456 		}
       
   457 		track.stop();
       
   458 		saveVolume();
       
   459 		setStreamVolume(AudioManager.STREAM_MUSIC,oldvol,0);
       
   460 		restoreSettings();
       
   461 		setStreamVolume(AudioManager.STREAM_MUSIC,oldvol,0);
       
   462 		tg.stopTone();
       
   463 		tg = new ToneGenerator(AudioManager.STREAM_RING,ToneGenerator.MAX_VOLUME/4*3);
       
   464 		tg.startTone(ToneGenerator.TONE_PROP_PROMPT);
       
   465 		try {
       
   466 			sleep(500);
       
   467 		} catch (InterruptedException e) {
       
   468 		}
       
   469 		tg.stopTone();
       
   470 		
       
   471 		rtp_socket.close();
       
   472 		rtp_socket = null;
       
   473 
       
   474 		if (DEBUG)
       
   475 			println("rtp receiver terminated");
       
   476 	}
       
   477 
       
   478 	/** Debug output */
       
   479 	private static void println(String str) {
       
   480 		if (!Sipdroid.release) System.out.println("RtpStreamReceiver: " + str);
       
   481 	}
       
   482 
       
   483 	public static int byte2int(byte b) { // return (b>=0)? b : -((b^0xFF)+1);
       
   484 		// return (b>=0)? b : b+0x100;
       
   485 		return (b + 0x100) % 0x100;
       
   486 	}
       
   487 
       
   488 	public static int byte2int(byte b1, byte b2) {
       
   489 		return (((b1 + 0x100) % 0x100) << 8) + (b2 + 0x100) % 0x100;
       
   490 	}
       
   491 }
   474 }