1 /* Webcamoid, webcam capture application.
2  * Copyright (C) 2016  Gonzalo Exequiel Pedone
3  *
4  * Webcamoid is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Webcamoid is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Web-Site: http://webcamoid.github.io/
18  */
19 
20 #ifndef AKAUDIOCAPS_H
21 #define AKAUDIOCAPS_H
22 
23 #include <QObject>
24 
25 #include "akcommons.h"
26 
27 class AkAudioCapsPrivate;
28 class AkCaps;
29 
30 class AKCOMMONS_EXPORT AkAudioCaps: public QObject
31 {
32     Q_OBJECT
33     Q_ENUMS(SampleFormat)
34     Q_ENUMS(SampleType)
35     Q_ENUMS(Position)
36     Q_ENUMS(ChannelLayout)
37     Q_PROPERTY(SampleFormat format
38                READ format
39                WRITE setFormat
40                RESET resetFormat
41                NOTIFY formatChanged)
42     Q_PROPERTY(ChannelLayout layout
43                READ layout
44                WRITE setLayout
45                RESET resetLayout
46                NOTIFY layoutChanged)
47     Q_PROPERTY(int bps
48                READ bps)
49     Q_PROPERTY(int channels
50                READ channels)
51     Q_PROPERTY(int rate
52                READ rate
53                WRITE setRate
54                RESET resetRate
55                NOTIFY rateChanged)
56     Q_PROPERTY(int samples
57                READ samples
58                WRITE setSamples
59                RESET resetSamples
60                NOTIFY samplesChanged)
61     Q_PROPERTY(size_t frameSize
62                READ frameSize)
63     Q_PROPERTY(bool planar
64                READ planar)
65     Q_PROPERTY(int planes
66                READ planes)
67     Q_PROPERTY(QVector<size_t> planeSize
68                READ planeSize
69                WRITE setPlaneSize
70                RESET resetPlaneSize
71                NOTIFY planeSizeChanged)
72 
73     public:
74         enum SampleFormat
75         {
76             SampleFormat_none = -1,
77             SampleFormat_s8,
78             SampleFormat_u8,
79             SampleFormat_s16le,
80             SampleFormat_s16be,
81             SampleFormat_u16le,
82             SampleFormat_u16be,
83             SampleFormat_s32le,
84             SampleFormat_s32be,
85             SampleFormat_u32le,
86             SampleFormat_u32be,
87             SampleFormat_s64le,
88             SampleFormat_s64be,
89             SampleFormat_u64le,
90             SampleFormat_u64be,
91             SampleFormat_fltle,
92             SampleFormat_fltbe,
93             SampleFormat_dblle,
94             SampleFormat_dblbe,
95 
96 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
97             SampleFormat_s16 = SampleFormat_s16le,
98             SampleFormat_u16 = SampleFormat_u16le,
99             SampleFormat_s32 = SampleFormat_s32le,
100             SampleFormat_u32 = SampleFormat_u32le,
101             SampleFormat_s64 = SampleFormat_s64le,
102             SampleFormat_u64 = SampleFormat_u64le,
103             SampleFormat_flt = SampleFormat_fltle,
104             SampleFormat_dbl = SampleFormat_dblle,
105 #else
106             SampleFormat_s16 = SampleFormat_s16be,
107             SampleFormat_u16 = SampleFormat_u16be,
108             SampleFormat_s32 = SampleFormat_s32be,
109             SampleFormat_u32 = SampleFormat_u32be,
110             SampleFormat_s64 = SampleFormat_s64be,
111             SampleFormat_u64 = SampleFormat_u64be,
112             SampleFormat_flt = SampleFormat_fltbe,
113             SampleFormat_dbl = SampleFormat_dblbe,
114 #endif
115         };
116 
117         enum SampleType
118         {
119             SampleType_unknown = -1,
120             SampleType_int,
121             SampleType_uint,
122             SampleType_float,
123         };
124 
125         enum Position
126         {
127             Position_unknown = -1,
128             Position_FrontCenter,
129             Position_FrontLeft,
130             Position_FrontRight,
131             Position_BackCenter,
132             Position_BackLeft,
133             Position_BackRight,
134             Position_FrontLeftOfCenter,
135             Position_FrontRightOfCenter,
136             Position_WideLeft,
137             Position_WideRight,
138             Position_SideLeft,
139             Position_SideRight,
140             Position_LowFrequency1,
141             Position_LowFrequency2,
142             Position_TopCenter,
143             Position_TopFrontCenter,
144             Position_TopFrontLeft,
145             Position_TopFrontRight,
146             Position_TopBackCenter,
147             Position_TopBackLeft,
148             Position_TopBackRight,
149             Position_TopSideLeft,
150             Position_TopSideRight,
151             Position_BottomFrontCenter,
152             Position_BottomFrontLeft,
153             Position_BottomFrontRight,
154             Position_StereoLeft,
155             Position_StereoRight,
156             Position_SurroundDirectLeft,
157             Position_SurroundDirectRight,
158         };
159 
160         enum ChannelLayout
161         {
162             Layout_none = -1,
163             Layout_mono,
164             Layout_stereo,
165             Layout_downmix,
166             Layout_2p1,
167             Layout_3p0,
168             Layout_3p0_back,
169             Layout_3p1,
170             Layout_4p0,
171             Layout_quad,
172             Layout_quad_side,
173             Layout_4p1,
174             Layout_5p0,
175             Layout_5p0_side,
176             Layout_5p1,
177             Layout_5p1_side,
178             Layout_6p0,
179             Layout_6p0_front,
180             Layout_hexagonal,
181             Layout_6p1,
182             Layout_6p1_back,
183             Layout_6p1_front,
184             Layout_7p0,
185             Layout_7p0_front,
186             Layout_7p1,
187             Layout_7p1_wide,
188             Layout_7p1_wide_back,
189             Layout_octagonal,
190             Layout_hexadecagonal,
191         };
192 
193         using SpeakerPosition = QPair<qreal, qreal>;
194 
195         AkAudioCaps(QObject *parent=nullptr);
196         AkAudioCaps(SampleFormat format,
197                     ChannelLayout layout,
198                     int rate,
199                     int samples=0,
200                     bool planar=false,
201                     int align=1);
202         AkAudioCaps(SampleFormat format,
203                     ChannelLayout layout,
204                     int rate,
205                     int samples,
206                     const QVector<size_t> &planeSize);
207         AkAudioCaps(const AkCaps &caps);
208         AkAudioCaps(const AkAudioCaps &other);
209          ~AkAudioCaps();
210         AkAudioCaps &operator =(const AkAudioCaps &other);
211         AkAudioCaps &operator =(const AkCaps &caps);
212         bool operator ==(const AkAudioCaps &other) const;
213         bool operator !=(const AkAudioCaps &other) const;
214         operator bool() const;
215         operator AkCaps() const;
216 
217         Q_INVOKABLE SampleFormat format() const;
218         Q_INVOKABLE ChannelLayout layout() const;
219         Q_INVOKABLE int bps() const;
220         Q_INVOKABLE int channels() const;
221         Q_INVOKABLE int rate() const;
222         Q_INVOKABLE int &rate();
223         Q_INVOKABLE int samples() const;
224         Q_INVOKABLE size_t frameSize() const;
225         Q_INVOKABLE const QVector<Position> positions() const;
226 
227         Q_INVOKABLE QVariantMap toMap() const;
228         Q_INVOKABLE AkAudioCaps &update(const AkCaps &caps);
229         Q_INVOKABLE size_t planeOffset(int plane) const;
230         Q_INVOKABLE bool planar() const;
231         Q_INVOKABLE int planes() const;
232         Q_INVOKABLE QVector<size_t> planeSize() const;
233         Q_INVOKABLE size_t bytesPerPlane() const;
234         Q_INVOKABLE void realign(int align);
235         Q_INVOKABLE void updatePlaneSize(bool planar, int align=1);
236 
237         Q_INVOKABLE static AkAudioCaps fromMap(const QVariantMap &caps);
238         Q_INVOKABLE static int bitsPerSample(SampleFormat sampleFormat);
239         Q_INVOKABLE static int bitsPerSample(const QString &sampleFormat);
240         Q_INVOKABLE static QString sampleFormatToString(SampleFormat sampleFormat);
241         Q_INVOKABLE static SampleFormat sampleFormatFromString(const QString &sampleFormat);
242         Q_INVOKABLE static SampleFormat sampleFormatFromProperties(SampleType type,
243                                                                    int bps,
244                                                                    int endianness);
245         Q_INVOKABLE static bool sampleFormatProperties(SampleFormat sampleFormat,
246                                                        SampleType *type=nullptr,
247                                                        int *bps=nullptr,
248                                                        int *endianness=nullptr);
249         Q_INVOKABLE static bool sampleFormatProperties(const QString &sampleFormat,
250                                                        SampleType *type=nullptr,
251                                                        int *bps=nullptr,
252                                                        int *endianness=nullptr);
253         Q_INVOKABLE static SampleType sampleType(SampleFormat sampleFormat);
254         Q_INVOKABLE static SampleType sampleType(const QString &sampleFormat);
255         Q_INVOKABLE static QString channelLayoutToString(ChannelLayout channelLayout);
256         Q_INVOKABLE static ChannelLayout channelLayoutFromString(const QString &channelLayout);
257         Q_INVOKABLE static ChannelLayout channelLayoutFromPositions(const QVector<Position> &positions);
258         Q_INVOKABLE static int channelCount(ChannelLayout channelLayout);
259         Q_INVOKABLE static int channelCount(const QString &channelLayout);
260         Q_INVOKABLE static int endianness(SampleFormat sampleFormat);
261         Q_INVOKABLE static int endianness(const QString &sampleFormat);
262         Q_INVOKABLE static ChannelLayout defaultChannelLayout(int channelCount);
263         Q_INVOKABLE static QString defaultChannelLayoutString(int channelCount);
264         Q_INVOKABLE static const QVector<Position> &positions(ChannelLayout channelLayout);
265         Q_INVOKABLE static SpeakerPosition position(Position position);
266         Q_INVOKABLE SpeakerPosition position(int channel) const;
267 
268     private:
269         AkAudioCapsPrivate *d;
270 
271     Q_SIGNALS:
272         void formatChanged(SampleFormat format);
273         void layoutChanged(ChannelLayout layout);
274         void rateChanged(int rate);
275         void samplesChanged(int samples);
276         void planeSizeChanged(const QVector<size_t> &planeSize);
277 
278     public Q_SLOTS:
279         void setFormat(SampleFormat format);
280         void setLayout(ChannelLayout layout);
281         void setRate(int rate);
282         void setSamples(int samples);
283         void setPlaneSize(const QVector<size_t> &planeSize);
284         void resetFormat();
285         void resetLayout();
286         void resetRate();
287         void resetSamples();
288         void resetPlaneSize();
289         void clear();
290 };
291 
292 AKCOMMONS_EXPORT qreal operator -(const AkAudioCaps::SpeakerPosition &pos1,
293                                   const AkAudioCaps::SpeakerPosition &pos2);
294 AKCOMMONS_EXPORT QDebug operator <<(QDebug debug, const AkAudioCaps &caps);
295 AKCOMMONS_EXPORT QDebug operator <<(QDebug debug, AkAudioCaps::SampleFormat format);
296 AKCOMMONS_EXPORT QDebug operator <<(QDebug debug, AkAudioCaps::SampleType sampleType);
297 AKCOMMONS_EXPORT QDebug operator <<(QDebug debug, AkAudioCaps::Position position);
298 AKCOMMONS_EXPORT QDebug operator <<(QDebug debug, AkAudioCaps::ChannelLayout layout);
299 AKCOMMONS_EXPORT QDataStream &operator >>(QDataStream &istream, AkAudioCaps &caps);
300 AKCOMMONS_EXPORT QDataStream &operator <<(QDataStream &ostream, const AkAudioCaps &caps);
301 
302 Q_DECLARE_METATYPE(AkAudioCaps)
303 Q_DECLARE_METATYPE(AkAudioCaps::SampleFormat)
304 Q_DECLARE_METATYPE(AkAudioCaps::SampleType)
305 Q_DECLARE_METATYPE(AkAudioCaps::Position)
306 Q_DECLARE_METATYPE(AkAudioCaps::ChannelLayout)
307 Q_DECLARE_METATYPE(QList<AkAudioCaps::SampleFormat>)
308 Q_DECLARE_METATYPE(QList<AkAudioCaps::ChannelLayout>)
309 
310 #endif // AKAUDIOCAPS_H
311