add ec calibrator

This commit is contained in:
Jehan Monnier 2011-01-25 15:45:36 +01:00
parent f1fbf1c714
commit 6bf7392952
9 changed files with 159 additions and 17 deletions

View file

@ -15,7 +15,7 @@ use_ipv6=0
register_only_when_network_is_up=1
default_proxy=0
auto_net_state_mon=0
keepalive_period=3600000
keepalive_period=30000
[rtp]
audio_rtp_port=7076
@ -30,7 +30,7 @@ ringer_dev_id=ANDROID SND: Android Sound card
capture_dev_id=ANDROID SND: Android Sound card
remote_ring=/data/data/org.linphone/files/ringback.wav
local_ring=/data/data/org.linphone/files/oldphone_mono.wav
ec_tail_len=100
ec_tail_len=120
el_type=mic
el_thres=0.05
el_force=100000

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="pref_echo_canceller_calibration_key">pref_echo_canceller_calibration_key</string>
<string name="pref_echo_canceller_calibration">Echo calibration</string>
<string name="pref_video_use_front_camera_title">Use front camera</string>
<string name="pref_video_use_front_camera_key">pref_video_use_front_camera_key</string>
<string name="pref_video">Video</string>
@ -85,10 +87,12 @@
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="dismiss">Dismiss</string>
<string name="cont">Continue</string>
<string name="never_remind">Never remind me</string>
<string name="config_error">%s, do you want to go to the settings page ?</string>
<string name="initial_config_error">&lt;P ALIGN=CENTER&gt;No SIP account has been configured yet, do you want to go to the settings page ?&lt;br/&gt;&lt;br/&gt; Need help ?&lt;br/&gt; &quot;http://www.linphone.org/m/help&quot;&lt;/p&gt;</string>
<string name="first_launch_message">&lt;P ALIGN=CENTER&gt;Welcome to Linphone SIP phone&lt;br/&gt;&lt;br/&gt; If you are new to SIP, have a look at&lt;br/&gt; &quot;http://www.linphone.org/m/help&quot;&lt;/p&gt;</string>
<string name="first_launch_message">&lt;P ALIGN=CENTER&gt;Welcome to Linphone SIP phone&lt;br/&gt;&lt;br/&gt; If you are new to SIP, have a look at&lt;br/&gt; &quot;http://www.linphone.org/m/help&quot;&lt;/p&gt; </string>
<string name="ec_calibration_launch_message">Starting echo cancelation audio calibration </string>
<string name="warning_already_incall">Cannot initiate a new call because a call is already engaged</string>
<string name="tab_history">History</string>
<string name="warning_wrong_destination_address">Cannot build destination address from [%s]</string>
@ -102,4 +106,7 @@
<string name="pref_echo_cancellation_summary">Removes the echo heard by other end</string>
<string name="pref_stun_server">Stun server</string>
<string name="pref_stun_server_key">pref_stun_server_key</string>
<string name="ec_calibrating">Calibrating...</string>
<string name="ec_calibrated">Calibrated [%s ms]</string>
<string name="failed">failed</string>
</resources>

View file

@ -45,7 +45,7 @@
<CheckBoxPreference android:key="@string/pref_echo_cancellation_key"
android:title="@string/pref_echo_cancellation" android:summary="@string/pref_echo_cancellation_summary"></CheckBoxPreference>
<PreferenceScreen android:title="@string/pref_codecs"
<CheckBoxPreference android:key="@string/pref_echo_canceller_calibration_key" android:title="@string/pref_echo_canceller_calibration" android:defaultValue="false"></CheckBoxPreference><PreferenceScreen android:title="@string/pref_codecs"
android:key="@string/pref_codecs_key">
<CheckBoxPreference android:key="@string/pref_codec_speex16_key"
android:title="@string/pref_codec_speex16" android:defaultValue="true"
@ -63,7 +63,8 @@
<CheckBoxPreference android:key="@string/pref_codec_pcma_key"
android:title="@string/pref_codec_pcma" android:defaultValue="true"></CheckBoxPreference>
</PreferenceScreen>
</PreferenceCategory>
</PreferenceCategory>

View file

@ -25,6 +25,7 @@ import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreListener;
import org.linphone.core.LinphoneFriend;
@ -100,7 +101,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
private ImageButton mAddVideo;
private static final String PREF_CHECK_CONFIG = "pref_check_config";
private static final String PREF_FIRST_LAUNCH = "pref_first_launch";
public static final String PREF_FIRST_LAUNCH = "pref_first_launch";
private static String CURRENT_ADDRESS = "org.linphone.current-address";
private static String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
static int VIDEO_VIEW_ACTIVITY = 100;
@ -359,10 +360,9 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
builder.setCustomTitle(lDialogTextView)
.setCancelable(false)
.setPositiveButton(getString(R.string.dismiss), new DialogInterface.OnClickListener() {
.setPositiveButton(getString(R.string.cont), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LinphoneActivity.instance().startprefActivity();
mPref.edit().putBoolean(PREF_FIRST_LAUNCH, false).commit();
accountCheckingDone = true;
}
});
@ -490,7 +490,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
if (state == LinphoneCall.State.OutgoingInit) {
mWakeLock.acquire();
enterIncalMode(lc);
routeAudioToReceiver();
} else if (state == LinphoneCall.State.IncomingReceived) {
@ -550,6 +549,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
}
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
LinphoneActivity.instance().startProxymitySensor();
if (!mWakeLock.isHeld()) mWakeLock.acquire();
}
private void configureMuteAndSpeakerButtons() {
@ -740,4 +740,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
private AndroidCameraRecordManager getVideoManager() {
return AndroidCameraRecordManager.getInstance();
}
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,
int delay_ms, Object data) {
}
}

View file

@ -0,0 +1,46 @@
/*
ContactPickerActivity.java
Copyright (C) 2010 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class KeepAliveManager extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!LinphoneService.isready()) {
Log.i(LinphoneService.TAG, "Linphone service not ready");
return;
} else {
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
LinphoneService.getLc().enableKeepAlive(true);
} else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) {
LinphoneService.getLc().enableKeepAlive(false);
}
}
}
}

View file

@ -21,26 +21,39 @@ package org.linphone;
import org.linphone.core.LinphoneCoreException;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.util.Log;
public class LinphonePreferencesActivity extends PreferenceActivity {
private static final int version = Integer.parseInt(Build.VERSION.SDK);
boolean mIsLowEndCpu = true;
private AudioManager mAudioManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE));
boolean enableIlbc=false;
if (LinphoneService.isready()) {
// if not ilbc, we are on low end cpu.
enableIlbc = LinphoneService.instance().getLinphoneCore().findPayloadType("iLBC", 8000)!=null?true:false;
if (enableIlbc && !getPreferenceManager().getSharedPreferences().contains(getString(R.string.pref_echo_cancellation_key))) {
mIsLowEndCpu=!enableIlbc;
if (!mIsLowEndCpu && !getPreferenceManager().getSharedPreferences().contains(getString(R.string.pref_echo_cancellation_key))) {
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_echo_cancellation_key), true).commit();
}
if (!enableIlbc) {
if (mIsLowEndCpu) {
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_codec_ilbc_key), false).commit();
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_codec_speex16_key), false).commit();
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_codec_speex32_key), false).commit();
@ -50,18 +63,48 @@ public class LinphonePreferencesActivity extends PreferenceActivity {
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
if (enableIlbc) {
if (!mIsLowEndCpu) {
getPreferenceScreen().findPreference(getString(R.string.pref_codec_ilbc_key)).setEnabled(enableIlbc);
getPreferenceScreen().findPreference(getString(R.string.pref_codec_speex16_key)).setEnabled(enableIlbc);
//getPreferenceScreen().findPreference(getString(R.string.pref_codec_speex32_key)).setEnabled(enableIlbc);
}
getPreferenceScreen().findPreference(getString(R.string.pref_echo_canceller_calibration_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
startEcCalibration(preference);
return false;
}
});
// Force disable video
if (version < 5 || !enableIlbc) {
disableCheckbox(R.string.pref_video_enable_key);
}
}
if (getPreferenceManager().getSharedPreferences().getBoolean(DialerActivity.PREF_FIRST_LAUNCH,true)) {
if (!mIsLowEndCpu ) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.ec_calibration_launch_message).setCancelable(false).setPositiveButton(getString(R.string.cont), new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startEcCalibration(getPreferenceScreen().findPreference(getString(R.string.pref_echo_canceller_calibration_key)));
}
}).create().show();
}
getPreferenceManager().getSharedPreferences().edit().putBoolean(DialerActivity.PREF_FIRST_LAUNCH, false).commit();
}
}
private void startEcCalibration(Preference preference) {
try {
while (mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL) != mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL)) {
mAudioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, 0);
}
LinphoneService.getLc().startEchoCalibration(preference);
preference.setSummary(R.string.ec_calibrating);
preference.getEditor().putBoolean(getString(R.string.pref_echo_canceller_calibration_key), false).commit();
} catch (LinphoneCoreException e) {
Log.w(LinphoneService.TAG, "Cannot calibrate EC",e);
}
}
private void disableCheckbox(int key) {
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(key), false).commit();
CheckBoxPreference box = (CheckBoxPreference) getPreferenceScreen().findPreference(getString(key));

View file

@ -30,6 +30,7 @@ import org.linphone.core.LinphoneAuthInfo;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListener;
@ -44,8 +45,10 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
@ -55,6 +58,8 @@ import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Vibrator;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.util.Log;
@ -86,6 +91,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
LinphoneCall.State mCurrentCallState;
Vibrator mVibrator;
private AudioManager mAudioManager;
private BroadcastReceiver mReceiver = new KeepAliveManager();
private Handler mHandler = new Handler() ;
static boolean isready() {
@ -142,12 +148,17 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
};
mTimer.scheduleAtFixedRate(lTask, 0, 100);
IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
lFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, lFilter);
}
catch (Exception e) {
Log.e(TAG,"Cannot start linphone",e);
}
}
@ -442,6 +453,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
mLinphoneCore.destroy();
theLinphone=null;
mNotificationManager.cancel(NOTIFICATION_ID);
unregisterReceiver(mReceiver);
}
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,
String url) {
@ -493,5 +505,21 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
mVibrator.cancel();
}
}
public void ecCalibrationStatus(final LinphoneCore lc,final EcCalibratorStatus status, final int delay_ms,
final Object data) {
final CheckBoxPreference pref = (CheckBoxPreference) data;
mHandler.post(new Runnable() {
public void run() {
if (status == EcCalibratorStatus.Done) {
pref.setSummary(String.format(getString(R.string.ec_calibrated), delay_ms));
pref.setChecked(true);
} else if (status == EcCalibratorStatus.Failed) {
pref.setSummary(R.string.failed);
pref.setChecked(false);
}
}
});
}
}

View file

@ -88,6 +88,9 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void setRing(long nativePtr, String path);
private native String getRing(long nativePtr);
private native long[] listVideoPayloadTypes(long nativePtr);
private native void enableKeepAlive(long nativePtr,boolean enable);
private native boolean isKeepAliveEnabled(long nativePtr);
private native int startEchoCalibration(long nativePtr,Object data);
private static final String TAG = "LinphoneCore";
@ -428,4 +431,14 @@ class LinphoneCoreImpl implements LinphoneCore {
public boolean isNetworkReachable() {
throw new RuntimeException("Not implemented");
}
public void enableKeepAlive(boolean enable) {
enableKeepAlive(nativePtr,enable);
}
public boolean isKeepAliveEnabled() {
return isKeepAliveEnabled(nativePtr);
}
public void startEchoCalibration(Object data) throws LinphoneCoreException {
startEchoCalibration(nativePtr, data);
}
}

@ -1 +1 @@
Subproject commit 407d88929acc90da18c7a047f0d47d21efe09420
Subproject commit 4166afa48fd099283684fd147c8fd07fd0b68c16