-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathQRetroMicrophone.cpp
More file actions
181 lines (158 loc) · 4.26 KB
/
Copy pathQRetroMicrophone.cpp
File metadata and controls
181 lines (158 loc) · 4.26 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <QtGlobal>
#if QRETRO_HAVE_MULTIMEDIA
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <QAudioDevice>
#include <QAudioSource>
#include <QMediaDevices>
#else
#include <QAudioDeviceInfo>
#include <QAudioInput>
#endif
#endif
#include "QRetroMicrophone.h"
#if QRETRO_HAVE_MULTIMEDIA
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
struct qretro_microphone_t
{
QAudioSource *input = nullptr;
QIODevice *device = nullptr;
};
#else
struct qretro_microphone_t
{
QAudioInput *input = nullptr;
QIODevice *device = nullptr;
};
#endif
#endif
typedef int16_t qretro_mic_sample_t;
#define QRETRO_MIC_BUFFER_FRAMES 10
retro_microphone_t *QRetroMicrophone::open(const retro_microphone_params_t *params)
{
#if QRETRO_HAVE_MULTIMEDIA
auto mic = new qretro_microphone_t;
QAudioFormat format;
format.setSampleRate(static_cast<int>(params->rate));
format.setChannelCount(1);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
format.setSampleFormat(QAudioFormat::Int16);
QAudioDevice info = QMediaDevices::defaultAudioInput();
mic->input = new QAudioSource(info, format);
#else
format.setSampleSize(sizeof(qretro_mic_sample_t) * 8);
format.setCodec("audio/pcm");
format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(format))
format = info.nearestFormat(format);
mic->input = new QAudioInput(format);
#endif
if (!mic->input || mic->input->error())
{
delete mic;
return nullptr;
}
auto *handle = reinterpret_cast<retro_microphone_t *>(mic);
m_OpenMics.append(handle);
return handle;
#else
Q_UNUSED(params)
return nullptr;
#endif
}
QString QRetroMicrophone::deviceName() const
{
#if QRETRO_HAVE_MULTIMEDIA
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
return QMediaDevices::defaultAudioInput().description();
#else
return QAudioDeviceInfo::defaultInputDevice().deviceName();
#endif
#else
return {};
#endif
}
void QRetroMicrophone::close(retro_microphone_t *microphone)
{
#if QRETRO_HAVE_MULTIMEDIA
m_OpenMics.removeOne(microphone);
auto mic = reinterpret_cast<qretro_microphone_t *>(microphone);
if (mic)
{
mic->input->stop();
delete mic->input;
delete mic->device;
delete mic;
}
#else
Q_UNUSED(microphone)
#endif
}
bool QRetroMicrophone::getParams(
const retro_microphone_t *microphone, retro_microphone_params_t *params)
{
#if QRETRO_HAVE_MULTIMEDIA
auto mic = reinterpret_cast<const qretro_microphone_t *>(microphone);
if (!mic || !mic->input)
return false;
else
{
params->rate = static_cast<unsigned>(mic->input->format().sampleRate());
return true;
}
#else
Q_UNUSED(microphone)
Q_UNUSED(params)
return false;
#endif
}
bool QRetroMicrophone::setState(retro_microphone_t *microphone, bool state)
{
#if QRETRO_HAVE_MULTIMEDIA
auto mic = reinterpret_cast<qretro_microphone_t *>(microphone);
if (!mic || !mic->input)
return false;
else if (state)
{
mic->input->setBufferSize(mic->input->format().sampleRate() / 60 * QRETRO_MIC_BUFFER_FRAMES);
mic->device = mic->input->start();
}
else
mic->input->stop();
return true;
#else
Q_UNUSED(microphone)
Q_UNUSED(state)
return false;
#endif
}
bool QRetroMicrophone::getState(const retro_microphone_t *microphone)
{
#if QRETRO_HAVE_MULTIMEDIA
auto mic = reinterpret_cast<const qretro_microphone_t *>(microphone);
return mic && mic->input &&
(mic->input->state() == QAudio::ActiveState || mic->input->state() == QAudio::IdleState);
#else
Q_UNUSED(microphone)
return false;
#endif
}
int QRetroMicrophone::read(retro_microphone_t *microphone, int16_t *samples, size_t num_samples)
{
#if QRETRO_HAVE_MULTIMEDIA
auto mic = reinterpret_cast<qretro_microphone_t *>(microphone);
if (!(mic->input->state() == QAudio::ActiveState || mic->input->state() == QAudio::IdleState))
return -1;
/* Clean the buffer with empty samples */
memset(samples, 0, num_samples * sizeof(qretro_mic_sample_t));
auto bytes_read = static_cast<unsigned>(mic->device->read(reinterpret_cast<char *>(samples),
static_cast<qint64>(num_samples * sizeof(qretro_mic_sample_t))));
/* Return number of samples, not number of bytes */
return bytes_read / sizeof(qretro_mic_sample_t);
#else
Q_UNUSED(microphone)
Q_UNUSED(samples)
Q_UNUSED(num_samples)
return -1;
#endif
}