// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QOPENSLESAUDIOOUTPUT_H #define QOPENSLESAUDIOOUTPUT_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include #include #include QT_BEGIN_NAMESPACE class QAndroidAudioSink : public QPlatformAudioSink { Q_OBJECT public: QAndroidAudioSink(QAudioDevice device, const QAudioFormat &, QObject *parent); ~QAndroidAudioSink(); void start(QIODevice *device) override; QIODevice *start() override; void stop() override; void reset() override; void suspend() override; void resume() override; qsizetype bytesFree() const override; void setBufferSize(qsizetype value) override; qsizetype bufferSize() const override; qint64 processedUSecs() const override; QAudio::State state() const override; void setVolume(float volume) override; private: friend class SLIODevicePrivate; Q_INVOKABLE void onEOSEvent(); Q_INVOKABLE void onBytesProcessed(qint64 bytes); Q_INVOKABLE void bufferAvailable(); static void playCallback(SLPlayItf playItf, void *ctx, SLuint32 event); static void bufferQueueCallback(SLBufferQueueItf bufferQueue, void *ctx); bool preparePlayer(); void destroyPlayer(); void stopPlayer(); void readyRead(); void startPlayer(); qint64 writeData(const char *data, qint64 len); void setState(QAudio::State state); SLmillibel adjustVolume(float vol); static constexpr int BufferCount = 4; QAudio::State m_state = QAudio::StoppedState; QAudio::State m_suspendedInState = QAudio::SuspendedState; SLObjectItf m_outputMixObject = nullptr; SLObjectItf m_playerObject = nullptr; SLPlayItf m_playItf = nullptr; SLVolumeItf m_volumeItf = nullptr; SLBufferQueueItf m_bufferQueueItf = nullptr; QIODevice *m_audioSource = nullptr; char *m_buffers = nullptr; bool m_pullMode = false; int m_nextBuffer = 0; int m_bufferSize = 0; qint64 m_elapsedTime = 0; qint64 m_processedBytes = 0; bool m_endSound = false; QAtomicInt m_availableBuffers = BufferCount; SLuint32 m_eventMask = SL_PLAYEVENT_HEADATEND; bool m_startRequiresInit = true; qint32 m_streamType; }; class SLIODevicePrivate : public QIODevice { Q_OBJECT public: inline SLIODevicePrivate(QAndroidAudioSink *audio) : m_audioDevice(audio) {} inline ~SLIODevicePrivate() override {} protected: inline qint64 readData(char *, qint64) override { return 0; } inline qint64 writeData(const char *data, qint64 len) override; private: QAndroidAudioSink *m_audioDevice; }; qint64 SLIODevicePrivate::writeData(const char *data, qint64 len) { Q_ASSERT(m_audioDevice); return m_audioDevice->writeData(data, len); } QT_END_NAMESPACE #endif // QOPENSLESAUDIOOUTPUT_H