6#include <private/qaudiohelpers_p.h>
16 m_state(QAudio::StoppedState),
18 m_elapsedTimeOffset(0),
34 if (m_state != QAudio::StoppedState)
37 if (!m_pullMode && m_audioSource)
41 m_audioSource = device;
44 changeState(QAudio::ActiveState, QAudio::NoError);
46 changeState(QAudio::StoppedState, QAudio::OpenError);
51 if (m_state != QAudio::StoppedState)
54 if (!m_pullMode && m_audioSource)
58 m_audioSource =
new InputPrivate(
this);
59 m_audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
62 changeState(QAudio::IdleState, QAudio::NoError);
67 changeState(QAudio::StoppedState, QAudio::OpenError);
75 if (m_state == QAudio::StoppedState)
78 changeState(QAudio::StoppedState, QAudio::NoError);
90 if (m_state == QAudio::StoppedState)
93 snd_pcm_capture_pause(m_pcmHandle.get());
96 m_pcmNotifier->setEnabled(
false);
98 changeState(QAudio::SuspendedState, QAudio::NoError);
103 if (m_state == QAudio::StoppedState)
106 snd_pcm_capture_resume(m_pcmHandle.get());
109 m_pcmNotifier->setEnabled(
true);
112 changeState(QAudio::ActiveState, QAudio::NoError);
114 changeState(QAudio::IdleState, QAudio::NoError);
119 return qMax(m_bytesAvailable, 0);
124 m_bufferSize = bufferSize;
134 return qint64(1000000) * m_format.framesForBytes(m_bytesRead) / m_format.sampleRate();
144 if (m_state == QAudio::StoppedState || m_state == QAudio::SuspendedState)
156 m_bytesAvailable = m_periodSize;
159 if (m_audioSource != 0) {
160 InputPrivate *input = qobject_cast<InputPrivate*>(m_audioSource);
165 if (m_state != QAudio::ActiveState)
173 m_pcmHandle = QnxAudioUtils::openPcmDevice(m_audioDevice.id(), QAudioDevice::Input);
181 snd_pcm_plugin_set_disable(m_pcmHandle.get(), PLUGIN_MMAP);
183 const std::optional<snd_pcm_channel_info_t> info = QnxAudioUtils::pcmChannelInfo(
184 m_pcmHandle.get(), QAudioDevice::Input);
191 snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(m_format,
192 QAudioDevice::Input, info->max_fragment_size);
194 if ((errorCode = snd_pcm_plugin_params(m_pcmHandle.get(), ¶ms)) < 0) {
195 qWarning(
"QQnxAudioSource: open error, couldn't set channel params (0x%x)", -errorCode);
200 if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle.get(), SND_PCM_CHANNEL_CAPTURE)) < 0) {
201 qWarning(
"QQnxAudioSource: open error, couldn't prepare channel (0x%x)", -errorCode);
206 const std::optional<snd_pcm_channel_setup_t> setup = QnxAudioUtils::pcmChannelSetup(
207 m_pcmHandle.get(), QAudioDevice::Input);
209 m_periodSize = qMin(2048, setup->buf.block.frag_size);
211 m_elapsedTimeOffset = 0;
212 m_totalTimeValue = 0;
215 m_pcmNotifier =
new QSocketNotifier(snd_pcm_file_descriptor(m_pcmHandle.get(), SND_PCM_CHANNEL_CAPTURE),
216 QSocketNotifier::Read,
this);
217 connect(m_pcmNotifier, SIGNAL(activated(QSocketDescriptor)),
this, SLOT(userFeed()));
225#if SND_PCM_VERSION < SND_PROTOCOL_VERSION('P',3
,0
,2
)
226 snd_pcm_plugin_flush(m_pcmHandle.get(), SND_PCM_CHANNEL_CAPTURE);
228 snd_pcm_plugin_drop(m_pcmHandle.get(), SND_PCM_CHANNEL_CAPTURE);
230 m_pcmHandle =
nullptr;
234 delete m_pcmNotifier;
238 if (!m_pullMode && m_audioSource) {
239 delete m_audioSource;
246 if (!m_pullMode && m_bytesAvailable == 0)
250 QByteArray tempBuffer(m_periodSize, 0);
252 const int actualRead = snd_pcm_plugin_read(m_pcmHandle.get(), tempBuffer.data(), m_periodSize);
253 if (actualRead < 1) {
254 snd_pcm_channel_status_t status;
255 memset(&status, 0,
sizeof(status));
256 status.channel = SND_PCM_CHANNEL_CAPTURE;
257 if ((errorCode = snd_pcm_plugin_status(m_pcmHandle.get(), &status)) < 0) {
258 qWarning(
"QQnxAudioSource: read error, couldn't get plugin status (0x%x)", -errorCode);
260 changeState(QAudio::StoppedState, QAudio::FatalError);
264 if (status.status == SND_PCM_STATUS_READY
265 || status.status == SND_PCM_STATUS_OVERRUN) {
266 if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle.get(), SND_PCM_CHANNEL_CAPTURE)) < 0) {
267 qWarning(
"QQnxAudioSource: read error, couldn't prepare plugin (0x%x)", -errorCode);
269 changeState(QAudio::StoppedState, QAudio::FatalError);
274 changeState(QAudio::ActiveState, QAudio::NoError);
278 QAudioHelperInternal::qMultiplySamples(volume(), m_format, tempBuffer.data(),
279 tempBuffer.data(), actualRead);
281 m_bytesRead += actualRead;
284 m_audioSource->write(tempBuffer.data(), actualRead);
286 memcpy(data, tempBuffer.data(), qMin(
static_cast<qint64>(actualRead), len));
289 m_bytesAvailable = 0;
294void QQnxAudioSource::changeState(QAudio::State state, QAudio::Error error)
296 if (m_state != state) {
298 emit stateChanged(state);
305 : m_audioDevice(audio)
311 return m_audioDevice->read(data, len);
323 return m_audioDevice->m_bytesAvailable + QIODevice::bytesAvailable();
The QAudioDevice class provides an information about audio devices and their functionality.
qsizetype bytesReady() const override
QAudio::State state() const override
QIODevice * start() override
void setBufferSize(qsizetype) override
qsizetype bufferSize() const override
qint64 processedUSecs() const override
void start(QIODevice *) override