From 6bf7392952a9899d935eaa2a6c24e727336aa0df Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Tue, 25 Jan 2011 15:45:36 +0100 Subject: [PATCH] add ec calibrator --- res/raw/linphonerc | 4 +- res/values/strings.xml | 9 +++- res/xml/preferences.xml | 5 +- src/org/linphone/DialerActivity.java | 12 +++-- src/org/linphone/KeepAliveManager.java | 46 ++++++++++++++++ .../linphone/LinphonePreferencesActivity.java | 53 +++++++++++++++++-- src/org/linphone/LinphoneService.java | 32 ++++++++++- src/org/linphone/core/LinphoneCoreImpl.java | 13 +++++ submodules/linphone | 2 +- 9 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 src/org/linphone/KeepAliveManager.java diff --git a/res/raw/linphonerc b/res/raw/linphonerc index a9d417c94..70f2c1359 100644 --- a/res/raw/linphonerc +++ b/res/raw/linphonerc @@ -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 diff --git a/res/values/strings.xml b/res/values/strings.xml index 81ad41cf6..2a15530a2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,5 +1,7 @@ + pref_echo_canceller_calibration_key + Echo calibration Use front camera pref_video_use_front_camera_key Video @@ -85,10 +87,12 @@ Yes No Dismiss +Continue Never remind me %s, do you want to go to the settings page ? <P ALIGN=CENTER>No SIP account has been configured yet, do you want to go to the settings page ?<br/><br/> Need help ?<br/> "http://www.linphone.org/m/help"</p> -<P ALIGN=CENTER>Welcome to Linphone SIP phone<br/><br/> If you are new to SIP, have a look at<br/> "http://www.linphone.org/m/help"</p> +<P ALIGN=CENTER>Welcome to Linphone SIP phone<br/><br/> If you are new to SIP, have a look at<br/> "http://www.linphone.org/m/help"</p> +Starting echo cancelation audio calibration Cannot initiate a new call because a call is already engaged History Cannot build destination address from [%s] @@ -102,4 +106,7 @@ Removes the echo heard by other end Stun server pref_stun_server_key +Calibrating... +Calibrated [%s ms] +failed diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index d9623bcfd..e7651acf5 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -45,7 +45,7 @@ - - + + diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java index 59a9a2227..3c072ec0c 100644 --- a/src/org/linphone/DialerActivity.java +++ b/src/org/linphone/DialerActivity.java @@ -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) { + + } } diff --git a/src/org/linphone/KeepAliveManager.java b/src/org/linphone/KeepAliveManager.java new file mode 100644 index 000000000..3baf685c9 --- /dev/null +++ b/src/org/linphone/KeepAliveManager.java @@ -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); + } + } + + } + +} diff --git a/src/org/linphone/LinphonePreferencesActivity.java b/src/org/linphone/LinphonePreferencesActivity.java index e86615c16..69077ba62 100644 --- a/src/org/linphone/LinphonePreferencesActivity.java +++ b/src/org/linphone/LinphonePreferencesActivity.java @@ -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)); diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 3d26ab177..ef3aa3657 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -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); + } + } + }); + } } diff --git a/src/org/linphone/core/LinphoneCoreImpl.java b/src/org/linphone/core/LinphoneCoreImpl.java index 3c21fe0f6..2f33278f9 100644 --- a/src/org/linphone/core/LinphoneCoreImpl.java +++ b/src/org/linphone/core/LinphoneCoreImpl.java @@ -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); + } } diff --git a/submodules/linphone b/submodules/linphone index 407d88929..4166afa48 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 407d88929acc90da18c7a047f0d47d21efe09420 +Subproject commit 4166afa48fd099283684fd147c8fd07fd0b68c16