aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.h
blob: bc9a27e9f0ca0aa1ef9e9ed97c27d44373a29db4 (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
/*
 *  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/base/scoped_ptr.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.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"

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();

    // Returns true if the participant is being mixed.
    bool IsMixed() const;

    // Returns true if the participant was mixed previous mix
    // iteration.
    bool WasMixed() const;

    // Updates the mixed status.
    int32_t SetIsMixed(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
    int64_t TimeUntilNextProcess() override;
    int32_t Process() override;

    // AudioConferenceMixer functions
    int32_t RegisterMixedStreamCallback(
        AudioMixerOutputReceiver* mixReceiver) override;
    int32_t UnRegisterMixedStreamCallback() override;
    int32_t SetMixabilityStatus(MixerParticipant* participant,
                                bool mixable) override;
    bool MixabilityStatus(const MixerParticipant& participant) const override;
    int32_t SetMinimumMixingFrequency(Frequency freq) override;
    int32_t SetAnonymousMixabilityStatus(
        MixerParticipant* participant, bool mixable) override;
    bool AnonymousMixabilityStatus(
        const MixerParticipant& participant) const override;

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.
    // 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) const;

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

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

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

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

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

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

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

    // Mix the AudioFrames stored in audioFrameList into mixedAudio.
    int32_t MixFromList(AudioFrame* mixedAudio,
                        const AudioFrameList& audioFrameList) const;

    // 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) const;

    bool LimitMixedAudio(AudioFrame* mixedAudio) const;

    rtc::scoped_ptr<CriticalSectionWrapper> _crit;
    rtc::scoped_ptr<CriticalSectionWrapper> _cbCrit;

    int32_t _id;

    Frequency _minimumMixingFreq;

    // Mix result callback
    AudioMixerOutputReceiver* _mixReceiver;

    // The current sample frequency and sample size when mixing.
    Frequency _outputFrequency;
    size_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;

    // 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.
    rtc::scoped_ptr<AudioProcessing> _limiter;
};
}  // namespace webrtc

#endif // WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_