diff --git a/apps/examples/simple_conference/Makefile b/apps/examples/simple_conference/Makefile new file mode 100644 index 00000000..ce8599e0 --- /dev/null +++ b/apps/examples/simple_conference/Makefile @@ -0,0 +1,9 @@ +plug_in_name = simple_conference + +module_ldflags = +module_cflags = + +extra_install = $(plug_in_name)_audio + +COREPATH ?=../../../core +include $(COREPATH)/plug-in/Makefile.app_module diff --git a/apps/examples/simple_conference/Readme.simple_conference b/apps/examples/simple_conference/Readme.simple_conference new file mode 100644 index 00000000..ef6fdfde --- /dev/null +++ b/apps/examples/simple_conference/Readme.simple_conference @@ -0,0 +1,22 @@ +simple_conference - simple example of conference mixer + +Due to the dialout function in the 'conference' application +plugin, the source code of the conference plugin is somewhat +obfuscated. Therefore this simple shows how simple it +actually is to use the conference mixer provided by the core: +The Session only needs to get a conference "channel" (a +connection to the mixer) from the conference "status" (which +is one conference room), and set it as input and output. + +It could actually be made even simpler, but one interesting +feature is left in here: if someone enters or leaves the +conference room, a sound is played to everyone. This shows how +useful the playlist is: We can have the conference channel, +our connector to the conference, always in the playlist, and +if we want to play a file, we can simply put it in front of the +playlist. When the file later is finished, the playlist +automatically selects the next item, which is again out +conference channel. + +Hopefully this example will be a good start for further custom +conference application development. \ No newline at end of file diff --git a/apps/examples/simple_conference/SimpleConference.cpp b/apps/examples/simple_conference/SimpleConference.cpp new file mode 100644 index 00000000..ee53fd1f --- /dev/null +++ b/apps/examples/simple_conference/SimpleConference.cpp @@ -0,0 +1,143 @@ +/* + * $Id: Conference.cpp 288 2007-03-28 16:32:02Z sayer $ + * + * Copyright (C) 2002-2003 Fhg Fokus + * + * This file is part of sems, a free SIP media server. + * + * sems 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. + * + * For a license to use the sems software under conditions + * other than those described here, or to purchase support for this + * software, please contact iptel.org by e-mail at the following addresses: + * info@iptel.org + * + * sems 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 + */ + +#include "SimpleConference.h" +#include "AmConferenceStatus.h" + +#include "log.h" + +#define APP_NAME "simple_conference" + +EXPORT_SESSION_FACTORY(SimpleConferenceFactory,APP_NAME); + +SimpleConferenceFactory::SimpleConferenceFactory(const string& _app_name) + : AmSessionFactory(_app_name) +{ +} + +int SimpleConferenceFactory::onLoad() +{ + return 0; +} + +// incoming calls - req is INVITE +AmSession* SimpleConferenceFactory::onInvite(const AmSipRequest& req) +{ + return new SimpleConferenceDialog(); +} + +// outgoing calls - rep is 200 class response to INVITE +AmSession* SimpleConferenceFactory::onInvite(const AmSipReply& rep) +{ + return new SimpleConferenceDialog(); +} + +SimpleConferenceDialog::SimpleConferenceDialog() + : play_list(this) +{ + // use adaptive playout - its the best method around + rtp_str.setPlayoutType(ADAPTIVE_PLAYOUT); +} + +SimpleConferenceDialog::~SimpleConferenceDialog() +{ +} + +void SimpleConferenceDialog::onSessionStart(const AmSipRequest& req) +{ + // set the conference id ('conference room') to user part of ruri + conf_id = dlg.user; + + // open the beep file + BeepSound.reset(new AmAudioFile()); + if(BeepSound->open(BEEP_FILE_NAME, AmAudioFile::Read)) { + BeepSound.reset(0); + } + + // get a channel from the status + channel.reset(AmConferenceStatus::getChannel(conf_id,getLocalTag())); + + // add the channel to our playlist + play_list.addToPlaylist(new AmPlaylistItem(channel.get(), + channel.get())); + + // set the playlist as input and output + setInOut(&play_list,&play_list); + + // we need to be in the same callgroup as the other + // people in the conference (important if we have multiple + // MediaProcessor threads + setCallgroup(conf_id); +} + +void SimpleConferenceDialog::onBye(const AmSipRequest& req) +{ + play_list.close(); + setInOut(NULL,NULL); + channel.reset(NULL); + setStopped(); +} + +void SimpleConferenceDialog::process(AmEvent* ev) +{ + // check conference events + ConferenceEvent* ce = dynamic_cast(ev); + if(ce && (conf_id == ce->conf_id)){ + switch(ce->event_id){ + + case ConfNewParticipant: { + if(BeepSound.get()){ + // rewind in case we already played it + BeepSound->rewind(); + // add to front of playlist - after the file is played + // we will be connected again to conference channel + play_list.addToPlayListFront(new AmPlaylistItem(BeepSound.get(), NULL)); + } + } break; + + case ConfParticipantLeft: { + if(BeepSound.get()){ + BeepSound->rewind(); + play_list.addToPlayListFront(new AmPlaylistItem( BeepSound.get(), NULL)); + } + } break; + + default: + break; + } + return; + } + + AmSession::process(ev); +} + +void SimpleConferenceDialog::onDtmf(int event, int duration) +{ + DBG("SimpleConferenceDialog::onDtmf: event %d duration %d\n", + event, duration); +} + diff --git a/apps/examples/simple_conference/SimpleConference.h b/apps/examples/simple_conference/SimpleConference.h new file mode 100644 index 00000000..9dd2cc17 --- /dev/null +++ b/apps/examples/simple_conference/SimpleConference.h @@ -0,0 +1,84 @@ +/* + * $Id: Conference.h 288 2007-03-28 16:32:02Z sayer $ + * + * Copyright (C) 2002-2003 Fhg Fokus + * + * This file is part of sems, a free SIP media server. + * + * sems 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. + * + * For a license to use the sems software under conditions + * other than those described here, or to purchase support for this + * software, please contact iptel.org by e-mail at the following addresses: + * info@iptel.org + * + * sems 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 + */ +#ifndef _SIMPLECONFERENCE_H_ +#define _SIMPLECONFERENCE_H_ + +#include "AmApi.h" +#include "AmSession.h" +#include "AmConferenceChannel.h" +#include "AmPlaylist.h" + +#include +#include +using std::map; +using std::string; + +class ConferenceStatus; +class ConferenceStatusContainer; + +// of course this should be taken from config +// - just wanted to make things simple +#define BEEP_FILE_NAME "../apps/examples/simple_conference/wav/beep.wav" + +class SimpleConferenceFactory : public AmSessionFactory +{ +public: + SimpleConferenceFactory(const string& _app_name); + AmSession* onInvite(const AmSipRequest&); + AmSession* onInvite(const AmSipReply&); + int onLoad(); +}; + +class SimpleConferenceDialog : public AmSession +{ + string conf_id; + // our connection to the conference + auto_ptr channel; + + // we use a playlist so we can put e.g. + // announcement files to be played to the + // user in front and after its finished we will + // be connected back to conference automatically + AmPlaylist play_list; + auto_ptr BeepSound; + + +public: + SimpleConferenceDialog(); + ~SimpleConferenceDialog(); + + void process(AmEvent* ev); + void onSessionStart(const AmSipRequest& req); + void onDtmf(int event, int duration); + void onBye(const AmSipRequest& req); +}; + +#endif +// Local Variables: +// mode:C++ +// End: + diff --git a/apps/examples/simple_conference/wav/beep.wav b/apps/examples/simple_conference/wav/beep.wav new file mode 100644 index 00000000..1151f909 Binary files /dev/null and b/apps/examples/simple_conference/wav/beep.wav differ