Ref T730, input/output

* style
* fload -> double
* CLogMessage
This commit is contained in:
Klaus Basan
2019-09-25 17:37:13 +02:00
committed by Mat Sutcliffe
parent 661a6576c5
commit fbc1efd7c7
4 changed files with 86 additions and 58 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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