/
AudioInput.h
179 lines (143 loc) · 4.81 KB
/
AudioInput.h
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
// Copyright 2005-2018 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_MUMBLE_AUDIOINPUT_H_
#define MUMBLE_MUMBLE_AUDIOINPUT_H_
#include <boost/shared_ptr.hpp>
#include <boost/array.hpp>
#include <speex/speex.h>
#include <speex/speex_echo.h>
#include <speex/speex_preprocess.h>
#include <speex/speex_resampler.h>
#include <QtCore/QObject>
#include <QtCore/QThread>
#include <vector>
#include "Audio.h"
#include "Settings.h"
#include "Timer.h"
#include "Message.h"
class AudioInput;
class CELTCodec;
class OpusCodec;
struct CELTEncoder;
struct OpusEncoder;
typedef boost::shared_ptr<AudioInput> AudioInputPtr;
class AudioInputRegistrar {
private:
Q_DISABLE_COPY(AudioInputRegistrar)
public:
static QMap<QString, AudioInputRegistrar *> *qmNew;
static QString current;
static AudioInputPtr newFromChoice(QString choice = QString());
const QString name;
int priority;
AudioInputRegistrar(const QString &n, int priority = 0);
virtual ~AudioInputRegistrar();
virtual AudioInput *create() = 0;
virtual const QList<audioDevice> getDeviceChoices() = 0;
virtual void setDeviceChoice(const QVariant &, Settings &) = 0;
virtual bool canEcho(const QString &outputsys) const = 0;
virtual bool canExclusive() const;
};
class AudioInput : public QThread {
friend class AudioNoiseWidget;
friend class AudioEchoWidget;
friend class AudioStats;
friend class AudioInputDialog;
private:
Q_OBJECT
Q_DISABLE_COPY(AudioInput)
protected:
typedef enum { CodecCELT, CodecSpeex } CodecFormat;
typedef enum { SampleShort, SampleFloat } SampleFormat;
typedef void (*inMixerFunc)(float * RESTRICT, const void * RESTRICT, unsigned int, unsigned int, quint64);
private:
SpeexResamplerState *srsMic, *srsEcho;
QMutex qmEcho;
QList<short *> qlEchoFrames;
unsigned int iJitterSeq;
int iMinBuffered;
unsigned int iMicFilled, iEchoFilled;
inMixerFunc imfMic, imfEcho;
inMixerFunc chooseMixer(const unsigned int nchan, SampleFormat sf, quint64 mask);
void resetAudioProcessor();
OpusCodec *oCodec;
OpusEncoder *opusState;
bool selectCodec();
typedef boost::array<unsigned char, 960> EncodingOutputBuffer;
int encodeOpusFrame(short *source, int size, EncodingOutputBuffer& buffer);
int encodeCELTFrame(short *pSource, EncodingOutputBuffer& buffer);
protected:
MessageHandler::UDPMessageType umtType;
SampleFormat eMicFormat, eEchoFormat;
unsigned int iSampleRate;
unsigned int iMicChannels, iEchoChannels;
unsigned int iMicFreq, iEchoFreq;
unsigned int iMicLength, iEchoLength;
unsigned int iMicSampleSize, iEchoSampleSize;
unsigned int iEchoMCLength, iEchoFrameSize;
quint64 uiMicChannelMask, uiEchoChannelMask;
bool bEchoMulti;
int iFrameSize;
QMutex qmSpeex;
SpeexPreprocessState *sppPreprocess;
SpeexEchoState *sesEcho;
CELTCodec *cCodec;
CELTEncoder *ceEncoder;
/// bResetEncoder is a flag that notifies
/// our encoder functions that the encoder
/// needs to be reset.
bool bResetEncoder;
/// Encoded audio rate in bit/s
int iAudioQuality;
/// Number of 10ms audio "frames" per packet (!= frames in packet)
int iAudioFrames;
short *psMic;
short *psSpeaker;
short *psClean;
float *pfMicInput;
float *pfEchoInput;
float *pfOutput;
std::vector<short> opusBuffer;
void encodeAudioFrame();
void addMic(const void *data, unsigned int nsamp);
void addEcho(const void *data, unsigned int nsamp);
volatile bool bRunning;
volatile bool bPreviousVoice;
int iFrameCounter;
int iSilentFrames;
int iHoldFrames;
int iBufferedFrames;
QList<QByteArray> qlFrames;
void flushCheck(const QByteArray &, bool terminator);
void initializeMixer();
static void adjustBandwidth(int bitspersec, int &bitrate, int &frames);
signals:
void doDeaf();
void doMute();
public:
typedef enum { ActivityStateIdle, ActivityStateReturnedFromIdle, ActivityStateActive } ActivityState;
ActivityState activityState;
bool bResetProcessor;
Timer tIdle;
int iBitrate;
float dPeakSpeaker, dPeakSignal, dMaxMic, dPeakMic, dPeakCleanMic;
float fSpeechProb;
static int getNetworkBandwidth(int bitrate, int frames);
static void setMaxBandwidth(int bitspersec);
/// Construct an AudioInput.
///
/// This constructor is only ever called by Audio::startInput(), and is guaranteed
/// to be called on the application's main thread.
AudioInput();
/// Destroy an AudioInput.
///
/// This destructor is only ever called by Audio::stopInput() and Audio::stop(),
/// and is guaranteed to be called on the application's main thread.
~AudioInput() Q_DECL_OVERRIDE;
void run() Q_DECL_OVERRIDE = 0;
virtual bool isAlive() const;
bool isTransmitting() const;
};
#endif