JS8Call-Improved master
Loading...
Searching...
No Matches
AudioDevice.h
1#ifndef AUDIODEVICE_HPP__
2#define AUDIODEVICE_HPP__
3
4#include <QIODevice>
5
6class QDataStream;
7
8//
9// abstract base class for audio devices
10//
11class AudioDevice : public QIODevice {
12 public:
13 enum Channel {
14 Mono,
15 Left,
16 Right,
17 Both
18 }; // these are mapped to combobox index so don't change
19
20 static char const *toString(Channel c) {
21 switch (c) {
22 case Mono:
23 return "Mono";
24 case Left:
25 return "Left";
26 case Right:
27 return "Right";
28 default:
29 return "Both";
30 }
31 }
32
33 static Channel fromString(QString const &str) {
34 QString const s(str.toCaseFolded().trimmed().toLatin1());
35
36 if (s == "both")
37 return Both;
38 else if (s == "right")
39 return Right;
40 else if (s == "left")
41 return Left;
42 else
43 return Mono;
44 }
45
46 bool initialize(OpenMode mode, Channel channel);
47
48 bool isSequential() const override { return true; }
49
50 size_t bytesPerFrame() const {
51 return sizeof(qint16) * (Mono == m_channel ? 1 : 2);
52 }
53
54 Channel channel() const { return m_channel; }
55
56 protected:
57 explicit AudioDevice(QObject *parent = nullptr) : QIODevice(parent) {}
58
59 void store(char const *source, size_t numFrames, qint16 *dest) {
60 qint16 const *begin(reinterpret_cast<qint16 const *>(source));
61 for (qint16 const *i = begin;
62 i != begin + numFrames * (bytesPerFrame() / sizeof(qint16));
63 i += bytesPerFrame() / sizeof(qint16)) {
64 switch (m_channel) {
65 case Mono:
66 *dest++ = *i;
67 break;
68
69 case Right:
70 *dest++ = *(i + 1);
71 break;
72
73 case Both: // should be able to happen but if it
74 // does we'll take left
75 Q_ASSERT(Both == m_channel);
76 [[fallthrough]];
77 case Left:
78 *dest++ = *i;
79 break;
80 }
81 }
82 }
83
84 qint16 *load(qint16 const sample, qint16 *dest) {
85 switch (m_channel) {
86 case Mono:
87 *dest++ = sample;
88 break;
89
90 case Left:
91 *dest++ = sample;
92 *dest++ = 0;
93 break;
94
95 case Right:
96 *dest++ = 0;
97 *dest++ = sample;
98 break;
99
100 case Both:
101 *dest++ = sample;
102 *dest++ = sample;
103 break;
104 }
105 return dest;
106 }
107
108 private:
109 Channel m_channel;
110};
111
112Q_DECLARE_METATYPE(AudioDevice::Channel);
113
114#endif