@@ -13,7 +13,7 @@ using namespace std::chrono_literals;
1313
1414AudioPort::AudioPort (QAudioDevice device) : m_device(device)
1515{
16- m_idleTimer.setInterval (1s );
16+ m_idleTimer.setInterval (10s );
1717 connect (&m_idleTimer, &QTimer::timeout, this , &AudioPort::stopIO);
1818
1919 connect (this , &AudioPort::startIdleTimer, this ,
@@ -168,6 +168,11 @@ void AudioPort::startSinkIO()
168168{
169169 m_idleTimer.stop ();
170170
171+ if (m_isDraining && !m_sink.isNull ()) {
172+ m_isDraining = false ;
173+ return ;
174+ }
175+
171176 if (!m_sink.isNull ()) {
172177 stopSinkIO ();
173178 }
@@ -191,17 +196,25 @@ void AudioPort::startSinkIO()
191196void AudioPort::stopSinkIO ()
192197{
193198 m_idleTimer.stop ();
199+ if (m_sink.isNull () || m_isDraining) {
200+ return ;
201+ }
194202
195- if (m_sink) {
196- writeSilenceMS (SILENCE_BUFFER_MS );
203+ writeSilenceMS (SILENCE_BUFFER_MS );
197204
198- m_sink->stop ();
199- m_sink->deleteLater ();
200- m_sink = nullptr ;
201- m_io = nullptr ;
202- }
205+ m_isDraining = true ;
206+ QTimer::singleShot (SILENCE_BUFFER_MS + 200 , this , [this ]() {
207+ m_isDraining = false ;
203208
204- Q_EMIT audioSinkChanged ();
209+ if (m_sink) {
210+ m_sink->stop ();
211+ m_sink->deleteLater ();
212+ m_sink = nullptr ;
213+ m_io = nullptr ;
214+ }
215+
216+ Q_EMIT audioSinkChanged ();
217+ });
205218}
206219
207220void AudioPort::startSourceIO ()
@@ -267,6 +280,11 @@ void AudioPort::onFrameRequested(pj::MediaFrame &frame)
267280 return ;
268281 }
269282
283+ if (m_isWarmingUp) {
284+ m_isWarmingUp = false ;
285+ QObject::disconnect (m_warmUpDrain);
286+ }
287+
270288 auto bytes = m_io->read (frame.size );
271289
272290 if (!m_isMuted) {
@@ -297,8 +315,50 @@ void AudioPort::onFrameReceived(pj::MediaFrame &frame)
297315 return ;
298316 }
299317
318+ m_isWarmingUp = false ;
319+
300320 m_io->write (reinterpret_cast <char *>(frame.buf .data ()), frame.size );
301321
302322 // Auto destroy sink after timeout
303323 Q_EMIT startIdleTimer ();
304324}
325+
326+ void AudioPort::acquire ()
327+ {
328+ if (m_device.mode () == QAudioDevice::Mode::Input) {
329+ if (m_source.isNull ()) {
330+ startSourceIO ();
331+ }
332+ } else {
333+ if (m_sink.isNull ()) {
334+ startSinkIO ();
335+ }
336+ }
337+
338+ m_isWarmingUp = true ;
339+
340+ if (m_device.mode () == QAudioDevice::Mode::Input && !m_io.isNull ()) {
341+ QObject::disconnect (m_warmUpDrain);
342+
343+ m_warmUpDrain = connect (m_io.data (), &QIODevice::readyRead, this , [this ]() {
344+ if (m_isWarmingUp && !m_io.isNull ()) {
345+ m_io->readAll ();
346+ }
347+ });
348+ }
349+ }
350+
351+ void AudioPort::release ()
352+ {
353+ if (!m_isWarmingUp) {
354+ return ;
355+ }
356+
357+ m_isWarmingUp = false ;
358+
359+ QObject::disconnect (m_warmUpDrain);
360+
361+ if (!m_idleTimer.isActive ()) {
362+ stopIO ();
363+ }
364+ }
0 commit comments