diff --git a/console/commands.c b/console/commands.c index b46edc194..7565f46d8 100644 --- a/console/commands.c +++ b/console/commands.c @@ -281,6 +281,7 @@ linphonec_parse_command_line(LinphoneCore *lc, char *cl) while ( isdigit(*cl) || *cl == '#' || *cl == '*' ) { linphone_core_send_dtmf(lc, *cl); + linphone_core_play_dtmf (lc,*cl,100); ms_sleep(1); // be nice ++cl; } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index c94388a9c..56bc2d4a0 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -100,6 +100,11 @@ static void call_received(SalOp *h){ /* play the ring */ if (lc->sound_conf.ring_sndcard!=NULL){ + if (lc->ringstream && lc->dmfs_playing_start_time!=0){ + ring_stop(lc->ringstream); + lc->ringstream=NULL; + lc->dmfs_playing_start_time=0; + } ms_message("Starting local ring..."); lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard); } @@ -122,6 +127,11 @@ static void call_ringing(SalOp *h){ lc->vtable.display_status(lc,_("Remote ringing.")); md=sal_call_get_final_media_description(h); if (md==NULL){ + if (lc->ringstream && lc->dmfs_playing_start_time!=0){ + ring_stop(lc->ringstream); + lc->ringstream=NULL; + lc->dmfs_playing_start_time=0; + } if (lc->ringstream!=NULL) return; /*already ringing !*/ if (lc->sound_conf.play_sndcard!=NULL){ ms_message("Remote ringing..."); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 55b9a7553..83b69c943 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/mediastream.h" #include "mediastreamer2/msvolume.h" #include "mediastreamer2/msequalizer.h" +#include "mediastreamer2/dtmfgen.h" #include @@ -1763,6 +1764,13 @@ void linphone_core_iterate(LinphoneCore *lc){ lc_callback_obj_invoke(&lc->preview_finished_cb,lc); } + if (lc->ringstream && lc->dmfs_playing_start_time!=0 + && (curtime-lc->dmfs_playing_start_time)>5){ + ring_stop(lc->ringstream); + lc->ringstream=NULL; + lc->dmfs_playing_start_time=0; + } + sal_iterate(lc->sal); if (lc->auto_net_state_mon) monitor_network_state(lc,curtime); @@ -3470,6 +3478,48 @@ void linphone_core_set_record_file(LinphoneCore *lc, const char *file){ } } +static MSFilter *get_dtmf_gen(LinphoneCore *lc){ + LinphoneCall *call=linphone_core_get_current_call (lc); + if (call){ + AudioStream *stream=lc->audiostream; + if (stream){ + return stream->dtmfgen; + } + } + if (lc->ringstream==NULL){ + MSSndCard *ringcard= lc->sound_conf.ring_sndcard; + lc->ringstream=ring_start(NULL,0,ringcard); + lc->dmfs_playing_start_time=time(NULL); + }else{ + if (lc->dmfs_playing_start_time!=0) + lc->dmfs_playing_start_time=time(NULL); + } + return lc->ringstream->gendtmf; +} + +/** + * Plays a dtmf to the local user. +**/ +void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms){ + MSFilter *f=get_dtmf_gen(lc); + if (f==NULL){ + ms_error("No dtmf generator at this time !"); + return; + } + if (duration_ms>0) + ms_filter_call_method(f, MS_DTMF_GEN_PLAY, &dtmf); + else ms_filter_call_method(f, MS_DTMF_GEN_START, &dtmf); +} + +/** + * Stops playing a dtmf started by linphone_core_play_dtmf(). +**/ +void linphone_core_stop_dtmf(LinphoneCore *lc){ + MSFilter *f=get_dtmf_gen(lc); + ms_filter_call_method_noarg (f, MS_DTMF_GEN_STOP); +} + + /** * Retrieves the user pointer that was given to linphone_core_new() * diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 28ad13587..9bfce8629 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -774,6 +774,9 @@ void linphone_core_set_play_file(LinphoneCore *lc, const char *file); void linphone_core_set_record_file(LinphoneCore *lc, const char *file); gstate_t linphone_core_get_state(const LinphoneCore *lc, gstate_group_t group); +void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms); +void linphone_core_stop_dtmf(LinphoneCore *lc); + int linphone_core_get_current_call_duration(const LinphoneCore *lc); const LinphoneAddress *linphone_core_get_remote_uri(LinphoneCore *lc); diff --git a/coreapi/private.h b/coreapi/private.h index 43f4e0f08..1faffaa67 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -364,6 +364,7 @@ struct _LinphoneCore MSList *friends; MSList *auth_info; struct _RingStream *ringstream; + time_t dmfs_playing_start_time; LCCallbackObj preview_finished_cb; struct _LinphoneCall *call; /* the current call, in the future it will be a list of calls (conferencing)*/ MSList *queued_calls; /* used by the autoreplier */ diff --git a/gtk-glade/main.c b/gtk-glade/main.c index 3ce841ad0..5fa9c6895 100644 --- a/gtk-glade/main.c +++ b/gtk-glade/main.c @@ -1003,12 +1003,12 @@ void linphone_gtk_load_identities(void){ static void linphone_gtk_dtmf_clicked(GtkButton *button){ const char *label=gtk_button_get_label(button); + GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"uribar"); + int pos=-1; + gtk_editable_insert_text(GTK_EDITABLE(uri_bar),label,1,&pos); + linphone_core_play_dtmf (linphone_gtk_get_core(),label[0],100); if (linphone_core_in_call(linphone_gtk_get_core())){ linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]); - }else{ - GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"uribar"); - int pos=-1; - gtk_editable_insert_text(GTK_EDITABLE(uri_bar),label,1,&pos); } } diff --git a/mediastreamer2 b/mediastreamer2 index 4b5164714..332d79209 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 4b5164714c2cf77a284f0213fc79e9b147e8563a +Subproject commit 332d79209b333bd8ded5b16a7b9dcfe2c0aedc63