Author: sayer Date: 2009-01-02 16:46:26 +0100 (Fri, 02 Jan 2009) New Revision: 1223
Added: trunk/core/AmAudioMixer.cpp trunk/core/AmAudioMixer.h Modified: trunk/core/AmAudioMixIn.h Log: audio mixer for input Modified: trunk/core/AmAudioMixIn.h =================================================================== --- trunk/core/AmAudioMixIn.h 2009-01-02 14:58:33 UTC (rev 1222) +++ trunk/core/AmAudioMixIn.h 2009-01-02 15:46:26 UTC (rev 1223) @@ -39,6 +39,8 @@ /** * \brief \ref AmAudio to mix in every n seconds a file * + * This is only for output (e.g. mixing in some tones into a call) + * * AmAudio that plays Audio A and * every s seconds mixes in AudioFile B with level l. * If l == 0, playback of A is not continued when playing B, Added: trunk/core/AmAudioMixer.cpp =================================================================== --- trunk/core/AmAudioMixer.cpp 2009-01-02 14:58:33 UTC (rev 1222) +++ trunk/core/AmAudioMixer.cpp 2009-01-02 15:46:26 UTC (rev 1223) @@ -0,0 +1,112 @@ +/* + * $Id$ + * + * Copyright (C) 2008 IPTEGO GmbH + * + * 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: + * [email protected] + * + * 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 "AmAudioMixer.h" + +AmAudioMixer::AmAudioMixer() { + sink_channel = mixer.addChannel(); + sink_connector = + new AmAudioMixerConnector(mixer, sink_channel, NULL, + &srcsink_mut, &sinks); +} + +AmAudioMixer::~AmAudioMixer() { + mixer.removeChannel(sink_channel); + for (std::map<AmAudioMixerConnector*, unsigned int>::iterator + it=sources.begin(); it != sources.end(); it++) { + mixer.removeChannel(it->second); + delete it->first; + } + delete sink_connector; +} + +AmAudio* AmAudioMixer::addSource() { + srcsink_mut.lock(); + unsigned int src_channel = mixer.addChannel(); + // the first source will process the media in the mixer channel + AmAudioMixerConnector* conn = + new AmAudioMixerConnector(mixer, src_channel, + sources.empty() ? sink_connector : NULL); + sources[conn] = src_channel; + srcsink_mut.unlock(); + return conn; +} + +void AmAudioMixer::releaseSource(AmAudio* s) { + srcsink_mut.lock(); + std::map<AmAudioMixerConnector*, unsigned int>::iterator it= + sources.find((AmAudioMixerConnector*)s); + if (it==sources.end()) { + srcsink_mut.unlock(); + ERROR("source [%p] is not part of this mixer.\n", s); + return; + } + mixer.removeChannel(it->second); + delete s; + sources.erase(it); + srcsink_mut.unlock(); +} + +void AmAudioMixer::addSink(AmAudio* s) { + srcsink_mut.lock(); + sinks.insert(s); + srcsink_mut.unlock(); +} + +void AmAudioMixer::releaseSink(AmAudio* s) { + srcsink_mut.lock(); + sinks.erase(s); + srcsink_mut.unlock(); +} + +int AmAudioMixerConnector::get(unsigned int user_ts, unsigned char* buffer, unsigned int nb_samples) { + // in fact GCP here only needed for the mixed channel + mixer.GetChannelPacket(channel, user_ts, buffer, nb_samples); + + if ((audio_mut != NULL) && (sinks != NULL)) { + audio_mut->lock(); + // write to all sinks + for (std::set<AmAudio*>::iterator it=sinks->begin(); + it != sinks->end(); it++) { + (*it)->put(user_ts, buffer, nb_samples); + } + audio_mut->unlock(); + } + + return nb_samples; +} + +int AmAudioMixerConnector::put(unsigned int user_ts, unsigned char* buffer, unsigned int size) { + mixer.PutChannelPacket(channel, user_ts, buffer, size); + + if (mix_channel != NULL) { + // we are processing the media of the mixed channel as well + ShortSample mix_buffer[SIZE_MIX_BUFFER]; + mix_channel->get(user_ts, (unsigned char*)mix_buffer, size); + } + return size; +} Property changes on: trunk/core/AmAudioMixer.cpp ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Added: trunk/core/AmAudioMixer.h =================================================================== --- trunk/core/AmAudioMixer.h 2009-01-02 14:58:33 UTC (rev 1222) +++ trunk/core/AmAudioMixer.h 2009-01-02 15:46:26 UTC (rev 1223) @@ -0,0 +1,98 @@ +/* + * $Id$ + * + * Copyright (C) 2008 IPTEGO GmbH + * + * 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: + * [email protected] + * + * 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 _AmAudioMixer_h_ +#define _AmAudioMixer_h_ + +#include "AmMultiPartyMixer.h" +#include "AmThread.h" + +#include <map> +#include <set> + +class AmAudioMixerConnector; + +/** + * \brief \ref AmAudio to mix input + * + * AmAudio that mixes some sources' audio and writes into a set of sinks. + * + * Can probably do lots of things together with AmAudioQueue and/or AmAudioMixIn. + * + * Attention: Sources (in fact AmAudioMixerConnector) are owned by the AmAudioMixer, + * i.e. deleted on releaseSink/destructor. + * Sinks are not owned by the AmAudioMixer. + */ +class AmAudioMixer +{ + AmMultiPartyMixer mixer; + + AmMutex srcsink_mut; + std::map<AmAudioMixerConnector*, unsigned int> sources; + + unsigned int sink_channel; + AmAudioMixerConnector* sink_connector; + std::set<AmAudio*> sinks; + + public: + AmAudioMixer(); + ~AmAudioMixer(); + + AmAudio* addSource(); + void releaseSource(AmAudio* s); + + void addSink(AmAudio* s); + void releaseSink(AmAudio* s); +}; + +class AmAudioMixerConnector +: public AmAudio { + AmMultiPartyMixer& mixer; + unsigned int channel; + AmMutex* audio_mut; + std::set<AmAudio*>* sinks; + AmAudio* mix_channel; + + protected: + int get(unsigned int user_ts, unsigned char* buffer, unsigned int nb_samples); + int put(unsigned int user_ts, unsigned char* buffer, unsigned int size); + + // dummies for AmAudio's pure virtual methods + int read(unsigned int user_ts, unsigned int size){ return -1; } + int write(unsigned int user_ts, unsigned int size){ return -1; } + + public: + AmAudioMixerConnector(AmMultiPartyMixer& mixer, unsigned int channel, + AmAudio* mix_channel, + AmMutex* audio_mut = NULL, std::set<AmAudio*>* sinks = NULL) + : mixer(mixer), channel(channel), mix_channel(mix_channel), + audio_mut(audio_mut), sinks(sinks) { } + ~AmAudioMixerConnector() { } + +}; + +#endif Property changes on: trunk/core/AmAudioMixer.h ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
