Commit b8eff5b0 authored by Simon Morlat's avatar Simon Morlat
Browse files

improve echo calibration

add mising declineCall() method to java api.
parent 685a0b31
......@@ -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.");
}
}
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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;
......
......@@ -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
......
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;
}
}
......@@ -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() {
......
mediastreamer2 @ 73f3e258
Subproject commit 756a51419d833105a6378db71679073f6e9492b0
Subproject commit 73f3e2580927705f26a8eb2e98d8e15606ec6148
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment