summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorf4exb <f4exb06@gmail.com>2019-02-24 03:28:54 +0100
committerf4exb <f4exb06@gmail.com>2019-02-24 03:28:54 +0100
commitc0e2d2d81fd822f9ddd00ed70308f0adbd88042e (patch)
tree62ac7c32b1859c400ff30d6d22c09715ab8faa53 /plugins
parente34faee3cea49b67084017fd6bac7b44453f38f7 (diff)
FreeDV modulator: 2400A from all modulations
Diffstat (limited to 'plugins')
-rw-r--r--plugins/channeltx/modfreedv/freedvmod.cpp224
-rw-r--r--plugins/channeltx/modfreedv/freedvmod.h2
-rw-r--r--plugins/channeltx/modfreedv/freedvmodsettings.cpp2
3 files changed, 101 insertions, 127 deletions
diff --git a/plugins/channeltx/modfreedv/freedvmod.cpp b/plugins/channeltx/modfreedv/freedvmod.cpp
index 5cb01756f..0ececd979 100644
--- a/plugins/channeltx/modfreedv/freedvmod.cpp
+++ b/plugins/channeltx/modfreedv/freedvmod.cpp
@@ -57,7 +57,7 @@ FreeDVMod::FreeDVMod(DeviceSinkAPI *deviceAPI) :
ChannelSourceAPI(m_channelIdURI),
m_deviceAPI(deviceAPI),
m_basebandSampleRate(48000),
- m_outputSampleRate(48000),
+ m_outputSampleRate(48000), // default 2400A mode
m_inputFrequencyOffset(0),
m_lowCutoff(0.0),
m_hiCutoff(6000.0),
@@ -69,7 +69,7 @@ FreeDVMod::FreeDVMod(DeviceSinkAPI *deviceAPI) :
m_settingsMutex(QMutex::Recursive),
m_fileSize(0),
m_recordLength(0),
- m_sampleRate(48000),
+ m_inputSampleRate(8000), // all modes take 8000 S/s input
m_levelCalcCount(0),
m_peakLevel(0.0f),
m_levelSum(0.0f),
@@ -100,10 +100,10 @@ FreeDVMod::FreeDVMod(DeviceSinkAPI *deviceAPI) :
m_magsq = 0.0;
- m_toneNco.setFreq(1000.0, m_audioSampleRate);
+ m_toneNco.setFreq(1000.0, m_inputSampleRate);
// CW keyer
- m_cwKeyer.setSampleRate(48000);
+ m_cwKeyer.setSampleRate(m_inputSampleRate);
m_cwKeyer.setWPM(13);
m_cwKeyer.setMode(CWKeyerSettings::CWNone);
@@ -214,153 +214,125 @@ void FreeDVMod::pullAF(Complex& sample)
int decim = 1<<(m_settings.m_spanLog2 - 1);
unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
- switch (m_settings.m_modAFInput)
+ if (m_iModem >= m_nNomModemSamples)
{
- case FreeDVModSettings::FreeDVModInputTone:
- sample = m_toneNco.nextIQ();
- break;
- case FreeDVModSettings::FreeDVModInputFile:
- if (m_iModem >= m_nNomModemSamples)
+ switch (m_settings.m_modAFInput)
{
- if (m_ifstream.is_open())
+ case FreeDVModSettings::FreeDVModInputTone:
+ for (int i = 0; i < m_nSpeechSamples; i++) {
+ m_speechIn[i] = m_toneNco.next() * 32768.0f * m_settings.m_volumeFactor;
+ }
+ freedv_tx(m_freeDV, m_modOut, m_speechIn);
+ break;
+ case FreeDVModSettings::FreeDVModInputFile:
+ if (m_iModem >= m_nNomModemSamples)
{
- std::fill(m_speechIn, m_speechIn + m_nSpeechSamples, 0);
-
- if (m_ifstream.eof())
+ if (m_ifstream.is_open())
{
- if (m_settings.m_playLoop)
+ std::fill(m_speechIn, m_speechIn + m_nSpeechSamples, 0);
+
+ if (m_ifstream.eof())
{
- m_ifstream.clear();
- m_ifstream.seekg(0, std::ios::beg);
+ if (m_settings.m_playLoop)
+ {
+ m_ifstream.clear();
+ m_ifstream.seekg(0, std::ios::beg);
+ }
}
- }
- if (m_ifstream.eof())
+ if (m_ifstream.eof())
+ {
+ std::fill(m_modOut, m_modOut + m_nNomModemSamples, 0);
+ }
+ else
+ {
+
+ m_ifstream.read(reinterpret_cast<char*>(m_speechIn), sizeof(int16_t) * m_nSpeechSamples);
+
+ if (m_settings.m_volumeFactor != 1.0)
+ {
+ for (int i = 0; i < m_nSpeechSamples; i++) {
+ m_speechIn[i] *= m_settings.m_volumeFactor;
+ }
+ }
+
+ freedv_tx(m_freeDV, m_modOut, m_speechIn);
+ }
+ }
+ else
{
std::fill(m_modOut, m_modOut + m_nNomModemSamples, 0);
}
+ }
+ break;
+ case FreeDVModSettings::FreeDVModInputAudio:
+ for (int i = 0; i < m_nSpeechSamples; i++) {
+ m_speechIn[i] = (m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) * (m_settings.m_volumeFactor / 2);
+ }
+ freedv_tx(m_freeDV, m_modOut, m_speechIn);
+ break;
+ case FreeDVModSettings::FreeDVModInputCWTone:
+ for (int i = 0; i < m_nSpeechSamples; i++)
+ {
+ Real fadeFactor;
+
+ if (m_cwKeyer.getSample())
+ {
+ m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
+ m_speechIn[i] = m_toneNco.next() * 32768.0f * fadeFactor * m_settings.m_volumeFactor;
+ }
else
{
-
- m_ifstream.read(reinterpret_cast<char*>(m_speechIn), sizeof(int16_t) * m_nSpeechSamples);
-
- if (m_settings.m_volumeFactor != 1.0)
+ if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
{
- for (int i = 0; i < m_nSpeechSamples; i++) {
- m_speechIn[i] *= m_settings.m_volumeFactor;
- }
+ m_speechIn[i] = m_toneNco.next() * 32768.0f * fadeFactor * m_settings.m_volumeFactor;
+ }
+ else
+ {
+ m_speechIn[i] = 0;
+ m_toneNco.setPhase(0);
}
-
- freedv_tx(m_freeDV, m_modOut, m_speechIn);
}
}
- else
- {
- std::fill(m_modOut, m_modOut + m_nNomModemSamples, 0);
- }
-
- m_iModem = 0;
+ freedv_tx(m_freeDV, m_modOut, m_speechIn);
+ break;
+ case FreeDVModSettings::FreeDVModInputNone:
+ default:
+ std::fill(m_speechIn, m_speechIn + m_nSpeechSamples, 0);
+ freedv_tx(m_freeDV, m_modOut, m_speechIn);
+ break;
}
- ci.real(m_modOut[m_iModem++] / (SDR_TX_SCALEF/8.0f));
- ci.imag(0.0f);
- break;
- case FreeDVModSettings::FreeDVModInputAudio:
- ci.real(((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / (2.0 * SDR_TX_SCALEF)) * m_settings.m_volumeFactor);
- ci.imag(0.0f);
- break;
- case FreeDVModSettings::FreeDVModInputCWTone:
- Real fadeFactor;
+ m_iModem = 0;
+ }
- if (m_cwKeyer.getSample())
- {
- m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
- sample = m_toneNco.nextIQ() * fadeFactor;
- }
- else
- {
- if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
- {
- sample = m_toneNco.nextIQ() * fadeFactor;
- }
- else
- {
- sample.real(0.0f);
- sample.imag(0.0f);
- m_toneNco.setPhase(0);
- }
- }
+ ci.real(m_modOut[m_iModem++] / (SDR_TX_SCALEF/8.0f));
+ ci.imag(0.0f);
- break;
- case FreeDVModSettings::FreeDVModInputNone:
- default:
- sample.real(0.0f);
- sample.imag(0.0f);
- break;
- }
+ n_out = m_SSBFilter->runSSB(ci, &filtered, true); // USB
- if ((m_settings.m_modAFInput == FreeDVModSettings::FreeDVModInputFile)
- || (m_settings.m_modAFInput == FreeDVModSettings::FreeDVModInputAudio)) // real audio
+ if (n_out > 0)
{
- n_out = m_SSBFilter->runSSB(ci, &filtered, true); // USB
+ memcpy((void *) m_SSBFilterBuffer, (const void *) filtered, n_out*sizeof(Complex));
+ m_SSBFilterBufferIndex = 0;
- if (n_out > 0)
+ for (int i = 0; i < n_out; i++)
{
- memcpy((void *) m_SSBFilterBuffer, (const void *) filtered, n_out*sizeof(Complex));
- m_SSBFilterBufferIndex = 0;
- }
+ // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
+ // smart decimation with bit gain using float arithmetic (23 bits significand)
- sample = m_SSBFilterBuffer[m_SSBFilterBufferIndex];
- m_SSBFilterBufferIndex++;
+ m_sum += filtered[i];
- if (n_out > 0)
- {
- for (int i = 0; i < n_out; i++)
+ if (!(m_undersampleCount++ & decim_mask))
{
- // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display
- // smart decimation with bit gain using float arithmetic (23 bits significand)
-
- m_sum += filtered[i];
-
- if (!(m_undersampleCount++ & decim_mask))
- {
- Real avgr = (m_sum.real() / decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
- Real avgi = (m_sum.imag() / decim) * 0.891235351562f * SDR_TX_SCALEF;
- m_sampleBuffer.push_back(Sample(avgr, avgi));
- m_sum.real(0.0);
- m_sum.imag(0.0);
- }
+ Real avgr = (m_sum.real() / decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
+ Real avgi = (m_sum.imag() / decim) * 0.891235351562f * SDR_TX_SCALEF;
+ m_sampleBuffer.push_back(Sample(avgr, avgi));
+ m_sum.real(0.0);
+ m_sum.imag(0.0);
}
- }
- } // Real audio
- else if ((m_settings.m_modAFInput == FreeDVModSettings::FreeDVModInputTone)
- || (m_settings.m_modAFInput == FreeDVModSettings::FreeDVModInputCWTone)) // tone
- {
- m_sum += sample;
-
- if (!(m_undersampleCount++ & decim_mask))
- {
- Real avgr = (m_sum.real() / decim) * 0.891235351562f * SDR_TX_SCALEF; //scaling at -1 dB to account for possible filter overshoot
- Real avgi = (m_sum.imag() / decim) * 0.891235351562f * SDR_TX_SCALEF;
- m_sampleBuffer.push_back(Sample(avgr, avgi));
- m_sum.real(0.0);
- m_sum.imag(0.0);
- }
-
- if (m_sumCount < (m_ssbFftLen>>1))
- {
- n_out = 0;
- m_sumCount++;
- }
- else
- {
- n_out = m_sumCount;
- m_sumCount = 0;
}
- }
- if (n_out > 0)
- {
if (m_sampleSink != 0)
{
m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), true); // SSB
@@ -368,6 +340,8 @@ void FreeDVMod::pullAF(Complex& sample)
m_sampleBuffer.clear();
}
+
+ sample = m_SSBFilterBuffer[m_SSBFilterBufferIndex++];
}
void FreeDVMod::calculateLevel(Complex& sample)
@@ -514,8 +488,8 @@ void FreeDVMod::openFileStream()
m_fileSize = m_ifstream.tellg();
m_ifstream.seekg(0,std::ios_base::beg);
- m_sampleRate = 48000; // fixed rate
- m_recordLength = m_fileSize / (sizeof(Real) * m_sampleRate);
+ m_inputSampleRate = 48000; // fixed rate
+ m_recordLength = m_fileSize / (sizeof(Real) * m_inputSampleRate);
qDebug() << "FreeDVMod::openFileStream: " << m_fileName.toStdString().c_str()
<< " fileSize: " << m_fileSize << "bytes"
@@ -524,7 +498,7 @@ void FreeDVMod::openFileStream()
if (getMessageQueueToGUI())
{
MsgReportFileSourceStreamData *report;
- report = MsgReportFileSourceStreamData::create(m_sampleRate, m_recordLength);
+ report = MsgReportFileSourceStreamData::create(m_inputSampleRate, m_recordLength);
getMessageQueueToGUI()->push(report);
}
}
@@ -535,7 +509,7 @@ void FreeDVMod::seekFileStream(int seekPercentage)
if (m_ifstream.is_open())
{
- int seekPoint = ((m_recordLength * seekPercentage) / 100) * m_sampleRate;
+ int seekPoint = ((m_recordLength * seekPercentage) / 100) * m_inputSampleRate;
seekPoint *= sizeof(Real);
m_ifstream.clear();
m_ifstream.seekg(seekPoint, std::ios::beg);
diff --git a/plugins/channeltx/modfreedv/freedvmod.h b/plugins/channeltx/modfreedv/freedvmod.h
index bbdc66c2e..d5fc2a489 100644
--- a/plugins/channeltx/modfreedv/freedvmod.h
+++ b/plugins/channeltx/modfreedv/freedvmod.h
@@ -305,7 +305,7 @@ private:
QString m_fileName;
quint64 m_fileSize; //!< raw file size (bytes)
quint32 m_recordLength; //!< record length in seconds computed from file size
- int m_sampleRate;
+ int m_inputSampleRate; //!< speech (input) sample rate (fixed 8000 S/s)
quint32 m_levelCalcCount;
Real m_peakLevel;
diff --git a/plugins/channeltx/modfreedv/freedvmodsettings.cpp b/plugins/channeltx/modfreedv/freedvmodsettings.cpp
index 4938980f3..8ec0566af 100644
--- a/plugins/channeltx/modfreedv/freedvmodsettings.cpp
+++ b/plugins/channeltx/modfreedv/freedvmodsettings.cpp
@@ -199,7 +199,7 @@ int FreeDVModSettings::getLowCutoff(FreeDVMode freeDVMode)
break;
case FreeDVModSettings::FreeDVMode2400A: // C4FM WB
default:
- return 50.0;
+ return 0.0;
break;
}
}