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 } |