1 /*
2  * Copyright (C) 2002-2003 Fhg Fokus
3  *
4  * This file is part of SEMS, a free SIP media server.
5  *
6  * SEMS is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * For a license to use the sems software under conditions
12  * other than those described here, or to purchase support for this
13  * software, please contact iptel.org by e-mail at the following addresses:
14  *    info@iptel.org
15  *
16  * SEMS 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.
20  *
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
24  */
25 /** @file AmMultiPartyMixer.h */
26 #ifndef _MultiPartyMixer_h_
27 #define _MultiPartyMixer_h_
28 
29 #include "AmAudio.h"
30 #include "AmThread.h"
31 #include "SampleArray.h"
32 
33 //#define RORPP_PLC
34 
35 #ifdef RORPP_PLC
36 #include "LowcFE.h"
37 #endif
38 
39 #include <map>
40 #include <set>
41 
42 struct MixerBufferState
43 {
44   typedef std::map<int,SampleArrayShort*> ChannelMap;
45 
46   unsigned int sample_rate;
47   unsigned int last_ts;
48   ChannelMap channels;
49   SampleArrayInt *mixed_channel;
50 
51   MixerBufferState(unsigned int sample_rate, std::set<int>& channelids);
52   MixerBufferState(const MixerBufferState& other);
53   ~MixerBufferState();
54 
55   void add_channel(unsigned int channel_id);
56   void remove_channel(unsigned int channel_id);
57   SampleArrayShort* get_channel(unsigned int channel_id);
58   void fix_channels(std::set<int>& curchannelids);
59   void free_channels();
60 };
61 
62 /**
63  * \brief Mixer for one conference.
64  *
65  * AmMultiPartyMixer mixes the audio from all channels,
66  * and returns the audio of all other channels.
67  */
68 class AmMultiPartyMixer
69 {
70   typedef std::set<int> ChannelIdSet;
71   typedef std::map<int,int> SampleRateMap;
72   typedef std::multiset<int> SampleRateSet;
73 
74   SampleRateMap    sampleratemap;
75   SampleRateSet    samplerates;
76   ChannelIdSet     channelids;
77   std::deque<MixerBufferState> buffer_state;
78 
79   AmMutex          audio_mut;
80   int              scaling_factor;
81   int              tmp_buffer[AUDIO_BUFFER_SIZE/2];
82 
83   std::deque<MixerBufferState>::iterator findOrCreateBufferState(unsigned int sample_rate);
84   std::deque<MixerBufferState>::iterator findBufferStateForReading(unsigned int sample_rate,
85 								   unsigned long long last_ts);
86   void cleanupBufferStates(unsigned int last_ts);
87 
88   void mix_add(int* dest,int* src1,short* src2,unsigned int size);
89   void mix_sub(int* dest,int* src1,short* src2,unsigned int size);
90   void scale(short* buffer,int* tmp_buf,unsigned int size);
91 
92 public:
93   AmMultiPartyMixer();
94   ~AmMultiPartyMixer();
95 
96   unsigned int addChannel(unsigned int external_sample_rate);
97   void removeChannel(unsigned int channel_id);
98 
99   void PutChannelPacket(unsigned int   channel_id,
100 			unsigned long long system_ts,
101 			unsigned char* buffer,
102 			unsigned int   size);
103 
104   void GetChannelPacket(unsigned int   channel,
105 			unsigned long long system_ts,
106 			unsigned char* buffer,
107 			unsigned int&  size,
108 			unsigned int&  output_sample_rate);
109 
110   int GetCurrentSampleRate();
111 
112   void lock();
113   void unlock();
114 };
115 
116 #endif
117 
118