-
Notifications
You must be signed in to change notification settings - Fork 26
/
AudioInput.cpp
152 lines (140 loc) · 3.41 KB
/
AudioInput.cpp
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
#include "AudioInput.h"
#include "netheader.h"
#include <QAudioFormat>
#include <QDebug>
#include <QThread>
extern QUEUE_DATA<MESG> queue_send;
extern QUEUE_DATA<MESG> queue_recv;
AudioInput::AudioInput(QObject *parent)
: QObject(parent)
{
recvbuf = (char*)malloc(MB * 2);
QAudioFormat format;
//set format
format.setSampleRate(8000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(format))
{
qWarning() << "Default format not supported, trying to use the nearest.";
format = info.nearestFormat(format);
}
audio = new QAudioInput(format, this);
connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
}
AudioInput::~AudioInput()
{
delete audio;
}
void AudioInput::startCollect()
{
if (audio->state() == QAudio::ActiveState) return;
WRITE_LOG("start collecting audio");
inputdevice = audio->start();
connect(inputdevice, SIGNAL(readyRead()), this, SLOT(onreadyRead()));
}
void AudioInput::stopCollect()
{
if (audio->state() == QAudio::StoppedState) return;
disconnect(this, SLOT(onreadyRead()));
audio->stop();
WRITE_LOG("stop collecting audio");
inputdevice = nullptr;
}
void AudioInput::onreadyRead()
{
static int num = 0, totallen = 0;
if (inputdevice == nullptr) return;
int len = inputdevice->read(recvbuf + totallen, 2 * MB - totallen);
if (num < 2)
{
totallen += len;
num++;
return;
}
totallen += len;
qDebug() << "totallen = " << totallen;
MESG* msg = (MESG*)malloc(sizeof(MESG));
if (msg == nullptr)
{
qWarning() << __LINE__ << "malloc fail";
}
else
{
memset(msg, 0, sizeof(MESG));
msg->msg_type = AUDIO_SEND;
//ѹËõÊý¾Ý£¬×ªbase64
QByteArray rr(recvbuf, totallen);
QByteArray cc = qCompress(rr).toBase64();
msg->len = cc.size();
msg->data = (uchar*)malloc(msg->len);
if (msg->data == nullptr)
{
qWarning() << "malloc mesg.data fail";
}
else
{
memset(msg->data, 0, msg->len);
memcpy_s(msg->data, msg->len, cc.data(), cc.size());
queue_send.push_msg(msg);
}
}
totallen = 0;
num = 0;
}
QString AudioInput::errorString()
{
if (audio->error() == QAudio::OpenError)
{
return QString("AudioInput An error occurred opening the audio device").toUtf8();
}
else if (audio->error() == QAudio::IOError)
{
return QString("AudioInput An error occurred during read/write of audio device").toUtf8();
}
else if (audio->error() == QAudio::UnderrunError)
{
return QString("AudioInput Audio data is not being fed to the audio device at a fast enough rate").toUtf8();
}
else if (audio->error() == QAudio::FatalError)
{
return QString("AudioInput A non-recoverable error has occurred, the audio device is not usable at this time.");
}
else
{
return QString("AudioInput No errors have occurred").toUtf8();
}
}
void AudioInput::handleStateChanged(QAudio::State newState)
{
switch (newState)
{
case QAudio::StoppedState:
if (audio->error() != QAudio::NoError)
{
stopCollect();
emit audioinputerror(errorString());
}
else
{
qWarning() << "stop recording";
}
break;
case QAudio::ActiveState:
//start recording
qWarning() << "start recording";
break;
default:
//
break;
}
}
void AudioInput::setVolumn(int v)
{
qDebug() << v;
audio->setVolume(v / 100.0);
}