[AFV] Ref T730, improved volume handling

* for the asymmetric output volume -60/18dB, make sure that normalized 50 means 0dB
* slider is centered
* return value if value for volume was changed
This commit is contained in:
Klaus Basan
2019-10-11 22:53:39 +02:00
parent a726c7709e
commit a9166d4e4c
7 changed files with 76 additions and 35 deletions

View File

@@ -94,6 +94,13 @@ namespace BlackCore
m_encoder.setBitRate(16 * 1024); m_encoder.setBitRate(16 * 1024);
} }
bool CInput::setVolume(double volume)
{
if (qFuzzyCompare(m_volume, volume)) { return false; }
m_volume = volume;
return true;
}
void CInput::start(const CAudioDeviceInfo &inputDevice) void CInput::start(const CAudioDeviceInfo &inputDevice)
{ {
if (m_started) { return; } if (m_started) { return; }

View File

@@ -95,11 +95,15 @@ namespace BlackCore
this->stop(); this->stop();
} }
//! Number of encoded bytes @{
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; }
//! @}
//! Volume @{
double volume() const { return m_volume; } double volume() const { return m_volume; }
void setVolume(double volume) { m_volume = volume; } bool setVolume(double volume);
//! @}
//! Started? //! Started?
bool started() const { return m_started; } bool started() const { return m_started; }
@@ -132,9 +136,9 @@ namespace BlackCore
QAudioFormat m_inputFormat; QAudioFormat m_inputFormat;
bool m_started = false; bool m_started = false;
int m_opusBytesEncoded = 0; int m_opusBytesEncoded = 0;
int m_sampleCount = 0; int m_sampleCount = 0;
double m_volume = 1.0; double m_volume = 1.0;
qint16 m_maxSampleInput = 0.0; qint16 m_maxSampleInput = 0.0;
const int SampleCountPerEvent = 4800; const int SampleCountPerEvent = 4800;
@@ -142,7 +146,6 @@ namespace BlackCore
const double minDb = -40; const double minDb = -40;
uint m_audioSequenceCounter = 0; uint m_audioSequenceCounter = 0;
CAudioInputBuffer m_audioInputBuffer; CAudioInputBuffer m_audioInputBuffer;
#ifdef Q_OS_MAC #ifdef Q_OS_MAC

View File

@@ -165,7 +165,8 @@ namespace BlackCore
bool CAfvClient::isMuted() const bool CAfvClient::isMuted() const
{ {
return this->getNormalizedOutputVolume() < 1; const int v = this->getNormalizedOutputVolume();
return v < 1;
} }
void CAfvClient::setMuted(bool mute) void CAfvClient::setMuted(bool mute)
@@ -475,17 +476,19 @@ namespace BlackCore
return m_inputVolumeDb; return m_inputVolumeDb;
} }
void CAfvClient::setInputVolumeDb(double valueDb) bool CAfvClient::setInputVolumeDb(double valueDb)
{ {
if (valueDb > MaxDbIn) { valueDb = MaxDbIn; } if (valueDb > MaxDbIn) { valueDb = MaxDbIn; }
else if (valueDb < MinDbIn) { valueDb = MinDbIn; } else if (valueDb < MinDbIn) { valueDb = MinDbIn; }
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
bool changed = !qFuzzyCompare(m_inputVolumeDb, valueDb);
m_inputVolumeDb = valueDb; m_inputVolumeDb = valueDb;
if (m_input) if (m_input)
{ {
m_input->setVolume(qPow(10, valueDb / 20.0)); changed = m_input->setVolume(qPow(10, valueDb / 20.0));
} }
return changed;
} }
double CAfvClient::getOutputVolumeDb() const double CAfvClient::getOutputVolumeDb() const
@@ -504,27 +507,46 @@ namespace BlackCore
int CAfvClient::getNormalizedOutputVolume() const int CAfvClient::getNormalizedOutputVolume() const
{ {
const double db = this->getOutputVolumeDb(); double db = this->getOutputVolumeDb();
const double range = MaxDbOut - MinDbOut; double range = MaxDbOut;
const int i = qRound((db - MinDbOut) / range * 100); int v = 50;
return i; if (db < 0)
{
v = 0;
db -= MinDbOut;
range = qAbs(MinDbOut);
}
v += qRound(db * 50 / range);
return v;
} }
void CAfvClient::setNormalizedInputVolume(int volume) bool CAfvClient::setNormalizedInputVolume(int volume)
{ {
if (volume < 0) { volume = 0; } if (volume < 0) { volume = 0; }
else if (volume > 100) { volume = 100; } else if (volume > 100) { volume = 100; }
const double range = MaxDbIn - MinDbIn; const double range = MaxDbIn - MinDbIn;
const double dB = MinDbIn + (volume * range / 100.0); const double dB = MinDbIn + (volume * range / 100.0);
this->setInputVolumeDb(dB); return this->setInputVolumeDb(dB);
} }
void CAfvClient::setNormalizedOutputVolume(int volume) void CAfvClient::setNormalizedOutputVolume(int volume)
{ {
if (volume < 0) { volume = 0; } if (volume < 0) { volume = 0; }
else if (volume > 100) { volume = 100; } else if (volume > 100) { volume = 100; }
const double range = MaxDbOut - MinDbOut;
const double dB = MinDbOut + (volume * range / 100.0); // Asymetric
double range = MaxDbOut;
double dB = 0;
if (volume >= 50)
{
volume -= 50;
}
else
{
dB = MinDbOut;
range = qAbs(MinDbOut);
}
dB += (volume * range / 50.0);
this->setOutputVolumeDb(dB); this->setOutputVolumeDb(dB);
} }
@@ -555,8 +577,8 @@ namespace BlackCore
audioData.lastPacket = false; audioData.lastPacket = false;
audioData.sequenceCounter = 0; audioData.sequenceCounter = 0;
RxTransceiverDto com1 = { 0, transceivers.size() > 0 ? transceivers[0].frequencyHz : UniCom, 1.0 }; const RxTransceiverDto com1 = { 0, transceivers.size() > 0 ? transceivers[0].frequencyHz : UniCom, 1.0 };
RxTransceiverDto com2 = { 1, transceivers.size() > 1 ? transceivers[1].frequencyHz : UniCom, 1.0 }; const RxTransceiverDto com2 = { 1, transceivers.size() > 1 ? transceivers[1].frequencyHz : UniCom, 1.0 };
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
m_soundcardSampleProvider->addOpusSamples(audioData, { com1, com2 }); m_soundcardSampleProvider->addOpusSamples(audioData, { com1, com2 });
@@ -719,8 +741,8 @@ namespace BlackCore
QVector<TransceiverDto> newTransceivers { transceiverCom1, transceiverCom2 }; QVector<TransceiverDto> newTransceivers { transceiverCom1, transceiverCom2 };
QVector<TransceiverDto> newEnabledTransceivers; QVector<TransceiverDto> newEnabledTransceivers;
QVector<TxTransceiverDto> newTransmittingTransceivers; QVector<TxTransceiverDto> newTransmittingTransceivers;
if (e1) { newEnabledTransceivers.push_back(transceiverCom1); newEnabledTransceiverIds.insert(transceiverCom1.id); } if (e1) { newEnabledTransceivers.push_back(transceiverCom1); newEnabledTransceiverIds.insert(transceiverCom1.id); }
if (e2) { newEnabledTransceivers.push_back(transceiverCom2); newEnabledTransceiverIds.insert(transceiverCom2.id); } if (e2) { newEnabledTransceivers.push_back(transceiverCom2); newEnabledTransceiverIds.insert(transceiverCom2.id); }
// Transmitting transceivers, currently ALLOW ONLY ONE // Transmitting transceivers, currently ALLOW ONLY ONE
if (tx1 && e1) { newTransmittingTransceivers.push_back(transceiverCom1); } if (tx1 && e1) { newTransmittingTransceivers.push_back(transceiverCom1); }
@@ -807,19 +829,21 @@ namespace BlackCore
return sApp && !sApp->isShuttingDown() && sApp->getIContextOwnAircraft(); return sApp && !sApp->isShuttingDown() && sApp->getIContextOwnAircraft();
} }
void CAfvClient::setOutputVolumeDb(double valueDb) bool CAfvClient::setOutputVolumeDb(double valueDb)
{ {
if (valueDb > MaxDbOut) { valueDb = MaxDbOut; } if (valueDb > MaxDbOut) { valueDb = MaxDbOut; }
if (valueDb < MinDbOut) { valueDb = MinDbOut; } else if (valueDb < MinDbOut) { valueDb = MinDbOut; }
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
bool changed = !qFuzzyCompare(m_outputVolumeDb, valueDb);
m_outputVolumeDb = valueDb; m_outputVolumeDb = valueDb;
m_outputVolume = qPow(10, m_outputVolumeDb / 20.0); m_outputVolume = qPow(10, m_outputVolumeDb / 20.0);
if (m_outputSampleProvider) if (m_outputSampleProvider)
{ {
m_outputSampleProvider->setVolume(m_outputVolume); changed = m_outputSampleProvider->setVolume(m_outputVolume);
} }
return changed;
} }
const CAudioDeviceInfo &CAfvClient::getInputDevice() const const CAudioDeviceInfo &CAfvClient::getInputDevice() const

View File

@@ -178,14 +178,14 @@ namespace BlackCore
//! \threadsafe //! \threadsafe
//! @{ //! @{
double getInputVolumeDb() const; double getInputVolumeDb() const;
Q_INVOKABLE void setInputVolumeDb(double valueDb); Q_INVOKABLE bool setInputVolumeDb(double valueDb);
//! @} //! @}
//! Output volume in dB, +-18dB //! Output volume in dB, +-18dB
//! \threadsafe //! \threadsafe
//! @{ //! @{
double getOutputVolumeDb() const; double getOutputVolumeDb() const;
Q_INVOKABLE void setOutputVolumeDb(double valueDb); Q_INVOKABLE bool setOutputVolumeDb(double valueDb);
//! @} //! @}
//! Normalized volumes 0..100 //! Normalized volumes 0..100
@@ -193,7 +193,7 @@ namespace BlackCore
//! @{ //! @{
int getNormalizedInputVolume() const; int getNormalizedInputVolume() const;
int getNormalizedOutputVolume() const; int getNormalizedOutputVolume() const;
void setNormalizedInputVolume(int volume); bool setNormalizedInputVolume(int volume);
void setNormalizedOutputVolume(int volume); void setNormalizedOutputVolume(int volume);
//! @} //! @}
@@ -262,13 +262,13 @@ namespace BlackCore
quint32 getAliasFrequencyHz(quint32 frequencyHz) const; quint32 getAliasFrequencyHz(quint32 frequencyHz) const;
static constexpr int PositionUpdatesMs = 5000; //!< position timer static constexpr int PositionUpdatesMs = 5000; //!< position timer
static constexpr int SampleRate = 48000; static constexpr int SampleRate = 48000;
static constexpr int FrameSize = 960; // 20ms static constexpr int FrameSize = 960; //!< 20ms
static constexpr double MinDbIn = -18.0; static constexpr double MinDbIn = -18.0;
static constexpr double MaxDbIn = 18.0; static constexpr double MaxDbIn = 18.0;
static constexpr double MinDbOut = -60.0; static constexpr double MinDbOut = -60.0;
static constexpr double MaxDbOut = 18.0; static constexpr double MaxDbOut = 18.0;
static constexpr quint32 UniCom = 122800000; static constexpr quint32 UniCom = 122800000;
static quint16 comUnitToTransceiverId(BlackMisc::Aviation::CComSystem::ComUnit comUnit); static quint16 comUnitToTransceiverId(BlackMisc::Aviation::CComSystem::ComUnit comUnit);
static BlackMisc::Aviation::CComSystem::ComUnit transceiverIdToComUnit(quint16 id); static BlackMisc::Aviation::CComSystem::ComUnit transceiverIdToComUnit(quint16 id);

View File

@@ -207,7 +207,7 @@ namespace BlackCore
if (changedVoiceOutput) if (changedVoiceOutput)
{ {
m_voiceClient->setNormalizedOutputVolume(volume); m_voiceClient->setNormalizedOutputVolume(volume);
m_outVolumeBeforeMute = currentVolume; m_outVolumeBeforeMute = volume;
emit this->changedAudioVolume(volume); emit this->changedAudioVolume(volume);
if ((volume > 0 && wasMuted) || (volume < 1 && !wasMuted)) if ((volume > 0 && wasMuted) || (volume < 1 && !wasMuted))

View File

@@ -33,5 +33,12 @@ namespace BlackSound
} }
return samplesRead; return samplesRead;
} }
bool CVolumeSampleProvider::setVolume(double volume)
{
const bool changed = !qFuzzyCompare(m_volume, volume);
m_volume = volume;
return changed;
}
} // ns } // ns
} // ns } // ns

View File

@@ -32,7 +32,7 @@ namespace BlackSound
//! Volume @{ //! Volume @{
double volume() const { return m_volume; } double volume() const { return m_volume; }
void setVolume(double volume) { m_volume = volume; } bool setVolume(double volume);
//! @} //! @}
private: private: