2017-01-02 21:07:43 -05:00
|
|
|
// Copyright (c) Charles J. Cliffe
|
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
|
2015-11-16 23:49:54 -05:00
|
|
|
#include "ModemAnalog.h"
|
|
|
|
|
2016-08-13 14:50:20 -04:00
|
|
|
ModemAnalog::ModemAnalog() : Modem(), aOutputCeil(1), aOutputCeilMA(1), aOutputCeilMAA(1) {
|
2015-11-16 23:49:54 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-11-18 23:40:30 -05:00
|
|
|
std::string ModemAnalog::getType() {
|
|
|
|
return "analog";
|
|
|
|
}
|
|
|
|
|
2016-02-04 18:05:33 -05:00
|
|
|
int ModemAnalog::checkSampleRate(long long sampleRate, int /* audioSampleRate */) {
|
2015-12-01 00:59:11 -05:00
|
|
|
if (sampleRate < MIN_BANDWIDTH) {
|
|
|
|
return MIN_BANDWIDTH;
|
2015-11-22 23:38:26 -05:00
|
|
|
}
|
2015-11-22 19:56:25 -05:00
|
|
|
return sampleRate;
|
|
|
|
}
|
|
|
|
|
2015-11-16 23:49:54 -05:00
|
|
|
ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) {
|
|
|
|
ModemKitAnalog *akit = new ModemKitAnalog;
|
|
|
|
|
|
|
|
// stop-band attenuation [dB]
|
|
|
|
float As = 60.0f;
|
|
|
|
|
|
|
|
akit->sampleRate = sampleRate;
|
|
|
|
akit->audioSampleRate = audioSampleRate;
|
|
|
|
akit->audioResampleRatio = double(audioSampleRate) / double(sampleRate);
|
|
|
|
akit->audioResampler = msresamp_rrrf_create(akit->audioResampleRatio, As);
|
|
|
|
|
|
|
|
return akit;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModemAnalog::disposeKit(ModemKit *kit) {
|
|
|
|
ModemKitAnalog *akit = (ModemKitAnalog *)kit;
|
|
|
|
|
|
|
|
msresamp_rrrf_destroy(akit->audioResampler);
|
2015-11-18 21:09:51 -05:00
|
|
|
delete akit;
|
2015-11-16 23:49:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void ModemAnalog::initOutputBuffers(ModemKitAnalog *akit, ModemIQData *input) {
|
|
|
|
bufSize = input->data.size();
|
|
|
|
|
|
|
|
if (!bufSize) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
double audio_resample_ratio = akit->audioResampleRatio;
|
|
|
|
|
2016-06-01 19:42:34 -04:00
|
|
|
size_t audio_out_size = (size_t)ceil((double) (bufSize) * audio_resample_ratio) + 512;
|
2015-11-16 23:49:54 -05:00
|
|
|
|
|
|
|
if (demodOutputData.size() != bufSize) {
|
|
|
|
if (demodOutputData.capacity() < bufSize) {
|
|
|
|
demodOutputData.reserve(bufSize);
|
|
|
|
}
|
|
|
|
demodOutputData.resize(bufSize);
|
|
|
|
}
|
|
|
|
if (resampledOutputData.size() != audio_out_size) {
|
|
|
|
if (resampledOutputData.capacity() < audio_out_size) {
|
|
|
|
resampledOutputData.reserve(audio_out_size);
|
|
|
|
}
|
|
|
|
resampledOutputData.resize(audio_out_size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ModemAnalog::buildAudioOutput(ModemKitAnalog *akit, AudioThreadInput *audioOut, bool autoGain) {
|
|
|
|
unsigned int numAudioWritten;
|
|
|
|
|
|
|
|
if (autoGain) {
|
2016-06-01 19:42:34 -04:00
|
|
|
aOutputCeilMA = aOutputCeilMA + (aOutputCeil - aOutputCeilMA) * 0.025f;
|
|
|
|
aOutputCeilMAA = aOutputCeilMAA + (aOutputCeilMA - aOutputCeilMAA) * 0.025f;
|
2015-11-16 23:49:54 -05:00
|
|
|
aOutputCeil = 0;
|
|
|
|
|
2016-02-04 18:05:33 -05:00
|
|
|
for (size_t i = 0; i < bufSize; i++) {
|
2015-11-16 23:49:54 -05:00
|
|
|
if (demodOutputData[i] > aOutputCeil) {
|
|
|
|
aOutputCeil = demodOutputData[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-01 19:42:34 -04:00
|
|
|
float gain = 0.5f / aOutputCeilMAA;
|
2015-11-16 23:49:54 -05:00
|
|
|
|
2016-02-04 18:05:33 -05:00
|
|
|
for (size_t i = 0; i < bufSize; i++) {
|
2015-11-16 23:49:54 -05:00
|
|
|
demodOutputData[i] *= gain;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
msresamp_rrrf_execute(akit->audioResampler, &demodOutputData[0], demodOutputData.size(), &resampledOutputData[0], &numAudioWritten);
|
|
|
|
|
|
|
|
audioOut->channels = 1;
|
2015-11-17 23:23:23 -05:00
|
|
|
audioOut->sampleRate = akit->audioSampleRate;
|
2015-11-16 23:49:54 -05:00
|
|
|
audioOut->data.assign(resampledOutputData.begin(), resampledOutputData.begin() + numAudioWritten);
|
|
|
|
}
|
2015-11-20 20:46:25 -05:00
|
|
|
|
|
|
|
std::vector<float> *ModemAnalog::getDemodOutputData() {
|
|
|
|
return &demodOutputData;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<float> *ModemAnalog::getResampledOutputData() {
|
|
|
|
return &resampledOutputData;
|
|
|
|
}
|