1 /***************************************************************************
5 * Copyright 2011 Belledonne Communications
7 * Email simon dot morlat at linphone dot org
8 ****************************************************************************/
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include "mediastreamer2/msvolume.h"
30 static void conference_check_init(LinphoneConference *ctx){
32 MSAudioConferenceParams params;
33 params.samplerate=16000;
34 ctx->conf=ms_audio_conference_new(¶ms);
38 static void remove_local_endpoint(LinphoneConference *ctx){
39 if (ctx->local_endpoint){
40 ms_audio_conference_remove_member(ctx->conf,ctx->local_endpoint);
41 ms_audio_endpoint_release_from_stream(ctx->local_endpoint);
42 ctx->local_endpoint=NULL;
43 audio_stream_stop(ctx->local_participant);
44 ctx->local_participant=NULL;
48 void linphone_core_conference_check_uninit(LinphoneConference *ctx){
50 ms_message("conference_check_uninit(): nmembers=%i",ctx->conf->nmembers);
51 if (ctx->conf->nmembers==1 && ctx->local_participant!=NULL){
52 remove_local_endpoint(ctx);
54 if (ctx->conf->nmembers==0){
55 ms_audio_conference_destroy(ctx->conf);
62 void linphone_call_add_to_conf(LinphoneCall *call){
63 LinphoneCore *lc=call->core;
64 LinphoneConference *conf=&lc->conf_ctx;
66 call->params.has_video = FALSE;
67 call->camera_active = FALSE;
68 ep=ms_audio_endpoint_get_from_stream(call->audiostream,TRUE);
69 ms_audio_conference_add_member(conf->conf,ep);
73 void linphone_call_remove_from_conf(LinphoneCall *call){
74 LinphoneCore *lc=call->core;
75 LinphoneConference *conf=&lc->conf_ctx;
77 ms_audio_conference_remove_member(conf->conf,call->endpoint);
78 ms_audio_endpoint_release_from_stream(call->endpoint);
82 static RtpProfile *make_dummy_profile(int samplerate){
83 RtpProfile *prof=rtp_profile_new("dummy");
84 PayloadType *pt=payload_type_clone(&payload_type_l16_mono);
85 pt->clock_rate=samplerate;
86 rtp_profile_set_payload(prof,0,pt);
90 static void add_local_endpoint(LinphoneConference *conf,LinphoneCore *lc){
91 /*create a dummy audiostream in order to extract the local part of it */
92 /* network address and ports have no meaning and are not used here. */
93 AudioStream *st=audio_stream_new(65000,FALSE);
94 MSSndCard *playcard=lc->sound_conf.lsd_card ?
95 lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
96 MSSndCard *captcard=lc->sound_conf.capt_sndcard;
97 const MSAudioConferenceParams *params=ms_audio_conference_get_params(conf->conf);
98 RtpProfile *prof=make_dummy_profile(params->samplerate);
100 audio_stream_start_full(st, prof,
110 linphone_core_echo_cancellation_enabled(lc)
112 _post_configure_audio_stream(st,lc,FALSE);
113 conf->local_participant=st;
114 conf->local_endpoint=ms_audio_endpoint_get_from_stream(st,FALSE);
115 ms_audio_conference_add_member(conf->conf,conf->local_endpoint);
116 /*normally and exceptionnaly, the profile is no more accessed past this point*/
117 rtp_profile_destroy(prof);
120 float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){
121 LinphoneConference *conf=&lc->conf_ctx;
122 AudioStream *st=conf->local_participant;
123 if (st && st->volsend && !conf->local_muted){
125 ms_filter_call_method(st->volsend,MS_VOLUME_GET,&vol);
129 return LINPHONE_VOLUME_DB_LOWEST;
132 int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){
133 LinphoneCallParams params;
134 LinphoneConference *conf=&lc->conf_ctx;
136 if (call->current_params.in_conference){
137 ms_error("Already in conference");
140 conference_check_init(&lc->conf_ctx);
141 call->params.in_conference=TRUE;
142 call->params.has_video=FALSE;
144 if (call->state==LinphoneCallPaused)
145 linphone_core_resume_call(lc,call);
146 else if (call->state==LinphoneCallStreamsRunning){
147 /*this will trigger a reINVITE that will later redraw the streams */
148 if (call->audiostream || call->videostream){
149 linphone_call_stop_media_streams (call); /*free the audio & video local resources*/
151 if (call==lc->current_call){
152 lc->current_call=NULL;
154 linphone_core_update_call(lc,call,¶ms);
155 add_local_endpoint(conf,lc);
157 ms_error("Call is in state %s, it cannot be added to the conference.",linphone_call_state_to_string(call->state));
163 int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){
165 if (!call->current_params.in_conference){
166 if (call->params.in_conference){
167 ms_warning("Not (yet) in conference, be patient");
170 ms_error("Not in a conference.");
174 call->params.in_conference=FALSE;
175 err=linphone_core_pause_call(lc,call);
179 bool_t linphone_core_is_in_conference(const LinphoneCore *lc){
180 return lc->conf_ctx.local_participant!=NULL;
183 int linphone_core_leave_conference(LinphoneCore *lc){
184 LinphoneConference *conf=&lc->conf_ctx;
185 if (linphone_core_is_in_conference(lc))
186 remove_local_endpoint(conf);
191 int linphone_core_enter_conference(LinphoneCore *lc){
192 LinphoneConference *conf=&lc->conf_ctx;
193 if (conf->local_participant==NULL) add_local_endpoint(conf,lc);
197 int linphone_core_add_all_to_conference(LinphoneCore *lc) {
198 MSList *calls=lc->calls;
200 LinphoneCall *call=(LinphoneCall*)calls->data;
202 if (!call->current_params.in_conference) {
203 linphone_core_add_to_conference(lc, call);
209 int linphone_core_terminate_conference(LinphoneCore *lc) {
210 MSList *calls=lc->calls;
212 LinphoneCall *call=(LinphoneCall*)calls->data;
214 if (call->current_params.in_conference) {
215 linphone_core_terminate_call(lc, call);
221 int linphone_core_get_conference_size(LinphoneCore *lc) {
222 return ms_audio_conference_size(lc->conf_ctx.conf);