summaryrefslogtreecommitdiffstats
path: root/src/multimedia/pulseaudio/qpulseaudiosink_p.h
blob: 2d7ff007b48d29662032be2955d7a65e87f3645f (plain)
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
// 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 QPULSEAUDIOSINK_P_H
#define QPULSEAUDIOSINK_P_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 <QtCore/qtclasshelpermacros.h>

#include <QtMultimedia/qaudio.h>
#include <QtMultimedia/qaudiodevice.h>
#include <QtMultimedia/private/qaudio_platform_implementation_support_p.h>
#include <QtMultimedia/private/qaudiosystem_p.h>
#include <QtMultimedia/private/qpulsehelpers_p.h>

QT_BEGIN_NAMESPACE

namespace QPulseAudioInternal {

using namespace QtMultimediaPrivate;
class QPulseAudioSink;

struct QPulseAudioSinkStream final : QPlatformAudioSinkStream
{
    using SinkType = QPulseAudioSink;

    QPulseAudioSinkStream(QAudioDevice, const QAudioFormat &format,
                          std::optional<qsizetype> ringbufferSize, QPulseAudioSink *parent,
                          float volume, std::optional<int32_t> hardwareBufferSize,
                          AudioEndpointRole);
    ~QPulseAudioSinkStream();

    using QPlatformAudioSinkStream::bytesFree;
    using QPlatformAudioSinkStream::processedDuration;
    using QPlatformAudioSinkStream::ringbufferSizeInBytes;
    using QPlatformAudioSinkStream::setVolume;

    bool start(QIODevice *device);
    bool start(AudioCallback &&);
    QIODevice *start();
    void stop(ShutdownPolicy);
    void stop() { stop(ShutdownPolicy::DrainRingbuffer); }
    void reset() { stop(ShutdownPolicy::DiscardRingbuffer); }
    void suspend();
    void resume();

    bool open() const;

private:
    enum class StreamType : uint8_t
    {
        Ringbuffer,
        Callback,
    };

    void installCallbacks(StreamType);
    void uninstallCallbacks();

    bool startStream(StreamType);

    void updateStreamIdle(bool) override;

    // PulseAudio callbacks
    void underflowCallback() { }
    void overflowCallback() { }
    void stateCallback() { }
    void writeCallbackRingbuffer(size_t requestedBytes);
    void writeCallbackAudioCallback(size_t requestedBytes);
    void latencyUpdateCallback() { }

    QPulseAudioSink *m_parent;
    PAStreamHandle m_stream;

    std::optional<AudioCallback> m_audioCallback;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class QPulseAudioSink final
    : public QPlatformAudioSinkImplementation<QPulseAudioSinkStream, QPulseAudioSink>
{
    using BaseClass = QPlatformAudioSinkImplementation<QPulseAudioSinkStream, QPulseAudioSink>;

public:
    QPulseAudioSink(QAudioDevice, const QAudioFormat &, QObject *parent);

    void start(QIODevice *device) override;
    QIODevice *start() override;
    void start(AudioCallback &&) override;

private:
    bool validatePulseaudio();
};

} // namespace QPulseAudioInternal

QT_END_NAMESPACE

#endif // QPULSEAUDIOSINK_P_H