-
Notifications
You must be signed in to change notification settings - Fork 0
/
QRetroMicrophone.cpp
109 lines (86 loc) · 2.86 KB
/
QRetroMicrophone.cpp
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
#include <QAudioInput>
#include "QRetroMicrophone.h"
struct qretro_microphone_t
{
QAudioInput *input = nullptr;
QIODevice *device = nullptr;
};
typedef int16_t qretro_mic_sample_t;
#define QRETRO_MIC_BUFFER_FRAMES 10
retro_microphone_t* QRetroMicrophone::open(const retro_microphone_params_t *params)
{
auto mic = new qretro_microphone_t;
QAudioFormat format;
format.setSampleRate(static_cast<int>(params->rate));
format.setChannelCount(1);
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);
if (!mic->input || mic->input->error())
return nullptr;
else
return reinterpret_cast<retro_microphone_t*>(mic);
}
void QRetroMicrophone::close(retro_microphone_t *microphone)
{
auto mic = reinterpret_cast<qretro_microphone_t*>(microphone);
if (mic)
{
mic->input->stop();
delete mic->input;
delete mic->device;
delete mic;
}
}
bool QRetroMicrophone::getParams(const retro_microphone_t *microphone,
retro_microphone_params_t *params)
{
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;
}
}
bool QRetroMicrophone::setState(retro_microphone_t *microphone, bool state)
{
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;
}
bool QRetroMicrophone::getState(const retro_microphone_t *microphone)
{
auto mic = reinterpret_cast<const qretro_microphone_t*>(microphone);
return mic &&
mic->input &&
(mic->input->state() == QAudio::ActiveState ||
mic->input->state() == QAudio::IdleState);
}
int QRetroMicrophone::read(retro_microphone_t *microphone, int16_t *samples,
size_t num_samples)
{
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 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 read / sizeof(qretro_mic_sample_t);
}