--- a/src/org/sipdroid/media/RtpStreamSender.java Sat Jan 23 22:19:43 2010 +0100
+++ b/src/org/sipdroid/media/RtpStreamSender.java Sun Jan 24 00:42:29 2010 +0100
@@ -19,22 +19,23 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-package src.org.sipdroid.media;
+package org.sipdroid.media;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.Random;
-import org.sipdroid.sipua.UserAgent;
-import org.sipdroid.sipua.ui.Receiver;
-import org.sipdroid.sipua.ui.Settings;
-import org.sipdroid.sipua.ui.Sipdroid;
+
import org.sipdroid.pjlib.Codec;
-import src.org.sipdroid.net.RtpPacket;
-import src.org.sipdroid.net.RtpSocket;
-import src.org.sipdroid.net.SipdroidSocket;
+import org.sipdroid.media.RtpStreamReceiver;
+import org.sipdroid.net.RtpPacket;
+import org.sipdroid.net.RtpSocket;
+import org.sipdroid.net.SipdroidSocket;
+
+import com.beem.project.beem.ui.Call;
+import com.beem.project.beem.utils.BeemConnectivity;
import android.content.Context;
import android.media.AudioFormat;
@@ -42,6 +43,7 @@
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.preference.PreferenceManager;
+import android.provider.Settings;
import android.telephony.TelephonyManager;
/**
@@ -49,331 +51,326 @@
* it through RTP.
*/
public class RtpStreamSender extends Thread {
- /** Whether working in debug mode. */
- public static boolean DEBUG = true;
+ /** Whether working in debug mode. */
+ public static boolean DEBUG = true;
+
+ /** The RtpSocket */
+ RtpSocket rtp_socket = null;
- /** The RtpSocket */
- RtpSocket rtp_socket = null;
+ /** Payload type */
+ int p_type;
+
+ /** Number of frame per second */
+ long frame_rate;
- /** Payload type */
- int p_type;
+ /** Number of bytes per frame */
+ int frame_size;
- /** Number of frame per second */
- long frame_rate;
+ /**
+ * Whether it works synchronously with a local clock, or it it acts as slave
+ * of the InputStream
+ */
+ boolean do_sync = true;
- /** Number of bytes per frame */
- int frame_size;
+ /**
+ * Synchronization correction value, in milliseconds. It accellarates the
+ * sending rate respect to the nominal value, in order to compensate program
+ * latencies.
+ */
+ int sync_adj = 0;
- /**
- * Whether it works synchronously with a local clock, or it it acts as slave
- * of the InputStream
- */
- boolean do_sync = true;
+ /** Whether it is running */
+ boolean running = false;
+ boolean muted = false;
- /**
- * Synchronization correction value, in milliseconds. It accellarates the
- * sending rate respect to the nominal value, in order to compensate program
- * latencies.
- */
- int sync_adj = 0;
-
- /** Whether it is running */
- boolean running = false;
- boolean muted = false;
+ /**
+ * Constructs a RtpStreamSender.
+ *
+ * @param input_stream
+ * the stream to be sent
+ * @param do_sync
+ * whether time synchronization must be performed by the
+ * RtpStreamSender, or it is performed by the InputStream (e.g.
+ * the system audio input)
+ * @param payload_type
+ * the payload type
+ * @param frame_rate
+ * the frame rate, i.e. the number of frames that should be sent
+ * per second; it is used to calculate the nominal packet time
+ * and,in case of do_sync==true, the next departure time
+ * @param frame_size
+ * the size of the payload
+ * @param src_socket
+ * the socket used to send the RTP packet
+ * @param dest_addr
+ * the destination address
+ * @param dest_port
+ * the destination port
+ */
+ public RtpStreamSender(boolean do_sync,
+ int payload_type, long frame_rate, int frame_size,
+ SipdroidSocket src_socket, String dest_addr, int dest_port) {
+ init(do_sync, payload_type, frame_rate, frame_size,
+ src_socket, dest_addr, dest_port);
+ }
- /**
- * Constructs a RtpStreamSender.
- *
- * @param input_stream
- * the stream to be sent
- * @param do_sync
- * whether time synchronization must be performed by the
- * RtpStreamSender, or it is performed by the InputStream (e.g.
- * the system audio input)
- * @param payload_type
- * the payload type
- * @param frame_rate
- * the frame rate, i.e. the number of frames that should be sent
- * per second; it is used to calculate the nominal packet time
- * and,in case of do_sync==true, the next departure time
- * @param frame_size
- * the size of the payload
- * @param src_socket
- * the socket used to send the RTP packet
- * @param dest_addr
- * the destination address
- * @param dest_port
- * the destination port
- */
- public RtpStreamSender(boolean do_sync,
- int payload_type, long frame_rate, int frame_size,
- SipdroidSocket src_socket, String dest_addr, int dest_port) {
- init(do_sync, payload_type, frame_rate, frame_size,
- src_socket, dest_addr, dest_port);
+ /** Inits the RtpStreamSender */
+ private void init(boolean do_sync,
+ int payload_type, long frame_rate, int frame_size,
+ SipdroidSocket src_socket, String dest_addr,
+ int dest_port) {
+ this.p_type = payload_type;
+ this.frame_rate = frame_rate;
+ this.frame_size = frame_size;
+ this.do_sync = do_sync;
+ try {
+ rtp_socket = new RtpSocket(src_socket, InetAddress
+ .getByName(dest_addr), dest_port);
+ } catch (Exception e) {
+ e.printStackTrace();
}
+ }
+
+ /** Sets the synchronization adjustment time (in milliseconds). */
+ public void setSyncAdj(int millisecs) {
+ sync_adj = millisecs;
+ }
+
+ /** Whether is running */
+ public boolean isRunning() {
+ return running;
+ }
+
+ public boolean mute() {
+ return muted = !muted;
+ }
+
+ public static int delay = 0;
- /** Inits the RtpStreamSender */
- private void init(boolean do_sync,
- int payload_type, long frame_rate, int frame_size,
- SipdroidSocket src_socket, String dest_addr,
- int dest_port) {
- this.p_type = payload_type;
- this.frame_rate = frame_rate;
- this.frame_size = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getString("server","").equals("pbxes.org")?
- (payload_type == 3?960:1024):frame_size; //15
- this.do_sync = do_sync;
- try {
- rtp_socket = new RtpSocket(src_socket, InetAddress
- .getByName(dest_addr), dest_port);
- } catch (Exception e) {
- if (!Sipdroid.release) e.printStackTrace();
- }
- }
+ /** Stops running */
+ public void halt() {
+ running = false;
+ }
+
+ Random random;
+ double smin = 200,s;
+ int nearend;
+
+ void calc(short[] lin,int off,int len) {
+ int i,j;
+ double sm = 30000,r;
- /** Sets the synchronization adjustment time (in milliseconds). */
- public void setSyncAdj(int millisecs) {
- sync_adj = millisecs;
- }
-
- /** Whether is running */
- public boolean isRunning() {
- return running;
+ for (i = 0; i < len; i += 5) {
+ j = lin[i+off];
+ s = 0.03*Math.abs(j) + 0.97*s;
+ if (s < sm) sm = s;
+ if (s > smin) nearend = 3000/5;
+ else if (nearend > 0) nearend--;
}
-
- public boolean mute() {
- return muted = !muted;
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ if (j > 6550)
+ lin[i+off] = 6550*5;
+ else if (j < -6550)
+ lin[i+off] = -6550*5;
+ else
+ lin[i+off] = (short)(j*5);
}
+ r = (double)len/100000;
+ smin = sm*r + smin*(1-r);
+ }
- public static int delay = 0;
-
- /** Stops running */
- public void halt() {
- running = false;
+ void calc1(short[] lin,int off,int len) {
+ int i,j;
+
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ lin[i+off] = (short)(j>>1);
}
+ }
- Random random;
- double smin = 200,s;
- int nearend;
-
- void calc(short[] lin,int off,int len) {
- int i,j;
- double sm = 30000,r;
-
- for (i = 0; i < len; i += 5) {
- j = lin[i+off];
- s = 0.03*Math.abs(j) + 0.97*s;
- if (s < sm) sm = s;
- if (s > smin) nearend = 3000/5;
- else if (nearend > 0) nearend--;
- }
- for (i = 0; i < len; i++) {
- j = lin[i+off];
- if (j > 6550)
- lin[i+off] = 6550*5;
- else if (j < -6550)
- lin[i+off] = -6550*5;
- else
- lin[i+off] = (short)(j*5);
- }
- r = (double)len/100000;
- smin = sm*r + smin*(1-r);
+ void calc5(short[] lin,int off,int len) {
+ int i,j;
+
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ if (j > 16350)
+ lin[i+off] = 16350<<1;
+ else if (j < -16350)
+ lin[i+off] = -16350<<1;
+ else
+ lin[i+off] = (short)(j<<1);
+ }
+ }
+
+ void calc10(short[] lin,int off,int len) {
+ int i,j;
+
+ for (i = 0; i < len; i++) {
+ j = lin[i+off];
+ if (j > 8150)
+ lin[i+off] = 8150<<2;
+ else if (j < -8150)
+ lin[i+off] = -8150<<2;
+ else
+ lin[i+off] = (short)(j<<2);
}
+ }
- void calc1(short[] lin,int off,int len) {
- int i,j;
-
- for (i = 0; i < len; i++) {
- j = lin[i+off];
- lin[i+off] = (short)(j>>1);
- }
- }
+ void noise(short[] lin,int off,int len,double power) {
+ int i,r = (int)(power*2);
+ short ran;
- void calc5(short[] lin,int off,int len) {
- int i,j;
-
- for (i = 0; i < len; i++) {
- j = lin[i+off];
- if (j > 16350)
- lin[i+off] = 16350<<1;
- else if (j < -16350)
- lin[i+off] = -16350<<1;
- else
- lin[i+off] = (short)(j<<1);
- }
+ if (r == 0) r = 1;
+ for (i = 0; i < len; i += 4) {
+ ran = (short)(random.nextInt(r*2)-r);
+ lin[i+off] = ran;
+ lin[i+off+1] = ran;
+ lin[i+off+2] = ran;
+ lin[i+off+3] = ran;
}
+ }
+ public static float getMicGain() {
+ if (Call.headset > 0)
+ return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("hmicgain", "1.0"));
+ return Float.valueOf(PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("micgain", "0.25"));
+ }
+
+ /** Runs it in a new Thread. */
+ public void run() {
+ if (rtp_socket == null)
+ return;
+ byte[] buffer = new byte[frame_size + 12];
+ RtpPacket rtp_packet = new RtpPacket(buffer, 0);
+ rtp_packet.setPayloadType(p_type);
+ int seqn = 0;
+ long time = 0;
+ double p = 0;
+ TelephonyManager tm = (TelephonyManager) Call.mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ boolean improve = PreferenceManager.getDefaultSharedPreferences(Call.mContext).getBoolean("improve",false);
+ boolean useGSM = !PreferenceManager.getDefaultSharedPreferences(Call.mContext).getString("compression","edge").equals("never");
+ int micgain = (int)(getMicGain()*10);
+ running = true;
+
+ if (DEBUG)
+ println("Reading blocks of " + buffer.length + " bytes");
- void calc10(short[] lin,int off,int len) {
- int i,j;
-
- for (i = 0; i < len; i++) {
- j = lin[i+off];
- if (j > 8150)
- lin[i+off] = 8150<<2;
- else if (j < -8150)
- lin[i+off] = -8150<<2;
- else
- lin[i+off] = (short)(j<<2);
- }
+ android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
+ AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
+ AudioRecord.getMinBufferSize(8000,
+ AudioFormat.CHANNEL_CONFIGURATION_MONO,
+ AudioFormat.ENCODING_PCM_16BIT)*3/2);
+ short[] lin = new short[frame_size*11];
+ int num,ring = 0;
+ random = new Random();
+ InputStream alerting = null;
+ try {
+ alerting = Call.mContext.getAssets().open("alerting");
+ } catch (IOException e2) {
+ e2.printStackTrace();
}
-
- void noise(short[] lin,int off,int len,double power) {
- int i,r = (int)(power*2);
- short ran;
-
- if (r == 0) r = 1;
- for (i = 0; i < len; i += 4) {
- ran = (short)(random.nextInt(r*2)-r);
- lin[i+off] = ran;
- lin[i+off+1] = ran;
- lin[i+off+2] = ran;
- lin[i+off+3] = ran;
- }
+ switch (p_type) {
+ case 3:
+ Codec.init();
+ break;
+ case 0:
+ case 8:
+ G711.init();
+ break;
}
-
- public static int m;
-
- /** Runs it in a new Thread. */
- public void run() {
- if (rtp_socket == null)
- return;
- byte[] buffer = new byte[frame_size + 12];
- RtpPacket rtp_packet = new RtpPacket(buffer, 0);
- rtp_packet.setPayloadType(p_type);
- int seqn = 0;
- long time = 0;
- double p = 0;
- TelephonyManager tm = (TelephonyManager) Receiver.mContext.getSystemService(Context.TELEPHONY_SERVICE);
- boolean improve = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getBoolean("improve",false);
- boolean useGSM = !PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).getString("compression","edge").equals("never");
- int micgain = (int)(Settings.getMicGain()*10);
- running = true;
- m = 1;
+ record.startRecording();
+ while (running) {
+ if (muted || Call.call_state == Call.UA_STATE_HOLD) {
+ record.stop();
+ while (running && (muted || Call.call_state == Call.UA_STATE_HOLD)) {
+ try {
+ sleep(1000);
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ }
+ record.startRecording();
+ }
+ num = record.read(lin,(ring+delay)%(frame_size*11),frame_size);
- if (DEBUG)
- println("Reading blocks of " + buffer.length + " bytes");
-
- android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
- AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
- AudioRecord.getMinBufferSize(8000,
- AudioFormat.CHANNEL_CONFIGURATION_MONO,
- AudioFormat.ENCODING_PCM_16BIT)*3/2);
- short[] lin = new short[frame_size*11];
- int num,ring = 0;
- random = new Random();
- InputStream alerting = null;
+ if (RtpStreamReceiver.speakermode == AudioManager.MODE_NORMAL) {
+ calc(lin,(ring+delay)%(frame_size*11),num);
+ if (RtpStreamReceiver.nearend != 0)
+ noise(lin,(ring+delay)%(frame_size*11),num,p);
+ else if (RtpStreamReceiver.nearend == 0)
+ p = 0.9*p + 0.1*s;
+ } else switch (micgain) {
+ case 1:
+ calc1(lin,(ring+delay)%(frame_size*11),num);
+ break;
+ case 5:
+ calc5(lin,(ring+delay)%(frame_size*11),num);
+ break;
+ case 10:
+ calc10(lin,(ring+delay)%(frame_size*11),num);
+ break;
+ }
+ if (Call.call_state != Call.UA_STATE_INCALL && alerting != null) {
try {
- alerting = Receiver.mContext.getAssets().open("alerting");
- } catch (IOException e2) {
- if (!Sipdroid.release) e2.printStackTrace();
+ if (alerting.available() < num)
+ alerting.reset();
+ alerting.read(buffer,12,num);
+ } catch (IOException e) {
+ e.printStackTrace();
}
- switch (p_type) {
- case 3:
- Codec.init();
+ switch (p_type) {// have to add ulaw case?
+ case 3:
+ G711.alaw2linear(buffer, lin, num);
+ num = Codec.encode(lin, 0, buffer, num);
break;
- case 0:
- case 8:
- G711.init();
+ case 0:
+ G711.alaw2linear(buffer, lin, num);
+ G711.linear2ulaw(lin, 0, buffer, num);
break;
}
- record.startRecording();
- while (running) {
- if (muted || Receiver.call_state == UserAgent.UA_STATE_HOLD) {
- record.stop();
- while (running && (muted || Receiver.call_state == UserAgent.UA_STATE_HOLD)) {
- try {
- sleep(1000);
- } catch (InterruptedException e1) {
- }
- }
- record.startRecording();
- }
- num = record.read(lin,(ring+delay)%(frame_size*11),frame_size);
+ } else {
+ switch (p_type) {
+ case 3:
+ num = Codec.encode(lin, ring%(frame_size*11), buffer, num);
+ break;
+ case 0:
+ G711.linear2ulaw(lin, ring%(frame_size*11), buffer, num);
+ break;
+ case 8:
+ G711.linear2alaw(lin, ring%(frame_size*11), buffer, num);
+ break;
+ }
+ }
+ ring += frame_size;
+ rtp_packet.setSequenceNumber(seqn++);
+ rtp_packet.setTimestamp(time);
+ rtp_packet.setPayloadLength(num);
+ try {
+ rtp_socket.send(rtp_packet);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ time += frame_size;
+ if (useGSM && p_type == 8 && !BeemConnectivity.isWifi(Call.mContext) && tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_EDGE) {
+ rtp_packet.setPayloadType(p_type = 3);
+ if (frame_size == 1024) {
+ frame_size = 960;
+ ring = 0;
+ }
+ }
+ }
+ record.stop();
- if (RtpStreamReceiver.speakermode == AudioManager.MODE_NORMAL) {
- calc(lin,(ring+delay)%(frame_size*11),num);
- if (RtpStreamReceiver.nearend != 0)
- noise(lin,(ring+delay)%(frame_size*11),num,p);
- else if (nearend == 0)
- p = 0.9*p + 0.1*s;
- } else switch (micgain) {
- case 1:
- calc1(lin,(ring+delay)%(frame_size*11),num);
- break;
- case 5:
- calc5(lin,(ring+delay)%(frame_size*11),num);
- break;
- case 10:
- calc10(lin,(ring+delay)%(frame_size*11),num);
- break;
- }
- if (Receiver.call_state != UserAgent.UA_STATE_INCALL && alerting != null) {
- try {
- if (alerting.available() < num)
- alerting.reset();
- alerting.read(buffer,12,num);
- } catch (IOException e) {
- if (!Sipdroid.release) e.printStackTrace();
- }
- switch (p_type) {// have to add ulaw case?
- case 3:
- G711.alaw2linear(buffer, lin, num);
- num = Codec.encode(lin, 0, buffer, num);
- break;
- case 0:
- G711.alaw2linear(buffer, lin, num);
- G711.linear2ulaw(lin, 0, buffer, num);
- break;
- }
- } else {
- switch (p_type) {
- case 3:
- num = Codec.encode(lin, ring%(frame_size*11), buffer, num);
- break;
- case 0:
- G711.linear2ulaw(lin, ring%(frame_size*11), buffer, num);
- break;
- case 8:
- G711.linear2alaw(lin, ring%(frame_size*11), buffer, num);
- break;
- }
- }
- ring += frame_size;
- rtp_packet.setSequenceNumber(seqn++);
- rtp_packet.setTimestamp(time);
- rtp_packet.setPayloadLength(num);
- try {
- rtp_socket.send(rtp_packet);
- if (m == 2)
- rtp_socket.send(rtp_packet);
- } catch (IOException e) {
- }
- time += frame_size;
- if (improve && RtpStreamReceiver.good != 0 &&
- RtpStreamReceiver.loss/RtpStreamReceiver.good > 0.01 &&
- (Receiver.on_wlan || tm.getNetworkType() != TelephonyManager.NETWORK_TYPE_EDGE))
- m = 2;
- else
- m = 1;
- if (useGSM && p_type == 8 && !Receiver.on_wlan && tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_EDGE) {
- rtp_packet.setPayloadType(p_type = 3);
- if (frame_size == 1024) {
- frame_size = 960;
- ring = 0;
- }
- }
- }
- record.stop();
-
- rtp_socket.close();
- rtp_socket = null;
+ rtp_socket.close();
+ rtp_socket = null;
- if (DEBUG)
- println("rtp sender terminated");
- }
+ if (DEBUG)
+ println("rtp sender terminated");
+ }
- /** Debug output */
- private static void println(String str) {
- if (!Sipdroid.release) System.out.println("RtpStreamSender: " + str);
- }
+ /** Debug output */
+ private static void println(String str) {
+ System.out.println("RtpStreamSender: " + str);
+ }
}
\ No newline at end of file