1
1
#include < QTcpSocket>
2
2
#include < QHostAddress>
3
- #include < QAudioOutput >
4
- #include < QTime >
3
+ #include < QAudioSink >
4
+ #include < QMediaDevices >
5
5
#include < QElapsedTimer>
6
-
6
+ #include < QProcess>
7
+ #include < QThread>
8
+ #include < QDebug>
9
+ #include < QByteArray>
7
10
#include " audiooutput.h"
8
11
9
12
AudioOutput::AudioOutput (QObject *parent)
10
13
: QObject(parent)
14
+ , m_outputDevice(nullptr )
15
+ , m_running(false )
16
+ , m_audioSink(nullptr )
11
17
{
12
18
connect (&m_sndcpy, &QProcess::readyReadStandardOutput, this , [this ]() {
13
- qInfo () << QString (" AudioOutput::" ) << QString ( m_sndcpy.readAllStandardOutput () );
19
+ qInfo () << QString (" AudioOutput::" ) << m_sndcpy.readAllStandardOutput ();
14
20
});
15
21
connect (&m_sndcpy, &QProcess::readyReadStandardError, this , [this ]() {
16
- qInfo () << QString (" AudioOutput::" ) << QString ( m_sndcpy.readAllStandardError () );
22
+ qInfo () << QString (" AudioOutput::" ) << m_sndcpy.readAllStandardError ();
17
23
});
18
24
}
19
25
20
26
AudioOutput::~AudioOutput ()
21
27
{
22
- if (QProcess::NotRunning != m_sndcpy.state ()) {
28
+ if (m_sndcpy.state () != QProcess::NotRunning ) {
23
29
m_sndcpy.kill ();
24
30
}
25
31
stop ();
26
32
}
27
33
28
- bool AudioOutput::start (const QString& serial, int port)
34
+ bool AudioOutput::start (const QString & serial, int port)
29
35
{
30
36
if (m_running) {
31
37
stop ();
@@ -36,7 +42,7 @@ bool AudioOutput::start(const QString& serial, int port)
36
42
bool ret = runSndcpyProcess (serial, port);
37
43
qInfo () << " AudioOutput::run sndcpy cost:" << timeConsumeCount.elapsed () << " milliseconds" ;
38
44
if (!ret) {
39
- return ret ;
45
+ return false ;
40
46
}
41
47
42
48
startAudioOutput ();
@@ -64,20 +70,15 @@ void AudioOutput::installonly(const QString &serial, int port)
64
70
65
71
bool AudioOutput::runSndcpyProcess (const QString &serial, int port, bool wait)
66
72
{
67
- if (QProcess::NotRunning != m_sndcpy.state ()) {
73
+ if (m_sndcpy.state () != QProcess::NotRunning ) {
68
74
m_sndcpy.kill ();
69
75
}
70
76
71
77
#ifdef Q_OS_WIN32
72
- QStringList params;
73
- params << serial;
74
- params << QString (" %1" ).arg (port);
78
+ QStringList params{serial, QString::number (port)};
75
79
m_sndcpy.start (" sndcpy.bat" , params);
76
80
#else
77
- QStringList params;
78
- params << " sndcpy.sh" ;
79
- params << serial;
80
- params << QString (" %1" ).arg (port);
81
+ QStringList params{" sndcpy.sh" , serial, QString::number (port)};
81
82
m_sndcpy.start (" bash" , params);
82
83
#endif
83
84
@@ -86,11 +87,11 @@ bool AudioOutput::runSndcpyProcess(const QString &serial, int port, bool wait)
86
87
}
87
88
88
89
if (!m_sndcpy.waitForStarted ()) {
89
- qWarning () << " AudioOutput::start sndcpy.bat failed" ;
90
+ qWarning () << " AudioOutput::start sndcpy process failed" ;
90
91
return false ;
91
92
}
92
93
if (!m_sndcpy.waitForFinished ()) {
93
- qWarning () << " AudioOutput::sndcpy.bat crashed" ;
94
+ qWarning () << " AudioOutput::sndcpy process crashed" ;
94
95
return false ;
95
96
}
96
97
@@ -99,41 +100,39 @@ bool AudioOutput::runSndcpyProcess(const QString &serial, int port, bool wait)
99
100
100
101
void AudioOutput::startAudioOutput ()
101
102
{
102
- if (m_audioOutput ) {
103
+ if (m_audioSink ) {
103
104
return ;
104
105
}
105
106
106
107
QAudioFormat format;
107
108
format.setSampleRate (48000 );
108
109
format.setChannelCount (2 );
109
- format.setSampleSize (16 );
110
- format.setCodec (" audio/pcm" );
111
- format.setByteOrder (QAudioFormat::LittleEndian);
112
- format.setSampleType (QAudioFormat::SignedInt);
110
+ format.setSampleFormat (QAudioFormat::Int16); // 16-bit signed integer format
113
111
114
- QAudioDeviceInfo info ( QAudioDeviceInfo::defaultOutputDevice () );
115
- if (!info .isFormatSupported (format)) {
112
+ QAudioDevice defaultDevice = QMediaDevices::defaultAudioOutput ( );
113
+ if (!defaultDevice .isFormatSupported (format)) {
116
114
qWarning () << " AudioOutput::audio format not supported, cannot play audio." ;
117
115
return ;
118
116
}
119
117
120
- m_audioOutput = new QAudioOutput (format, this );
121
- connect (m_audioOutput, &QAudioOutput::stateChanged, this , [](QAudio::State state) {
122
- qInfo () << " AudioOutput::audio state changed:" << state;
123
- });
124
- m_audioOutput->setBufferSize (48000 *2 *15 /1000 * 20 );
125
- m_outputDevice = m_audioOutput->start ();
118
+ m_audioSink = new QAudioSink (defaultDevice, format, this );
119
+ m_outputDevice = m_audioSink->start ();
120
+ if (!m_outputDevice) {
121
+ qWarning () << " AudioOutput::failed to start audio sink." ;
122
+ delete m_audioSink;
123
+ m_audioSink = nullptr ;
124
+ return ;
125
+ }
126
126
}
127
127
128
128
void AudioOutput::stopAudioOutput ()
129
129
{
130
- if (!m_audioOutput) {
131
- return ;
130
+ if (m_audioSink) {
131
+ m_audioSink->stop ();
132
+ delete m_audioSink;
133
+ m_audioSink = nullptr ;
132
134
}
133
-
134
- m_audioOutput->stop ();
135
- delete m_audioOutput;
136
- m_audioOutput = nullptr ;
135
+ m_outputDevice = nullptr ;
137
136
}
138
137
139
138
void AudioOutput::startRecvData (int port)
@@ -156,7 +155,6 @@ void AudioOutput::startRecvData(int port)
156
155
});
157
156
connect (audioSocket, &QIODevice::readyRead, audioSocket, [this , audioSocket]() {
158
157
qint64 recv = audioSocket->bytesAvailable ();
159
- // qDebug() << "AudioOutput::recv data:" << recv;
160
158
161
159
if (!m_outputDevice) {
162
160
return ;
@@ -165,22 +163,16 @@ void AudioOutput::startRecvData(int port)
165
163
m_buffer.reserve (recv);
166
164
}
167
165
168
- qint64 count = audioSocket->read (m_buffer.data (), audioSocket-> bytesAvailable () );
166
+ qint64 count = audioSocket->read (m_buffer.data (), recv );
169
167
m_outputDevice->write (m_buffer.data (), count);
170
168
});
171
169
connect (audioSocket, &QTcpSocket::stateChanged, audioSocket, [](QAbstractSocket::SocketState state) {
172
170
qInfo () << " AudioOutput::audio socket state changed:" << state;
173
-
174
171
});
175
- # if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
172
+
176
173
connect (audioSocket, &QTcpSocket::errorOccurred, audioSocket, [](QAbstractSocket::SocketError error) {
177
174
qInfo () << " AudioOutput::audio socket error occurred:" << error;
178
175
});
179
- #else
180
- connect (audioSocket, QOverload<QAbstractSocket::SocketError>::of (&QAbstractSocket::error), audioSocket, [](QAbstractSocket::SocketError error) {
181
- qInfo () << " AudioOutput::audio socket error occurred:" << error;
182
- });
183
- #endif
184
176
185
177
m_workerThread.start ();
186
178
emit connectTo (port);
0 commit comments