Ref T730, namespace for BlackCore::Afv

* added namespace
* removed some *.pri files and added files to blackcore.pro
* added copyright etc.
This commit is contained in:
Klaus Basan
2019-09-19 00:56:54 +02:00
committed by Mat Sutcliffe
parent d064da13b5
commit 384aa3ce19
46 changed files with 2985 additions and 2916 deletions

View File

@@ -1,191 +1,205 @@
/* Copyright (C) 2019
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
* or distributed except according to the terms contained in the LICENSE file.
*/
//! \file
#include "callsignsampleprovider.h"
#include "callsigndelaycache.h"
#include "blacksound/sampleprovider/samples.h"
#include <QtMath>
#include <QDebug>
CallsignSampleProvider::CallsignSampleProvider(const QAudioFormat &audioFormat, QObject *parent) :
ISampleProvider(parent),
m_audioFormat(audioFormat),
m_decoder(audioFormat.sampleRate(), 1)
namespace BlackCore
{
Q_ASSERT(audioFormat.channelCount() == 1);
mixer = new MixingSampleProvider(this);
crackleSoundProvider = new ResourceSoundSampleProvider(Samples::instance().crackle(), mixer);
crackleSoundProvider->setLooping(true);
crackleSoundProvider->setGain(0.0);
whiteNoise = new ResourceSoundSampleProvider(Samples::instance().whiteNoise(), mixer);
whiteNoise->setLooping(true);
whiteNoise->setGain(0.0);
acBusNoise = new SawToothGenerator(400, mixer);
audioInput = new BufferedWaveProvider(audioFormat, mixer);
// Create the compressor
simpleCompressorEffect = new SimpleCompressorEffect(audioInput, mixer);
simpleCompressorEffect->setMakeUpGain(-5.5);
// Create the voice EQ
voiceEq = new EqualizerSampleProvider(simpleCompressorEffect, EqualizerPresets::VHFEmulation, mixer);
mixer->addMixerInput(whiteNoise);
mixer->addMixerInput(acBusNoise);
mixer->addMixerInput(voiceEq);
m_timer.setInterval(100);
connect(&m_timer, &QTimer::timeout, this, &CallsignSampleProvider::timerElapsed);
}
int CallsignSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
int noOfSamples = mixer->readSamples(samples, count);
if (m_inUse && m_lastPacketLatch && audioInput->getBufferedBytes() == 0)
namespace Afv
{
idle();
m_lastPacketLatch = false;
}
namespace Audio
{
CallsignSampleProvider::CallsignSampleProvider(const QAudioFormat &audioFormat, QObject *parent) :
ISampleProvider(parent),
m_audioFormat(audioFormat),
m_decoder(audioFormat.sampleRate(), 1)
{
Q_ASSERT(audioFormat.channelCount() == 1);
if (m_inUse && !m_underflow && audioInput->getBufferedBytes() == 0)
{
qDebug() << "[" << m_callsign << "] [Delay++]";
CallsignDelayCache::instance().underflow(m_callsign);
m_underflow = true;
}
mixer = new MixingSampleProvider(this);
crackleSoundProvider = new ResourceSoundSampleProvider(Samples::instance().crackle(), mixer);
crackleSoundProvider->setLooping(true);
crackleSoundProvider->setGain(0.0);
whiteNoise = new ResourceSoundSampleProvider(Samples::instance().whiteNoise(), mixer);
whiteNoise->setLooping(true);
whiteNoise->setGain(0.0);
acBusNoise = new SawToothGenerator(400, mixer);
audioInput = new BufferedWaveProvider(audioFormat, mixer);
return noOfSamples;
}
// Create the compressor
simpleCompressorEffect = new SimpleCompressorEffect(audioInput, mixer);
simpleCompressorEffect->setMakeUpGain(-5.5);
void CallsignSampleProvider::timerElapsed()
{
if (m_inUse && audioInput->getBufferedBytes() == 0 && m_lastSamplesAddedUtc.msecsTo(QDateTime::currentDateTimeUtc()) > idleTimeoutMs)
{
idle();
}
}
// Create the voice EQ
voiceEq = new EqualizerSampleProvider(simpleCompressorEffect, EqualizerPresets::VHFEmulation, mixer);
QString CallsignSampleProvider::type() const
{
return m_type;
}
mixer->addMixerInput(whiteNoise);
mixer->addMixerInput(acBusNoise);
mixer->addMixerInput(voiceEq);
void CallsignSampleProvider::active(const QString &callsign, const QString &aircraftType)
{
m_callsign = callsign;
CallsignDelayCache::instance().initialise(callsign);
m_type = aircraftType;
m_decoder.resetState();
m_inUse = true;
setEffects();
m_underflow = false;
m_timer.setInterval(100);
connect(&m_timer, &QTimer::timeout, this, &CallsignSampleProvider::timerElapsed);
}
int delayMs = CallsignDelayCache::instance().get(callsign);
qDebug() << "[" << m_callsign << "] [Delay " << delayMs << "ms]";
if (delayMs > 0)
{
int phaseDelayLength = (m_audioFormat.sampleRate() / 1000) * delayMs;
QVector<qint16> phaseDelay(phaseDelayLength * 2, 0);
audioInput->addSamples(phaseDelay);
}
}
int CallsignSampleProvider::readSamples(QVector<qint16> &samples, qint64 count)
{
int noOfSamples = mixer->readSamples(samples, count);
void CallsignSampleProvider::activeSilent(const QString &callsign, const QString &aircraftType)
{
m_callsign = callsign;
CallsignDelayCache::instance().initialise(callsign);
m_type = aircraftType;
m_decoder.resetState();
m_inUse = true;
setEffects(true);
m_underflow = true;
}
if (m_inUse && m_lastPacketLatch && audioInput->getBufferedBytes() == 0)
{
idle();
m_lastPacketLatch = false;
}
void CallsignSampleProvider::clear()
{
idle();
audioInput->clearBuffer();
}
if (m_inUse && !m_underflow && audioInput->getBufferedBytes() == 0)
{
qDebug() << "[" << m_callsign << "] [Delay++]";
CallsignDelayCache::instance().underflow(m_callsign);
m_underflow = true;
}
void CallsignSampleProvider::addOpusSamples(const IAudioDto &audioDto, float distanceRatio)
{
m_distanceRatio = distanceRatio;
return noOfSamples;
}
QVector<qint16> audio = decodeOpus(audioDto.audio);
audioInput->addSamples(audio);
m_lastPacketLatch = audioDto.lastPacket;
if (audioDto.lastPacket && !m_underflow)
CallsignDelayCache::instance().success(m_callsign);
void CallsignSampleProvider::timerElapsed()
{
if (m_inUse && audioInput->getBufferedBytes() == 0 && m_lastSamplesAddedUtc.msecsTo(QDateTime::currentDateTimeUtc()) > idleTimeoutMs)
{
idle();
}
}
m_lastSamplesAddedUtc = QDateTime::currentDateTimeUtc();
if (!m_timer.isActive()) { m_timer.start(); }
}
QString CallsignSampleProvider::type() const
{
return m_type;
}
void CallsignSampleProvider::addSilentSamples(const IAudioDto &audioDto)
{
// Disable all audio effects
setEffects(true);
void CallsignSampleProvider::active(const QString &callsign, const QString &aircraftType)
{
m_callsign = callsign;
CallsignDelayCache::instance().initialise(callsign);
m_type = aircraftType;
m_decoder.resetState();
m_inUse = true;
setEffects();
m_underflow = false;
// TODO audioInput->addSamples(decoderByteBuffer, 0, frameCount * 2);
m_lastPacketLatch = audioDto.lastPacket;
int delayMs = CallsignDelayCache::instance().get(callsign);
qDebug() << "[" << m_callsign << "] [Delay " << delayMs << "ms]";
if (delayMs > 0)
{
int phaseDelayLength = (m_audioFormat.sampleRate() / 1000) * delayMs;
QVector<qint16> phaseDelay(phaseDelayLength * 2, 0);
audioInput->addSamples(phaseDelay);
}
}
m_lastSamplesAddedUtc = QDateTime::currentDateTimeUtc();
if (!m_timer.isActive()) { m_timer.start(); }
}
void CallsignSampleProvider::activeSilent(const QString &callsign, const QString &aircraftType)
{
m_callsign = callsign;
CallsignDelayCache::instance().initialise(callsign);
m_type = aircraftType;
m_decoder.resetState();
m_inUse = true;
setEffects(true);
m_underflow = true;
}
QString CallsignSampleProvider::callsign() const
{
return m_callsign;
}
void CallsignSampleProvider::clear()
{
idle();
audioInput->clearBuffer();
}
void CallsignSampleProvider::idle()
{
m_timer.stop();
m_inUse = false;
setEffects();
m_callsign = QString();
m_type = QString();
}
void CallsignSampleProvider::addOpusSamples(const IAudioDto &audioDto, float distanceRatio)
{
m_distanceRatio = distanceRatio;
QVector<qint16> CallsignSampleProvider::decodeOpus(const QByteArray &opusData)
{
int decodedLength = 0;
QVector<qint16> decoded = m_decoder.decode(opusData, opusData.size(), &decodedLength);
return decoded;
}
QVector<qint16> audio = decodeOpus(audioDto.audio);
audioInput->addSamples(audio);
m_lastPacketLatch = audioDto.lastPacket;
if (audioDto.lastPacket && !m_underflow)
CallsignDelayCache::instance().success(m_callsign);
void CallsignSampleProvider::setEffects(bool noEffects)
{
if (noEffects || m_bypassEffects || !m_inUse)
{
crackleSoundProvider->setGain(0.0);
whiteNoise->setGain(0.0);
acBusNoise->setGain(0.0);
simpleCompressorEffect->setEnabled(false);
voiceEq->setBypassEffects(true);
}
else
{
float crackleFactor = (float)(((qExp(m_distanceRatio) * qPow(m_distanceRatio, -4.0)) / 350) - 0.00776652);
m_lastSamplesAddedUtc = QDateTime::currentDateTimeUtc();
if (!m_timer.isActive()) { m_timer.start(); }
}
if (crackleFactor < 0.0f) { crackleFactor = 0.0f; }
if (crackleFactor > 0.20f) { crackleFactor = 0.20f; }
void CallsignSampleProvider::addSilentSamples(const IAudioDto &audioDto)
{
// Disable all audio effects
setEffects(true);
crackleSoundProvider->setGain(crackleFactor * 2);
whiteNoise->setGain(whiteNoiseGainMin);
acBusNoise->setGain(acBusGainMin);
simpleCompressorEffect->setEnabled(true);
voiceEq->setBypassEffects(false);
voiceEq->setOutputGain(1.0 - crackleFactor * 3.7);
}
}
// TODO audioInput->addSamples(decoderByteBuffer, 0, frameCount * 2);
m_lastPacketLatch = audioDto.lastPacket;
void CallsignSampleProvider::setBypassEffects(bool bypassEffects)
{
m_bypassEffects = bypassEffects;
setEffects();
}
m_lastSamplesAddedUtc = QDateTime::currentDateTimeUtc();
if (!m_timer.isActive()) { m_timer.start(); }
}
bool CallsignSampleProvider::inUse() const
{
return m_inUse;
}
void CallsignSampleProvider::idle()
{
m_timer.stop();
m_inUse = false;
setEffects();
m_callsign = QString();
m_type = QString();
}
QVector<qint16> CallsignSampleProvider::decodeOpus(const QByteArray &opusData)
{
int decodedLength = 0;
QVector<qint16> decoded = m_decoder.decode(opusData, opusData.size(), &decodedLength);
return decoded;
}
void CallsignSampleProvider::setEffects(bool noEffects)
{
if (noEffects || m_bypassEffects || !m_inUse)
{
crackleSoundProvider->setGain(0.0);
whiteNoise->setGain(0.0);
acBusNoise->setGain(0.0);
simpleCompressorEffect->setEnabled(false);
voiceEq->setBypassEffects(true);
}
else
{
float crackleFactor = (float)(((qExp(m_distanceRatio) * qPow(m_distanceRatio, -4.0)) / 350) - 0.00776652);
if (crackleFactor < 0.0f) { crackleFactor = 0.0f; }
if (crackleFactor > 0.20f) { crackleFactor = 0.20f; }
crackleSoundProvider->setGain(crackleFactor * 2);
whiteNoise->setGain(whiteNoiseGainMin);
acBusNoise->setGain(acBusGainMin);
simpleCompressorEffect->setEnabled(true);
voiceEq->setBypassEffects(false);
voiceEq->setOutputGain(1.0 - crackleFactor * 3.7);
}
}
void CallsignSampleProvider::setBypassEffects(bool bypassEffects)
{
m_bypassEffects = bypassEffects;
setEffects();
}
bool CallsignSampleProvider::inUse() const
{
return m_inUse;
}
} // ns
} // ns
} // ns