mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-08 03:35:35 +08:00
Ref T730, input/output
* style * fload -> double * CLogMessage
This commit is contained in:
committed by
Mat Sutcliffe
parent
661a6576c5
commit
fbc1efd7c7
@@ -9,12 +9,16 @@
|
|||||||
//! \file
|
//! \file
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "blackmisc/logmessage.h"
|
||||||
#include "blacksound/audioutilities.h"
|
#include "blacksound/audioutilities.h"
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <QStringBuilder>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
using namespace BlackMisc;
|
||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
namespace Afv
|
namespace Afv
|
||||||
@@ -53,7 +57,7 @@ namespace BlackCore
|
|||||||
m_buffer.append(data, static_cast<int>(len));
|
m_buffer.append(data, static_cast<int>(len));
|
||||||
while (m_buffer.size() > 1920)
|
while (m_buffer.size() > 1920)
|
||||||
{
|
{
|
||||||
qDebug() << QDateTime::currentMSecsSinceEpoch() << "CAudioInputBuffer::writeData " << m_buffer.size();
|
// qDebug() << QDateTime::currentMSecsSinceEpoch() << "CAudioInputBuffer::writeData " << m_buffer.size();
|
||||||
emit frameAvailable(m_buffer.left(1920));
|
emit frameAvailable(m_buffer.left(1920));
|
||||||
m_buffer.remove(0, 1920);
|
m_buffer.remove(0, 1920);
|
||||||
}
|
}
|
||||||
@@ -70,8 +74,7 @@ namespace BlackCore
|
|||||||
const qint64 delta = now - m_lastFrameSent;
|
const qint64 delta = now - m_lastFrameSent;
|
||||||
if (delta >= 19)
|
if (delta >= 19)
|
||||||
{
|
{
|
||||||
qDebug() << now << "[signal] frameAvailable - buffer size" << m_buffer.size();
|
// qDebug() << now << "[signal] frameAvailable - buffer size" << m_buffer.size();
|
||||||
|
|
||||||
m_buffer.remove(0, 1920);
|
m_buffer.remove(0, 1920);
|
||||||
m_lastFrameSent = now;
|
m_lastFrameSent = now;
|
||||||
emit frameAvailable(m_buffer.left(1920));
|
emit frameAvailable(m_buffer.left(1920));
|
||||||
@@ -91,7 +94,6 @@ namespace BlackCore
|
|||||||
if (m_started) { return; }
|
if (m_started) { return; }
|
||||||
|
|
||||||
QAudioFormat inputFormat;
|
QAudioFormat inputFormat;
|
||||||
|
|
||||||
inputFormat.setSampleRate(m_sampleRate);
|
inputFormat.setSampleRate(m_sampleRate);
|
||||||
inputFormat.setChannelCount(1);
|
inputFormat.setChannelCount(1);
|
||||||
inputFormat.setSampleSize(16);
|
inputFormat.setSampleSize(16);
|
||||||
@@ -100,14 +102,17 @@ namespace BlackCore
|
|||||||
inputFormat.setCodec("audio/pcm");
|
inputFormat.setCodec("audio/pcm");
|
||||||
if (!inputDevice.isFormatSupported(inputFormat))
|
if (!inputDevice.isFormatSupported(inputFormat))
|
||||||
{
|
{
|
||||||
qWarning() << "Default INPUT format not supported - trying to use nearest";
|
inputFormat = inputDevice.nearestFormat(inputFormat);
|
||||||
qWarning() << "Default format not supported - trying to use nearest:";
|
const QString w =
|
||||||
qWarning() << "Sample rate: " << inputFormat.sampleRate();
|
inputDevice.deviceName() %
|
||||||
qWarning() << "Sample size: " << inputFormat.sampleSize();
|
": Default INPUT format not supported - trying to use nearest" %
|
||||||
qWarning() << "Sample type: " << inputFormat.sampleType();
|
" Sample rate: " % QString::number(inputFormat.sampleRate()) %
|
||||||
qWarning() << "Byte order: " << inputFormat.byteOrder();
|
" Sample size: " % QString::number(inputFormat.sampleSize()) %
|
||||||
qWarning() << "Codec: " << inputFormat.codec();
|
" Sample type: " % QString::number(inputFormat.sampleType()) %
|
||||||
qWarning() << "Channel count: " << inputFormat.channelCount();
|
" Byte order: " % QString::number(inputFormat.byteOrder()) %
|
||||||
|
" Codec: " % inputFormat.codec() %
|
||||||
|
" Channel count: " % QString::number(inputFormat.channelCount());
|
||||||
|
CLogMessage(this).warning(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_audioInput.reset(new QAudioInput(inputDevice, inputFormat));
|
m_audioInput.reset(new QAudioInput(inputDevice, inputFormat));
|
||||||
@@ -152,18 +157,16 @@ namespace BlackCore
|
|||||||
m_opusBytesEncoded += length;
|
m_opusBytesEncoded += length;
|
||||||
|
|
||||||
m_sampleCount += samples.size();
|
m_sampleCount += samples.size();
|
||||||
if (m_sampleCount >= c_sampleCountPerEvent)
|
if (m_sampleCount >= SampleCountPerEvent)
|
||||||
{
|
{
|
||||||
InputVolumeStreamArgs inputVolumeStreamArgs;
|
InputVolumeStreamArgs inputVolumeStreamArgs;
|
||||||
qint16 maxInt = std::numeric_limits<qint16>::max();
|
qint16 maxInt = std::numeric_limits<qint16>::max();
|
||||||
inputVolumeStreamArgs.PeakRaw = static_cast<float>(m_maxSampleInput) / maxInt;
|
inputVolumeStreamArgs.PeakRaw = static_cast<float>(m_maxSampleInput) / maxInt;
|
||||||
inputVolumeStreamArgs.PeakDB = static_cast<float>(20 * std::log10(inputVolumeStreamArgs.PeakRaw));
|
inputVolumeStreamArgs.PeakDB = static_cast<float>(20 * std::log10(inputVolumeStreamArgs.PeakRaw));
|
||||||
float db = qBound(minDb, inputVolumeStreamArgs.PeakDB, maxDb);
|
double db = qBound(minDb, inputVolumeStreamArgs.PeakDB, maxDb);
|
||||||
float ratio = (db - minDb) / (maxDb - minDb);
|
double ratio = (db - minDb) / (maxDb - minDb);
|
||||||
if (ratio < 0.30)
|
if (ratio < 0.30) { ratio = 0.0; }
|
||||||
ratio = 0;
|
if (ratio > 1.0) { ratio = 1.0; }
|
||||||
if (ratio > 1.0)
|
|
||||||
ratio = 1;
|
|
||||||
inputVolumeStreamArgs.PeakVU = ratio;
|
inputVolumeStreamArgs.PeakVU = ratio;
|
||||||
emit inputVolumeStream(inputVolumeStreamArgs);
|
emit inputVolumeStream(inputVolumeStreamArgs);
|
||||||
m_sampleCount = 0;
|
m_sampleCount = 0;
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ namespace BlackCore
|
|||||||
struct InputVolumeStreamArgs
|
struct InputVolumeStreamArgs
|
||||||
{
|
{
|
||||||
QAudioDeviceInfo DeviceNumber;
|
QAudioDeviceInfo DeviceNumber;
|
||||||
float PeakRaw = 0.0;
|
double PeakRaw = 0.0;
|
||||||
float PeakDB = -1 * std::numeric_limits<float>::infinity();
|
double PeakDB = -1.0 * std::numeric_limits<double>::infinity();
|
||||||
float PeakVU = 0.0;
|
double PeakVU = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Input
|
//! Input
|
||||||
@@ -85,16 +85,24 @@ namespace BlackCore
|
|||||||
//! Ctor
|
//! Ctor
|
||||||
CInput(int sampleRate, QObject *parent = nullptr);
|
CInput(int sampleRate, QObject *parent = nullptr);
|
||||||
|
|
||||||
bool started() const { return m_started; }
|
|
||||||
|
|
||||||
int opusBytesEncoded() const { return m_opusBytesEncoded; }
|
int opusBytesEncoded() const { return m_opusBytesEncoded; }
|
||||||
void setOpusBytesEncoded(int opusBytesEncoded) { m_opusBytesEncoded = opusBytesEncoded; }
|
void setOpusBytesEncoded(int opusBytesEncoded) { m_opusBytesEncoded = opusBytesEncoded; }
|
||||||
|
|
||||||
double volume() const { return m_volume; }
|
double volume() const { return m_volume; }
|
||||||
void setVolume(double volume) { m_volume = volume; }
|
void setVolume(double volume) { m_volume = volume; }
|
||||||
|
|
||||||
|
//! Started?
|
||||||
|
bool started() const { return m_started; }
|
||||||
|
|
||||||
|
//! Start
|
||||||
void start(const QAudioDeviceInfo &inputDevice);
|
void start(const QAudioDeviceInfo &inputDevice);
|
||||||
|
|
||||||
|
//! Stop
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
//! Corresponding device
|
||||||
|
const QAudioDeviceInfo &device() const { return m_device; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
//! Volume stream data
|
//! Volume stream data
|
||||||
void inputVolumeStream(const InputVolumeStreamArgs &args);
|
void inputVolumeStream(const InputVolumeStreamArgs &args);
|
||||||
@@ -110,6 +118,7 @@ namespace BlackCore
|
|||||||
|
|
||||||
BlackSound::Codecs::COpusEncoder m_encoder;
|
BlackSound::Codecs::COpusEncoder m_encoder;
|
||||||
QScopedPointer<QAudioInput> m_audioInput;
|
QScopedPointer<QAudioInput> m_audioInput;
|
||||||
|
QAudioDeviceInfo m_device;
|
||||||
|
|
||||||
bool m_started = false;
|
bool m_started = false;
|
||||||
int m_opusBytesEncoded = 0;
|
int m_opusBytesEncoded = 0;
|
||||||
@@ -117,9 +126,9 @@ namespace BlackCore
|
|||||||
double m_volume = 1.0;
|
double m_volume = 1.0;
|
||||||
qint16 m_maxSampleInput = 0.0;
|
qint16 m_maxSampleInput = 0.0;
|
||||||
|
|
||||||
const int c_sampleCountPerEvent = 4800;
|
const int SampleCountPerEvent = 4800;
|
||||||
const float maxDb = 0;
|
const double maxDb = 0;
|
||||||
const float minDb = -40;
|
const double minDb = -40;
|
||||||
|
|
||||||
uint m_audioSequenceCounter = 0;
|
uint m_audioSequenceCounter = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,13 @@
|
|||||||
//! \file
|
//! \file
|
||||||
|
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
#include "blackmisc/logmessage.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QStringBuilder>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
using namespace BlackMisc;
|
||||||
using namespace BlackSound::SampleProvider;
|
using namespace BlackSound::SampleProvider;
|
||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
@@ -38,23 +41,20 @@ namespace BlackCore
|
|||||||
{
|
{
|
||||||
qint16 sampleInput = sample;
|
qint16 sampleInput = sample;
|
||||||
sampleInput = qAbs(sampleInput);
|
sampleInput = qAbs(sampleInput);
|
||||||
if (sampleInput > m_maxSampleOutput)
|
if (sampleInput > m_maxSampleOutput) { m_maxSampleOutput = sampleInput; }
|
||||||
m_maxSampleOutput = sampleInput;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sampleCount += buffer.size();
|
m_sampleCount += buffer.size();
|
||||||
if (m_sampleCount >= c_sampleCountPerEvent)
|
if (m_sampleCount >= SampleCountPerEvent)
|
||||||
{
|
{
|
||||||
OutputVolumeStreamArgs outputVolumeStreamArgs;
|
OutputVolumeStreamArgs outputVolumeStreamArgs;
|
||||||
qint16 maxInt = std::numeric_limits<qint16>::max();
|
qint16 maxInt = std::numeric_limits<qint16>::max();
|
||||||
outputVolumeStreamArgs.PeakRaw = m_maxSampleOutput / maxInt;
|
outputVolumeStreamArgs.PeakRaw = m_maxSampleOutput / maxInt;
|
||||||
outputVolumeStreamArgs.PeakDB = (float)(20 * std::log10(outputVolumeStreamArgs.PeakRaw));
|
outputVolumeStreamArgs.PeakDB = static_cast<float>(20 * std::log10(outputVolumeStreamArgs.PeakRaw));
|
||||||
float db = qBound(minDb, outputVolumeStreamArgs.PeakDB, maxDb);
|
const double db = qBound(minDb, outputVolumeStreamArgs.PeakDB, maxDb);
|
||||||
float ratio = (db - minDb) / (maxDb - minDb);
|
double ratio = (db - minDb) / (maxDb - minDb);
|
||||||
if (ratio < 0.30)
|
if (ratio < 0.30) { ratio = 0.0; }
|
||||||
ratio = 0;
|
if (ratio > 1.0) { ratio = 1.0; }
|
||||||
if (ratio > 1.0)
|
|
||||||
ratio = 1;
|
|
||||||
outputVolumeStreamArgs.PeakVU = ratio;
|
outputVolumeStreamArgs.PeakVU = ratio;
|
||||||
emit outputVolumeStream(outputVolumeStreamArgs);
|
emit outputVolumeStream(outputVolumeStreamArgs);
|
||||||
m_sampleCount = 0;
|
m_sampleCount = 0;
|
||||||
@@ -84,7 +84,7 @@ namespace BlackCore
|
|||||||
Output::Output(QObject *parent) : QObject(parent)
|
Output::Output(QObject *parent) : QObject(parent)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void Output::start(const QAudioDeviceInfo &device, ISampleProvider *sampleProvider)
|
void Output::start(const QAudioDeviceInfo &outputDevice, ISampleProvider *sampleProvider)
|
||||||
{
|
{
|
||||||
m_audioOutputBuffer = new CAudioOutputBuffer(sampleProvider, this);
|
m_audioOutputBuffer = new CAudioOutputBuffer(sampleProvider, this);
|
||||||
connect(m_audioOutputBuffer, &CAudioOutputBuffer::outputVolumeStream, this, &Output::outputVolumeStream);
|
connect(m_audioOutputBuffer, &CAudioOutputBuffer::outputVolumeStream, this, &Output::outputVolumeStream);
|
||||||
@@ -97,20 +97,22 @@ namespace BlackCore
|
|||||||
outputFormat.setByteOrder(QAudioFormat::LittleEndian);
|
outputFormat.setByteOrder(QAudioFormat::LittleEndian);
|
||||||
outputFormat.setCodec("audio/pcm");
|
outputFormat.setCodec("audio/pcm");
|
||||||
|
|
||||||
if (!device.isFormatSupported(outputFormat))
|
if (!outputDevice.isFormatSupported(outputFormat))
|
||||||
{
|
{
|
||||||
qWarning() << "Default OUTPUT format not supported - trying to use nearest";
|
outputFormat = outputDevice.nearestFormat(outputFormat);
|
||||||
outputFormat = device.nearestFormat(outputFormat);
|
const QString w =
|
||||||
qWarning() << "Default format not supported - trying to use nearest:";
|
outputDevice.deviceName() %
|
||||||
qWarning() << "Sample rate: " << outputFormat.sampleRate();
|
": Default OUTPUT format not supported - trying to use nearest" %
|
||||||
qWarning() << "Sample size: " << outputFormat.sampleSize();
|
" Sample rate: " % QString::number(outputFormat.sampleRate()) %
|
||||||
qWarning() << "Sample type: " << outputFormat.sampleType();
|
" Sample size: " % QString::number(outputFormat.sampleSize()) %
|
||||||
qWarning() << "Byte order: " << outputFormat.byteOrder();
|
" Sample type: " % QString::number(outputFormat.sampleType()) %
|
||||||
qWarning() << "Codec: " << outputFormat.codec();
|
" Byte order: " % QString::number(outputFormat.byteOrder()) %
|
||||||
qWarning() << "Channel count: " << outputFormat.channelCount();
|
" Codec: " % outputFormat.codec() %
|
||||||
|
" Channel count: " % QString::number(outputFormat.channelCount());
|
||||||
|
CLogMessage(this).warning(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_audioOutputCom1.reset(new QAudioOutput(device, outputFormat));
|
m_audioOutputCom1.reset(new QAudioOutput(outputDevice, outputFormat));
|
||||||
// m_audioOutput->setBufferSize(bufferSize);
|
// m_audioOutput->setBufferSize(bufferSize);
|
||||||
m_audioOutputBuffer->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
|
m_audioOutputBuffer->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
|
||||||
m_audioOutputBuffer->setAudioFormat(outputFormat);
|
m_audioOutputBuffer->setAudioFormat(outputFormat);
|
||||||
@@ -123,6 +125,8 @@ namespace BlackCore
|
|||||||
{
|
{
|
||||||
if (!m_started) { return; }
|
if (!m_started) { return; }
|
||||||
m_started = false;
|
m_started = false;
|
||||||
|
m_audioOutputBuffer->deleteLater();
|
||||||
|
m_audioOutputBuffer = nullptr;
|
||||||
}
|
}
|
||||||
} // ns
|
} // ns
|
||||||
} // ns
|
} // ns
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ namespace BlackCore
|
|||||||
struct OutputVolumeStreamArgs
|
struct OutputVolumeStreamArgs
|
||||||
{
|
{
|
||||||
QAudioDeviceInfo DeviceNumber;
|
QAudioDeviceInfo DeviceNumber;
|
||||||
float PeakRaw = 0.0;
|
double PeakRaw = 0.0;
|
||||||
float PeakDB = -1 * std::numeric_limits<float>::infinity();
|
double PeakDB = -1 * std::numeric_limits<double>::infinity();
|
||||||
float PeakVU = 0.0;
|
double PeakVU = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CAudioOutputBuffer : public QIODevice
|
class CAudioOutputBuffer : public QIODevice
|
||||||
@@ -40,8 +40,10 @@ namespace BlackCore
|
|||||||
//! Ctor
|
//! Ctor
|
||||||
CAudioOutputBuffer(BlackSound::SampleProvider::ISampleProvider *sampleProvider, QObject *parent = nullptr);
|
CAudioOutputBuffer(BlackSound::SampleProvider::ISampleProvider *sampleProvider, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
//! Related provider
|
||||||
BlackSound::SampleProvider::ISampleProvider *m_sampleProvider = nullptr;
|
BlackSound::SampleProvider::ISampleProvider *m_sampleProvider = nullptr;
|
||||||
|
|
||||||
|
//! Set the format
|
||||||
void setAudioFormat(const QAudioFormat &format) { m_outputFormat = format; }
|
void setAudioFormat(const QAudioFormat &format) { m_outputFormat = format; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -54,30 +56,40 @@ namespace BlackCore
|
|||||||
private:
|
private:
|
||||||
QAudioFormat m_outputFormat;
|
QAudioFormat m_outputFormat;
|
||||||
|
|
||||||
float m_maxSampleOutput = 0;
|
double m_maxSampleOutput = 0;
|
||||||
int m_sampleCount = 0;
|
int m_sampleCount = 0;
|
||||||
const int c_sampleCountPerEvent = 4800;
|
const int SampleCountPerEvent = 4800;
|
||||||
const float maxDb = 0;
|
const double maxDb = 0;
|
||||||
const float minDb = -40;
|
const double minDb = -40;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Output
|
||||||
class Output : public QObject
|
class Output : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
//! Ctor
|
||||||
Output(QObject *parent = nullptr);
|
Output(QObject *parent = nullptr);
|
||||||
|
|
||||||
void start(const QAudioDeviceInfo &device, BlackSound::SampleProvider::ISampleProvider *sampleProvider);
|
//! Start output
|
||||||
|
void start(const QAudioDeviceInfo &outputDevice, BlackSound::SampleProvider::ISampleProvider *sampleProvider);
|
||||||
|
|
||||||
|
//! Stop output
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
//! Corresponding device
|
||||||
|
const QAudioDeviceInfo &device() const { return m_device; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
//! Streaming data
|
||||||
void outputVolumeStream(const OutputVolumeStreamArgs &args);
|
void outputVolumeStream(const OutputVolumeStreamArgs &args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_started = false;
|
bool m_started = false;
|
||||||
|
|
||||||
|
QAudioDeviceInfo m_device;
|
||||||
QScopedPointer<QAudioOutput> m_audioOutputCom1;
|
QScopedPointer<QAudioOutput> m_audioOutputCom1;
|
||||||
CAudioOutputBuffer *m_audioOutputBuffer;
|
CAudioOutputBuffer *m_audioOutputBuffer = nullptr;
|
||||||
};
|
};
|
||||||
} // ns
|
} // ns
|
||||||
} // ns
|
} // ns
|
||||||
|
|||||||
Reference in New Issue
Block a user