summaryrefslogtreecommitdiff
path: root/modules/audio_conference_mixer/source/audio_conference_mixer_impl.h
blob: 44f4ff045e74db6748fb01aeb327ba86fd67eb2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_
#define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_

#include <list>
#include <map>

#include "webrtc/engine_configurations.h"
#include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h"
#include "webrtc/modules/audio_conference_mixer/source/level_indicator.h"
#include "webrtc/modules/audio_conference_mixer/source/memory_pool.h"
#include "webrtc/modules/audio_conference_mixer/source/time_scheduler.h"
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

namespace webrtc {
class AudioProcessing;
class CriticalSectionWrapper;

typedef std::list<AudioFrame*> AudioFrameList;
typedef std::list<MixerParticipant*> MixerParticipantList;

// Cheshire cat implementation of MixerParticipant's non virtual functions.
class MixHistory
{
public:
    MixHistory();
    ~MixHistory();

    // MixerParticipant function
    int32_t IsMixed(bool& mixed) const;

    // Sets wasMixed to true if the participant was mixed previous mix
    // iteration.
    int32_t WasMixed(bool& wasMixed) const;

    // Updates the mixed status.
    int32_t SetIsMixed(const bool mixed);

    void ResetMixedStatus();
private:
    bool _isMixed;
};

class AudioConferenceMixerImpl : public AudioConferenceMixer
{
public:
    // AudioProcessing only accepts 10 ms frames.
    enum {kProcessPeriodicityInMs = 10};

    AudioConferenceMixerImpl(int id);
    ~AudioConferenceMixerImpl();

    // Must be called after ctor.
    bool Init();

    // Module functions
    virtual int32_t ChangeUniqueId(const int32_t id);
    virtual int32_t TimeUntilNextProcess();
    virtual int32_t Process();

    // AudioConferenceMixer functions
    virtual int32_t RegisterMixedStreamCallback(
        AudioMixerOutputReceiver& mixReceiver);
    virtual int32_t UnRegisterMixedStreamCallback();
    virtual int32_t RegisterMixerStatusCallback(
        AudioMixerStatusReceiver& mixerStatusCallback,
        const uint32_t amountOf10MsBetweenCallbacks);
    virtual int32_t UnRegisterMixerStatusCallback();
    virtual int32_t SetMixabilityStatus(MixerParticipant& participant,
                                        bool mixable);
    virtual int32_t MixabilityStatus(MixerParticipant& participant,
                                     bool& mixable);
    virtual int32_t SetMinimumMixingFrequency(Frequency freq);
    virtual int32_t SetAnonymousMixabilityStatus(
        MixerParticipant& participant, const bool mixable);
    virtual int32_t AnonymousMixabilityStatus(
        MixerParticipant& participant, bool& mixable);
private:
    enum{DEFAULT_AUDIO_FRAME_POOLSIZE = 50};

    // Set/get mix frequency
    int32_t SetOutputFrequency(const Frequency frequency);
    Frequency OutputFrequency() const;

    // Fills mixList with the AudioFrames pointers that should be used when
    // mixing. Fills mixParticipantList with ParticipantStatistics for the
    // participants who's AudioFrames are inside mixList.
    // maxAudioFrameCounter both input and output specifies how many more
    // AudioFrames that are allowed to be mixed.
    // rampOutList contain AudioFrames corresponding to an audio stream that
    // used to be mixed but shouldn't be mixed any longer. These AudioFrames
    // should be ramped out over this AudioFrame to avoid audio discontinuities.
    void UpdateToMix(
        AudioFrameList* mixList,
        AudioFrameList* rampOutList,
        std::map<int, MixerParticipant*>* mixParticipantList,
        size_t& maxAudioFrameCounter);

    // Return the lowest mixing frequency that can be used without having to
    // downsample any audio.
    int32_t GetLowestMixingFrequency();
    int32_t GetLowestMixingFrequencyFromList(MixerParticipantList* mixList);

    // Return the AudioFrames that should be mixed anonymously.
    void GetAdditionalAudio(AudioFrameList* additionalFramesList);

    // Update the MixHistory of all MixerParticipants. mixedParticipantsList
    // should contain a map of MixerParticipants that have been mixed.
    void UpdateMixedStatus(
        std::map<int, MixerParticipant*>& mixedParticipantsList);

    // Clears audioFrameList and reclaims all memory associated with it.
    void ClearAudioFrameList(AudioFrameList* audioFrameList);

    // Update the list of MixerParticipants who have a positive VAD. mixList
    // should be a list of AudioFrames
    void UpdateVADPositiveParticipants(
        AudioFrameList* mixList);

    // This function returns true if it finds the MixerParticipant in the
    // specified list of MixerParticipants.
    bool IsParticipantInList(
        MixerParticipant& participant,
        MixerParticipantList* participantList) const;

    // Add/remove the MixerParticipant to the specified
    // MixerParticipant list.
    bool AddParticipantToList(
        MixerParticipant& participant,
        MixerParticipantList* participantList);
    bool RemoveParticipantFromList(
        MixerParticipant& removeParticipant,
        MixerParticipantList* participantList);

    // Mix the AudioFrames stored in audioFrameList into mixedAudio.
    int32_t MixFromList(
        AudioFrame& mixedAudio,
        const AudioFrameList* audioFrameList);
    // Mix the AudioFrames stored in audioFrameList into mixedAudio. No
    // record will be kept of this mix (e.g. the corresponding MixerParticipants
    // will not be marked as IsMixed()
    int32_t MixAnonomouslyFromList(AudioFrame& mixedAudio,
                                   const AudioFrameList* audioFrameList);

    bool LimitMixedAudio(AudioFrame& mixedAudio);

    // Scratch memory
    // Note that the scratch memory may only be touched in the scope of
    // Process().
    size_t         _scratchParticipantsToMixAmount;
    ParticipantStatistics  _scratchMixedParticipants[
        kMaximumAmountOfMixedParticipants];
    uint32_t         _scratchVadPositiveParticipantsAmount;
    ParticipantStatistics  _scratchVadPositiveParticipants[
        kMaximumAmountOfMixedParticipants];

    scoped_ptr<CriticalSectionWrapper> _crit;
    scoped_ptr<CriticalSectionWrapper> _cbCrit;

    int32_t _id;

    Frequency _minimumMixingFreq;

    // Mix result callback
    AudioMixerOutputReceiver* _mixReceiver;

    AudioMixerStatusReceiver* _mixerStatusCallback;
    uint32_t _amountOf10MsBetweenCallbacks;
    uint32_t _amountOf10MsUntilNextCallback;
    bool _mixerStatusCb;

    // The current sample frequency and sample size when mixing.
    Frequency _outputFrequency;
    uint16_t _sampleSize;

    // Memory pool to avoid allocating/deallocating AudioFrames
    MemoryPool<AudioFrame>* _audioFramePool;

    // List of all participants. Note all lists are disjunct
    MixerParticipantList _participantList;              // May be mixed.
    // Always mixed, anonomously.
    MixerParticipantList _additionalParticipantList;

    size_t _numMixedParticipants;
    // Determines if we will use a limiter for clipping protection during
    // mixing.
    bool use_limiter_;

    uint32_t _timeStamp;

    // Metronome class.
    TimeScheduler _timeScheduler;

    // Smooth level indicator.
    LevelIndicator _mixedAudioLevel;

    // Counter keeping track of concurrent calls to process.
    // Note: should never be higher than 1 or lower than 0.
    int16_t _processCalls;

    // Used for inhibiting saturation in mixing.
    scoped_ptr<AudioProcessing> _limiter;
};
}  // namespace webrtc

#endif // WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_