]> sjero.net Git - linphone/commitdiff
improve echo calibration
authorSimon Morlat <simon.morlat@linphone.org>
Tue, 19 Feb 2013 16:43:16 +0000 (17:43 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Tue, 19 Feb 2013 16:45:48 +0000 (17:45 +0100)
add mising declineCall() method to java api.

coreapi/ec-calibrator.c
coreapi/linphonecore.c
coreapi/linphonecore_jni.cc
coreapi/private.h
java/common/org/linphone/core/LinphoneCore.java
java/common/org/linphone/core/Reason.java [new file with mode: 0644]
java/impl/org/linphone/core/LinphoneCoreImpl.java
mediastreamer2

index 7fb001d3de75554467c4ddc83de2c04bcbe46e87..8efbabb1b0a0758c0fde6bcef4592860361eb296 100644 (file)
@@ -97,17 +97,37 @@ static void ecc_deinit_filters(EcCalibrator *ecc){
 static void on_tone_sent(void *data, MSFilter *f, unsigned int event_id, void *arg){
        MSDtmfGenEvent *ev=(MSDtmfGenEvent*)arg;
        EcCalibrator *ecc=(EcCalibrator*)data;
-       ecc->sent_count++;
        ecc->acc-=ev->tone_start_time;
        ms_message("Sent tone at %u",(unsigned int)ev->tone_start_time);
 }
 
+static bool_t is_valid_tone(EcCalibrator *ecc, MSToneDetectorEvent *ev){
+       bool_t *toneflag=NULL;
+       if (strcmp(ev->tone_name,"freq1")==0){
+               toneflag=&ecc->freq1;
+       }else if (strcmp(ev->tone_name,"freq2")==0){
+               toneflag=&ecc->freq2;
+       }else if (strcmp(ev->tone_name,"freq3")==0){
+               toneflag=&ecc->freq3;
+       }else{
+               ms_error("Calibrator bug.");
+               return FALSE;
+       }
+       if (*toneflag){
+               ms_message("Duplicated tone event, ignored.");
+               return FALSE;
+       }
+       *toneflag=TRUE;
+       return TRUE;
+}
+
 static void on_tone_received(void *data, MSFilter *f, unsigned int event_id, void *arg){
        MSToneDetectorEvent *ev=(MSToneDetectorEvent*)arg;
        EcCalibrator *ecc=(EcCalibrator*)data;
-       ecc->recv_count++;
-       ecc->acc+=ev->tone_start_time;
-       ms_message("Received tone at %u",(unsigned int)ev->tone_start_time);
+       if (is_valid_tone(ecc,ev)){
+               ecc->acc+=ev->tone_start_time;
+               ms_message("Received tone at %u",(unsigned int)ev->tone_start_time);
+       }
 }
 
 static void ecc_play_tones(EcCalibrator *ecc){
@@ -116,53 +136,76 @@ static void ecc_play_tones(EcCalibrator *ecc){
 
        ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc);
 
+       /* configure the tones to be scanned */
+       
+       strncpy(expected_tone.tone_name,"freq1",sizeof(expected_tone.tone_name));
        expected_tone.frequency=2000;
        expected_tone.min_duration=40;
-       expected_tone.min_amplitude=0.02;
+       expected_tone.min_amplitude=0.1;
 
        ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone);
        
-       tone.frequency=1300;
-       tone.duration=1000;
-       tone.amplitude=1.0;
+       strncpy(expected_tone.tone_name,"freq2",sizeof(expected_tone.tone_name));
+       expected_tone.frequency=2300;
+       expected_tone.min_duration=40;
+       expected_tone.min_amplitude=0.1;
 
+       ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone);
+       
+       strncpy(expected_tone.tone_name,"freq3",sizeof(expected_tone.tone_name));
+       expected_tone.frequency=2500;
+       expected_tone.min_duration=40;
+       expected_tone.min_amplitude=0.1;
+
+       ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone);
+       
        /*play an initial tone to startup the audio playback/capture*/
+       
+       tone.frequency=140;
+       tone.duration=1000;
+       tone.amplitude=0.5;
+
        ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
        ms_sleep(2);
 
        ms_filter_set_notify_callback(ecc->gen,on_tone_sent,ecc);
+       
+       /* play the three tones*/
+       
        tone.frequency=2000;
        tone.duration=100;
-
        ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
-       ms_sleep(1);
+       ms_usleep(300000);
+       
+       tone.frequency=2300;
+       tone.duration=100;
        ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
-       ms_sleep(1);
+       ms_usleep(300000);
+       
+       tone.frequency=2500;
+       tone.duration=100;
        ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
        ms_sleep(1);
-
-       if (ecc->sent_count==3) {
-               if (ecc->recv_count==3){
-                       int delay=ecc->acc/3;
-                       if (delay<0){
-                               ms_error("Quite surprising calibration result, delay=%i",delay);
-                               ecc->status=LinphoneEcCalibratorFailed;
-                       }else{
-                               ms_message("Echo calibration estimated delay to be %i ms",delay);
-                               ecc->delay=delay;
-                               ecc->status=LinphoneEcCalibratorDone;
-                       }
-               } else if (ecc->recv_count == 0) {
+       
+       if (ecc->freq1 && ecc->freq2 && ecc->freq3) {
+               int delay=ecc->acc/3;
+               if (delay<0){
+                       ms_error("Quite surprising calibration result, delay=%i",delay);
+                       ecc->status=LinphoneEcCalibratorFailed;
+               }else{
+                       ms_message("Echo calibration estimated delay to be %i ms",delay);
+                       ecc->delay=delay;
+                       ecc->status=LinphoneEcCalibratorDone;
+               }
+       } else if ((ecc->freq1 || ecc->freq2 || ecc->freq3)==FALSE) {
                        ms_message("Echo calibration succeeded, no echo has been detected");
                        ecc->status = LinphoneEcCalibratorDoneNoEcho;
-               } else {
+       } else {
                        ecc->status = LinphoneEcCalibratorFailed;
-               }
-       }else{
-               ecc->status=LinphoneEcCalibratorFailed;
        }
+
        if (ecc->status == LinphoneEcCalibratorFailed) {
-               ms_error("Echo calibration failed, tones received = %i",ecc->recv_count);
+               ms_error("Echo calibration failed.");
        }
 }
 
index 5ba0fbf700d78965838b0e1070a0b642fad3ec44..d9d199c3f95102cf8e43d4693e4dd71fb95a24dd 100644 (file)
@@ -2054,9 +2054,11 @@ void linphone_core_iterate(LinphoneCore *lc){
                                lc->ecc->cb(lc,ecs,lc->ecc->delay,lc->ecc->cb_data);
                        if (ecs==LinphoneEcCalibratorDone){
                                int len=lp_config_get_int(lc->config,"sound","ec_tail_len",0);
-                               lp_config_set_int(lc->config, "sound", "ec_delay",MAX(lc->ecc->delay-(len/2),0));
+                               int margin=len/2;
+                               
+                               lp_config_set_int(lc->config, "sound", "ec_delay",MAX(lc->ecc->delay-margin,0));
                        } else if (ecs == LinphoneEcCalibratorFailed) {
-                               lp_config_set_int(lc->config, "sound", "ec_delay", LP_CONFIG_DEFAULT_INT(lc->config, "ec_delay", 250));
+                               lp_config_set_int(lc->config, "sound", "ec_delay", -1);/*use default value from soundcard*/
                        } else if (ecs == LinphoneEcCalibratorDoneNoEcho) {
                                linphone_core_enable_echo_cancellation(lc, FALSE);
                        }
index 64897b2189a89b53e03c06fa28b5d6e7173339a8..9c8697f6aad5f3082ff550eb24fe97e4be89d758 100644 (file)
@@ -650,6 +650,13 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_terminateCall(     JNIEnv*
        linphone_core_terminate_call((LinphoneCore*)lc,(LinphoneCall*)call);
 }
 
+extern "C" void Java_org_linphone_core_LinphoneCoreImpl_declineCall(   JNIEnv*  env
+               ,jobject  thiz
+               ,jlong lc
+               ,jlong call, jint reason) {
+       linphone_core_decline_call((LinphoneCore*)lc,(LinphoneCall*)call,(LinphoneReason)reason);
+}
+
 extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getRemoteAddress(     JNIEnv*  env
                ,jobject  thiz
                ,jlong lc) {
@@ -993,6 +1000,18 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_startEchoCalibration(JNI
 
 }
 
+extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_needsEchoCalibration(JNIEnv *env, jobject thiz, jlong lc){
+       MSSndCard *sndcard;
+       MSSndCardManager *m=ms_snd_card_manager_get();
+       const char *card=linphone_core_get_capture_device((LinphoneCore*)lc);
+       sndcard=ms_snd_card_manager_get_card(m,card);
+       if (sndcard == NULL){
+               ms_error("Could not get soundcard.");
+               return TRUE;
+       }
+       return (ms_snd_card_get_capabilities(sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) || (ms_snd_card_get_minimal_latency(sndcard)>0);
+}
+
 extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getMediaEncryption(JNIEnv*  env
                                                                                                                                                        ,jobject  thiz
                                                                                                                                                        ,jlong lc
index 90054052c7b72e48ba790dd682a65b29740e4267..c0b467cee3f719ed06515c2270253613b9722a70 100644 (file)
@@ -643,12 +643,11 @@ struct _EcCalibrator{
        MSTicker *ticker;
        LinphoneEcCalibrationCallback cb;
        void *cb_data;
-       int recv_count;
-       int sent_count;
        int64_t acc;
        int delay;
        unsigned int rate;
        LinphoneEcCalibratorStatus status;
+       bool_t freq1,freq2,freq3;
 };
 
 typedef struct _EcCalibrator EcCalibrator;
index 11a7c275f9f569c8c1f7b7068f69c436dd9fb144..3a6cf2a760e1d6c304161b638dc0d3ed8a8cd88c 100644 (file)
@@ -396,6 +396,10 @@ public interface LinphoneCore {
         * @param aCall to be terminated
         */
        public void terminateCall(LinphoneCall aCall);
+       /**
+        * Declines an incoming call, providing a reason for declining it.
+        */
+       public void declineCall(LinphoneCall aCall, Reason reason);
        /**
         * Returns The LinphoneCall the current call if one is in call
         *
@@ -744,6 +748,12 @@ public interface LinphoneCore {
        **/
        void startEchoCalibration(Object data) throws LinphoneCoreException;
 
+       /**
+        * Returns true if echo calibration is recommended.
+        * If the device has a builtin echo canceller or calibration value is already known, it will return false.
+        */
+       boolean needsEchoCalibration();
+       
        void enableIpv6(boolean enable);
        /**
         * @deprecated
diff --git a/java/common/org/linphone/core/Reason.java b/java/common/org/linphone/core/Reason.java
new file mode 100644 (file)
index 0000000..b07686a
--- /dev/null
@@ -0,0 +1,56 @@
+package org.linphone.core;
+
+import java.util.Vector;
+
+public class Reason {
+       static private Vector<Reason> values = new Vector<Reason>();
+       /**
+        * None (no failure)
+        */
+       static public Reason None = new Reason(0,"None");
+       /**
+        * No response 
+        */
+       static public Reason NoResponse = new Reason(1,"NoResponse");
+       /**
+        * Bad credentials
+        */
+       static public Reason BadCredentials = new Reason(2,"BadCredentials");
+       /**
+        * Call declined
+        */
+       static public Reason Declined = new Reason(3,"Declined");
+       /**
+        * Not found
+        */
+       static public Reason NotFound = new Reason(4,"NotFound");
+       /**
+        * Call not answered (in time).
+        */
+       static public Reason NotAnswered = new Reason(5,"NotAnswered");
+       /**
+        * Call not answered (in time).
+        */
+       static public Reason Busy = new Reason(6,"Busy");
+       
+       protected final int mValue;
+       private final String mStringValue;
+
+       
+       private Reason(int value,String stringValue) {
+               mValue = value;
+               values.addElement(this);
+               mStringValue=stringValue;
+       }
+       public static Reason fromInt(int value) {
+               for (int i=0; i<values.size();i++) {
+                       Reason state = (Reason) values.elementAt(i);
+                       if (state.mValue == value) return state;
+               }
+               throw new RuntimeException("Reason not found ["+value+"]");
+       }
+
+       public String toString() {
+               return mStringValue;
+       }
+}
index 2d42c8f550ed5727b5ea079b6ae6c25346f49c68..7b596f7e2f4788ecb4d57fd9ff73f4b510e0b020 100644 (file)
@@ -757,30 +757,30 @@ class LinphoneCoreImpl implements LinphoneCore {
                setVideoPolicy(nativePtr, autoInitiate, autoAccept);
        }
        private native void setStaticPicture(long nativePtr, String path);
-       public void setStaticPicture(String path) {
+       public synchronized void setStaticPicture(String path) {
                setStaticPicture(nativePtr, path);
        }
        private native void setUserAgent(long nativePtr, String name, String version);
        @Override
-       public void setUserAgent(String name, String version) {
+       public synchronized void setUserAgent(String name, String version) {
                setUserAgent(nativePtr,name,version);
        }
 
        private native void setCpuCountNative(int count);
-       public void setCpuCount(int count)
+       public synchronized void setCpuCount(int count)
        {
                setCpuCountNative(count);
        }
        
-       public int getMissedCallsCount() {
+       public synchronized int getMissedCallsCount() {
                return getMissedCallsCount(nativePtr);
        }
        
-       public void removeCallLog(LinphoneCallLog log) {
+       public synchronized void removeCallLog(LinphoneCallLog log) {
                removeCallLog(nativePtr, ((LinphoneCallLogImpl) log).getNativePtr());
        }
 
-       public void resetMissedCallsCount() {
+       public synchronized void resetMissedCallsCount() {
                resetMissedCallsCount(nativePtr);
        }
        
@@ -793,7 +793,7 @@ class LinphoneCoreImpl implements LinphoneCore {
        }
        
        private native void refreshRegisters(long nativePtr);
-       public void refreshRegisters() {
+       public synchronized void refreshRegisters() {
                refreshRegisters(nativePtr);
        }
        
@@ -803,19 +803,19 @@ class LinphoneCoreImpl implements LinphoneCore {
        }
        
        @Override
-       public PayloadType findPayloadType(String mime, int clockRate) {
+       public synchronized PayloadType findPayloadType(String mime, int clockRate) {
                return findPayloadType(mime, clockRate, 1);
        }
        
        private native void removeFriend(long ptr, long lf);
        @Override
-       public void removeFriend(LinphoneFriend lf) {
+       public synchronized void removeFriend(LinphoneFriend lf) {
                removeFriend(nativePtr, lf.getNativePtr());
        }
        
        private native long getFriendByAddress(long ptr, String sipUri);
        @Override
-       public LinphoneFriend findFriendByAddress(String sipUri) {
+       public synchronized LinphoneFriend findFriendByAddress(String sipUri) {
                long ptr = getFriendByAddress(nativePtr, sipUri);
                if (ptr == 0) {
                        return null;
@@ -823,55 +823,65 @@ class LinphoneCoreImpl implements LinphoneCore {
                return new LinphoneFriendImpl(ptr);
        }
        
-       public void setAudioPort(int port) {
+       public synchronized void setAudioPort(int port) {
                setAudioPort(nativePtr, port);
        }
        
-       public void setVideoPort(int port) {
+       public synchronized void setVideoPort(int port) {
                setVideoPort(nativePtr, port);
        }
        
-       public void setAudioPortRange(int minPort, int maxPort) {
+       public synchronized void setAudioPortRange(int minPort, int maxPort) {
                setAudioPortRange(nativePtr, minPort, maxPort);
        }
        
-       public void setVideoPortRange(int minPort, int maxPort) {
+       public synchronized void setVideoPortRange(int minPort, int maxPort) {
                setVideoPortRange(nativePtr, minPort, maxPort);
        }
        
-       public void setIncomingTimeout(int timeout) {
+       public synchronized void setIncomingTimeout(int timeout) {
                setIncomingTimeout(nativePtr, timeout);
        }
        
-       public void setInCallTimeout(int timeout)
+       public synchronized void setInCallTimeout(int timeout)
        {
                setInCallTimeout(nativePtr, timeout);
        }
        
        private native void setMicrophoneGain(long ptr, float gain);
-       public void setMicrophoneGain(float gain) {
+       public synchronized void setMicrophoneGain(float gain) {
                setMicrophoneGain(nativePtr, gain);
        }
        
-       public void setPrimaryContact(String displayName, String username) {
+       public synchronized void setPrimaryContact(String displayName, String username) {
                setPrimaryContact(nativePtr, displayName, username);
        }
        
        private native void setUseSipInfoForDtmfs(long ptr, boolean use);
-       public void setUseSipInfoForDtmfs(boolean use) {
+       public synchronized void setUseSipInfoForDtmfs(boolean use) {
                setUseSipInfoForDtmfs(nativePtr, use);
        }
        
        private native void setUseRfc2833ForDtmfs(long ptr, boolean use);
-       public void setUseRfc2833ForDtmfs(boolean use) {
+       public synchronized void setUseRfc2833ForDtmfs(boolean use) {
                setUseRfc2833ForDtmfs(nativePtr, use);
        }
 
        private native long getConfig(long ptr);
-       public LpConfig getConfig() {
+       public synchronized LpConfig getConfig() {
                long configPtr=getConfig(nativePtr);
                return new LpConfigImpl(configPtr);
        }
+       private native boolean needsEchoCalibration(long ptr);
+       @Override
+       public synchronized boolean needsEchoCalibration() {
+               return needsEchoCalibration(nativePtr);
+       }
+       private native void declineCall(long coreptr, long callptr, int reason);
+       @Override
+       public synchronized void declineCall(LinphoneCall aCall, Reason reason) {
+               declineCall(nativePtr,((LinphoneCallImpl)aCall).nativePtr,reason.mValue);
+       }
        
        private native boolean upnpAvailable(long ptr);
        public boolean upnpAvailable() {
index 756a51419d833105a6378db71679073f6e9492b0..73f3e2580927705f26a8eb2e98d8e15606ec6148 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 756a51419d833105a6378db71679073f6e9492b0
+Subproject commit 73f3e2580927705f26a8eb2e98d8e15606ec6148