• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_
12 #define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_
13 
14 #include <list>
15 #include <map>
16 
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/engine_configurations.h"
19 #include "webrtc/modules/audio_conference_mixer/include/audio_conference_mixer.h"
20 #include "webrtc/modules/audio_conference_mixer/source/memory_pool.h"
21 #include "webrtc/modules/audio_conference_mixer/source/time_scheduler.h"
22 #include "webrtc/modules/include/module_common_types.h"
23 
24 namespace webrtc {
25 class AudioProcessing;
26 class CriticalSectionWrapper;
27 
28 typedef std::list<AudioFrame*> AudioFrameList;
29 typedef std::list<MixerParticipant*> MixerParticipantList;
30 
31 // Cheshire cat implementation of MixerParticipant's non virtual functions.
32 class MixHistory
33 {
34 public:
35     MixHistory();
36     ~MixHistory();
37 
38     // Returns true if the participant is being mixed.
39     bool IsMixed() const;
40 
41     // Returns true if the participant was mixed previous mix
42     // iteration.
43     bool WasMixed() const;
44 
45     // Updates the mixed status.
46     int32_t SetIsMixed(bool mixed);
47 
48     void ResetMixedStatus();
49 private:
50     bool _isMixed;
51 };
52 
53 class AudioConferenceMixerImpl : public AudioConferenceMixer
54 {
55 public:
56     // AudioProcessing only accepts 10 ms frames.
57     enum {kProcessPeriodicityInMs = 10};
58 
59     AudioConferenceMixerImpl(int id);
60     ~AudioConferenceMixerImpl();
61 
62     // Must be called after ctor.
63     bool Init();
64 
65     // Module functions
66     int64_t TimeUntilNextProcess() override;
67     int32_t Process() override;
68 
69     // AudioConferenceMixer functions
70     int32_t RegisterMixedStreamCallback(
71         AudioMixerOutputReceiver* mixReceiver) override;
72     int32_t UnRegisterMixedStreamCallback() override;
73     int32_t SetMixabilityStatus(MixerParticipant* participant,
74                                 bool mixable) override;
75     bool MixabilityStatus(const MixerParticipant& participant) const override;
76     int32_t SetMinimumMixingFrequency(Frequency freq) override;
77     int32_t SetAnonymousMixabilityStatus(
78         MixerParticipant* participant, bool mixable) override;
79     bool AnonymousMixabilityStatus(
80         const MixerParticipant& participant) const override;
81 
82 private:
83     enum{DEFAULT_AUDIO_FRAME_POOLSIZE = 50};
84 
85     // Set/get mix frequency
86     int32_t SetOutputFrequency(const Frequency& frequency);
87     Frequency OutputFrequency() const;
88 
89     // Fills mixList with the AudioFrames pointers that should be used when
90     // mixing.
91     // maxAudioFrameCounter both input and output specifies how many more
92     // AudioFrames that are allowed to be mixed.
93     // rampOutList contain AudioFrames corresponding to an audio stream that
94     // used to be mixed but shouldn't be mixed any longer. These AudioFrames
95     // should be ramped out over this AudioFrame to avoid audio discontinuities.
96     void UpdateToMix(
97         AudioFrameList* mixList,
98         AudioFrameList* rampOutList,
99         std::map<int, MixerParticipant*>* mixParticipantList,
100         size_t* maxAudioFrameCounter) const;
101 
102     // Return the lowest mixing frequency that can be used without having to
103     // downsample any audio.
104     int32_t GetLowestMixingFrequency() const;
105     int32_t GetLowestMixingFrequencyFromList(
106         const MixerParticipantList& mixList) const;
107 
108     // Return the AudioFrames that should be mixed anonymously.
109     void GetAdditionalAudio(AudioFrameList* additionalFramesList) const;
110 
111     // Update the MixHistory of all MixerParticipants. mixedParticipantsList
112     // should contain a map of MixerParticipants that have been mixed.
113     void UpdateMixedStatus(
114         const std::map<int, MixerParticipant*>& mixedParticipantsList) const;
115 
116     // Clears audioFrameList and reclaims all memory associated with it.
117     void ClearAudioFrameList(AudioFrameList* audioFrameList) const;
118 
119     // Update the list of MixerParticipants who have a positive VAD. mixList
120     // should be a list of AudioFrames
121     void UpdateVADPositiveParticipants(AudioFrameList* mixList) const;
122 
123     // This function returns true if it finds the MixerParticipant in the
124     // specified list of MixerParticipants.
125     bool IsParticipantInList(const MixerParticipant& participant,
126                              const MixerParticipantList& participantList) const;
127 
128     // Add/remove the MixerParticipant to the specified
129     // MixerParticipant list.
130     bool AddParticipantToList(
131         MixerParticipant* participant,
132         MixerParticipantList* participantList) const;
133     bool RemoveParticipantFromList(
134         MixerParticipant* removeParticipant,
135         MixerParticipantList* participantList) const;
136 
137     // Mix the AudioFrames stored in audioFrameList into mixedAudio.
138     int32_t MixFromList(AudioFrame* mixedAudio,
139                         const AudioFrameList& audioFrameList) const;
140 
141     // Mix the AudioFrames stored in audioFrameList into mixedAudio. No
142     // record will be kept of this mix (e.g. the corresponding MixerParticipants
143     // will not be marked as IsMixed()
144     int32_t MixAnonomouslyFromList(AudioFrame* mixedAudio,
145                                    const AudioFrameList& audioFrameList) const;
146 
147     bool LimitMixedAudio(AudioFrame* mixedAudio) const;
148 
149     rtc::scoped_ptr<CriticalSectionWrapper> _crit;
150     rtc::scoped_ptr<CriticalSectionWrapper> _cbCrit;
151 
152     int32_t _id;
153 
154     Frequency _minimumMixingFreq;
155 
156     // Mix result callback
157     AudioMixerOutputReceiver* _mixReceiver;
158 
159     // The current sample frequency and sample size when mixing.
160     Frequency _outputFrequency;
161     size_t _sampleSize;
162 
163     // Memory pool to avoid allocating/deallocating AudioFrames
164     MemoryPool<AudioFrame>* _audioFramePool;
165 
166     // List of all participants. Note all lists are disjunct
167     MixerParticipantList _participantList;              // May be mixed.
168     // Always mixed, anonomously.
169     MixerParticipantList _additionalParticipantList;
170 
171     size_t _numMixedParticipants;
172     // Determines if we will use a limiter for clipping protection during
173     // mixing.
174     bool use_limiter_;
175 
176     uint32_t _timeStamp;
177 
178     // Metronome class.
179     TimeScheduler _timeScheduler;
180 
181     // Counter keeping track of concurrent calls to process.
182     // Note: should never be higher than 1 or lower than 0.
183     int16_t _processCalls;
184 
185     // Used for inhibiting saturation in mixing.
186     rtc::scoped_ptr<AudioProcessing> _limiter;
187 };
188 }  // namespace webrtc
189 
190 #endif // WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_
191