8 #include <QAudioSource>
9 #include <QMediaDevices>
10 #include <QStringBuilder>
15 using namespace swift::config;
16 using namespace swift::misc::audio;
18 namespace swift::sound
20 QVector<float> convertBytesTo32BitFloatPCM(
const QByteArray &input)
22 int inputSamples = input.size() / 2;
23 QVector<float> output;
24 output.fill(0, inputSamples);
26 for (
int n = 0; n < inputSamples; n++)
28 output[n] = *
reinterpret_cast<const qint16 *
>(input.data() + n * 2);
29 output[n] /= 32767.0f;
34 QVector<qint16> convertBytesTo16BitPCM(
const QByteArray &input)
36 const int inputSamples = input.size() / 2;
37 QVector<qint16> output;
38 output.fill(0, inputSamples);
39 for (
int n = 0; n < inputSamples; n++) { output[n] = *
reinterpret_cast<const qint16 *
>(input.data() + n * 2); }
43 QVector<float> convertFromMonoToStereo(
const QVector<float> &mono)
45 QVector<float> stereo;
46 stereo.reserve(mono.size() * 2);
47 for (
float sample : mono)
55 QVector<qint16> convertFromStereoToMono(
const QVector<qint16> &stereo)
58 mono.reserve(stereo.size() / 2);
59 for (
int i = 0; i < stereo.size(); i = i + 2) { mono.append(stereo.at(i)); }
63 QVector<float> convertFromShortToFloat(
const QVector<qint16> &input)
65 QVector<float> output;
66 for (
auto sample : input) { output.push_back(sample / 32768.0f); }
70 QAudioDevice getLowestLatencyDevice(
const CAudioDeviceInfo &device, QAudioFormat &format)
74 const QAudioDevice defDevice =
75 device.
isInputDevice() ? QMediaDevices::defaultAudioInput() : QMediaDevices::defaultAudioOutput();
76 Q_ASSERT_X(defDevice.isFormatSupported(format), Q_FUNC_INFO,
"Device does not support format");
80 const QList<QAudioDevice> allQtDevices = device.
isInputDevice() ? CAudioDeviceInfoList::allQtInputDevices() :
84 QList<QAudioDevice> supportedDevices;
85 for (
const QAudioDevice &d : allQtDevices)
87 if (d.description() == device.
getName() && d.isFormatSupported(format)) { supportedDevices.
push_back(d); }
90 if (supportedDevices.isEmpty()) {
return {}; }
92 QAudioDevice deviceWithLowestLatency = supportedDevices.at(0);
94 if (supportedDevices.size() > 1)
96 int lowestBufferSize = std::numeric_limits<int>::max();
97 for (
const QAudioDevice &d : supportedDevices)
99 if (!d.isFormatSupported(format))
continue;
101 if (device.
getType() == CAudioDeviceInfo::InputDevice)
103 QAudioSource input(d, format);
106 bufferSize = input.bufferSize();
110 QAudioSink output(d, format);
113 bufferSize = output.bufferSize();
116 if (bufferSize < lowestBufferSize)
118 deviceWithLowestLatency = d;
119 lowestBufferSize = bufferSize;
123 return deviceWithLowestLatency;
126 QAudioDevice getHighestCompatibleOutputDevice(
const CAudioDeviceInfo &device, QAudioFormat &format)
128 if (device.
isDefault()) {
return CAudioDeviceInfoList::defaultQtOutputDevice(); }
129 const QList<QAudioDevice> allQtDevices = CAudioDeviceInfoList::allQtOutputDevices();
131 QList<QAudioDevice> supportedDevices;
132 for (
const QAudioDevice &d : allQtDevices)
134 if (d.description() == device.
getName())
137 if (d.isFormatSupported(format)) {
return d; }
139 supportedDevices.push_back(d);
143 if (supportedDevices.isEmpty())
145 format = QAudioFormat();
150 QAudioDevice usedDevice = supportedDevices.front();
151 Q_ASSERT_X(usedDevice.isFormatSupported(format), Q_FUNC_INFO,
"Device does not support format");
155 QString toQString(
const QAudioFormat &format)
157 return QStringLiteral(
"Sample rate: %1 channels: %2 sample format: %3 bytes/frame: %4")
158 .arg(format.sampleRate())
159 .arg(format.channelCount())
160 .arg(format.sampleFormat())
161 .arg(format.bytesPerFrame());
164 const QString &toQString(QSysInfo::Endian s)
166 static const QString l(
"little");
167 static const QString b(
"big");
170 case QSysInfo::BigEndian:
return b;
171 case QSysInfo::LittleEndian:
return l;
174 static const QString u(
"??");
178 const QString &toQString(QAudioFormat::SampleFormat e)
180 static const QString s(
"signed int 16");
181 static const QString u(
"unsigned int 8");
182 static const QString f(
"float");
185 case QAudioFormat::Int16:
return s;
186 case QAudioFormat::UInt8:
return u;
187 case QAudioFormat::Float:
return f;
188 case QAudioFormat::Unknown:
191 static const QString unknown(
"unknown");
195 double normalize0to100(
double in)
197 if (in < 0) {
return 0; }
198 return (in >= 1.0) ? 1.0 : in;
201 qreal normalize0to100qr(
double in) {
return static_cast<qreal
>(normalize0to100(in)); }
203 void occupyAudioInputDevice() {
static const QAudioInput input(QMediaDevices::defaultAudioInput()); }
void push_back(const T &value)
Appends an element at the end of the sequence.
Value object encapsulating information of a audio device.
bool isInputDevice() const
Input device.
bool isDefault() const
Is this a default device?
DeviceType getType() const
Type.
bool isValid() const
Valid audio device object?
const QString & getName() const
Get the device name.
Value object encapsulating a list of audio devices.