diff --git a/app/main.cpp b/app/main.cpp index a843b4f10..e405a11df 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -35,7 +35,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo */ QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangel"); - QCoreApplication::setApplicationVersion("3.14.4"); + QCoreApplication::setApplicationVersion("3.14.5"); #if 1 qApp->setStyle(QStyleFactory::create("fusion")); diff --git a/appsrv/main.cpp b/appsrv/main.cpp index 3c82592f2..d0fbbdfac 100644 --- a/appsrv/main.cpp +++ b/appsrv/main.cpp @@ -56,7 +56,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangelSrv"); - QCoreApplication::setApplicationVersion("3.14.4"); + QCoreApplication::setApplicationVersion("3.14.5"); int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP}; std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int)); diff --git a/debian/changelog b/debian/changelog index 057c4dce7..d8a5a17ee 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +sdrangel (3.14.5-1) unstable; urgency=medium + + * DSD demod: allow audio rates integer multiples of 8k other than 48k + + -- Edouard Griffiths, F4EXB Sun, 29 Apr 2018 17:14:18 +0200 + sdrangel (3.14.4-1) unstable; urgency=medium * AM demod: squelch buffer to open at start of valid squelch diff --git a/plugins/channelrx/demoddsd/dsddecoder.cpp b/plugins/channelrx/demoddsd/dsddecoder.cpp index bc39c4b05..54c8d75e9 100644 --- a/plugins/channelrx/demoddsd/dsddecoder.cpp +++ b/plugins/channelrx/demoddsd/dsddecoder.cpp @@ -41,6 +41,11 @@ void DSDDecoder::set48k(bool to48k) m_decoder.setUpsampling(to48k ? 6 : 0); } +void DSDDecoder::setUpsampling(int upsampling) +{ + m_decoder.setUpsampling(upsampling); +} + void DSDDecoder::setBaudRate(int baudRate) { if (baudRate == 2400) diff --git a/plugins/channelrx/demoddsd/dsddecoder.h b/plugins/channelrx/demoddsd/dsddecoder.h index 0b283fa7f..b135a653c 100644 --- a/plugins/channelrx/demoddsd/dsddecoder.h +++ b/plugins/channelrx/demoddsd/dsddecoder.h @@ -72,6 +72,7 @@ public: void setSymbolPLLLock(bool pllLock) { m_decoder.setSymbolPLLLock(pllLock); } void useHPMbelib(bool useHP) { m_decoder.useHPMbelib(useHP); } void set48k(bool to48k); + void setUpsampling(int upsampling); private: DSDcc::DSDDecoder m_decoder; diff --git a/plugins/channelrx/demoddsd/dsddemod.cpp b/plugins/channelrx/demoddsd/dsddemod.cpp index 481716fb2..d16142854 100644 --- a/plugins/channelrx/demoddsd/dsddemod.cpp +++ b/plugins/channelrx/demoddsd/dsddemod.cpp @@ -238,7 +238,7 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto m_settings.m_volume * 10.0, m_settings.m_tdmaStereo ? 1 : 3, // left or both channels m_settings.m_highPassFilter, - m_audioSampleRate != 8000, // upsample to 48k unless native 8k + m_audioSampleRate/8000, // upsample from native 8k &m_audioFifo1); } @@ -255,7 +255,7 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto m_settings.m_volume * 10.0, m_settings.m_tdmaStereo ? 2 : 3, // right or both channels m_settings.m_highPassFilter, - m_audioSampleRate != 8000, // upsample to 48k unless native 8k + m_audioSampleRate/8000, // upsample from native 8k &m_audioFifo2); } @@ -412,14 +412,15 @@ bool DSDDemod::handleMessage(const Message& cmd) void DSDDemod::applyAudioSampleRate(int sampleRate) { - qDebug("DSDDemod::applyAudioSampleRate: %d", sampleRate); + int upsampling = sampleRate / 8000; - if ((sampleRate != 48000) && (sampleRate != 8000)) { - qWarning("DSDDemod::applyAudioSampleRate: audio does not work properly with sample rates other than 48 or 8 kS/s"); + qDebug("DSDDemod::applyAudioSampleRate: audio rate: %d upsample by %d", sampleRate, upsampling); + + if (sampleRate % 8000 != 0) { + qDebug("DSDDemod::applyAudioSampleRate: audio will sound best with sample rates that are integer multiples of 8 kS/s"); } - m_dsdDecoder.set48k(sampleRate != 8000); - + m_dsdDecoder.setUpsampling(upsampling); m_audioSampleRate = sampleRate; } diff --git a/plugins/channelrx/demoddsd/dsddemodplugin.cpp b/plugins/channelrx/demoddsd/dsddemodplugin.cpp index c4b190b5e..8403767d0 100644 --- a/plugins/channelrx/demoddsd/dsddemodplugin.cpp +++ b/plugins/channelrx/demoddsd/dsddemodplugin.cpp @@ -25,7 +25,7 @@ const PluginDescriptor DSDDemodPlugin::m_pluginDescriptor = { QString("DSD Demodulator"), - QString("3.14.4"), + QString("3.14.5"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/sdrbase/dsp/dspengine.cpp b/sdrbase/dsp/dspengine.cpp index 6fc5505b2..afa9c4453 100644 --- a/sdrbase/dsp/dspengine.cpp +++ b/sdrbase/dsp/dspengine.cpp @@ -164,10 +164,10 @@ void DSPEngine::pushMbeFrame( int mbeVolumeIndex, unsigned char channels, bool useHP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo) { - m_dvSerialEngine.pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upSample48k, audioFifo); + m_dvSerialEngine.pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upsampling, audioFifo); } #else void DSPEngine::pushMbeFrame( @@ -176,7 +176,7 @@ void DSPEngine::pushMbeFrame( int mbeVolumeIndex __attribute((unused)), unsigned char channels __attribute((unused)), bool useHP __attribute((unused)), - bool upSample48k __attribute((unused)), + int upsampling __attribute((unused)), AudioFifo *audioFifo __attribute((unused))) {} #endif diff --git a/sdrbase/dsp/dspengine.h b/sdrbase/dsp/dspengine.h index f99cd1346..f7438cf28 100644 --- a/sdrbase/dsp/dspengine.h +++ b/sdrbase/dsp/dspengine.h @@ -68,7 +68,7 @@ public: int mbeVolumeIndex, unsigned char channels, bool useHP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo); const QTimer& getMasterTimer() const { return m_masterTimer; } diff --git a/sdrbase/dsp/dvserialengine.cpp b/sdrbase/dsp/dvserialengine.cpp index d19b09b07..ddb4370b9 100644 --- a/sdrbase/dsp/dvserialengine.cpp +++ b/sdrbase/dsp/dvserialengine.cpp @@ -253,7 +253,7 @@ void DVSerialEngine::pushMbeFrame( int mbeVolumeIndex, unsigned char channels, bool useLP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo) { std::vector::iterator it = m_controllers.begin(); @@ -265,7 +265,7 @@ void DVSerialEngine::pushMbeFrame( { if (it->worker->hasFifo(audioFifo)) { - it->worker->pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useLP, upSample48k, audioFifo); + it->worker->pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useLP, upsampling, audioFifo); done = true; } else if (it->worker->isAvailable()) @@ -283,7 +283,7 @@ void DVSerialEngine::pushMbeFrame( int wNum = itAvail - m_controllers.begin(); qDebug("DVSerialEngine::pushMbeFrame: push %p on empty queue %d", audioFifo, wNum); - itAvail->worker->pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useLP, upSample48k, audioFifo); + itAvail->worker->pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useLP, upsampling, audioFifo); } else { diff --git a/sdrbase/dsp/dvserialengine.h b/sdrbase/dsp/dvserialengine.h index 24b50bea7..dfc3d1520 100644 --- a/sdrbase/dsp/dvserialengine.h +++ b/sdrbase/dsp/dvserialengine.h @@ -49,7 +49,7 @@ public: int mbeVolumeIndex, unsigned char channels, bool useHP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo); private: diff --git a/sdrbase/dsp/dvserialworker.cpp b/sdrbase/dsp/dvserialworker.cpp index 9d5d1bc2c..0423f48b6 100644 --- a/sdrbase/dsp/dvserialworker.cpp +++ b/sdrbase/dsp/dvserialworker.cpp @@ -86,8 +86,11 @@ void DVSerialWorker::handleInputMessages() if (m_dvController.decode(m_dvAudioSamples, decodeMsg->getMbeFrame(), decodeMsg->getMbeRate(), dBVolume)) { - if (decodeMsg->getUpsample48k()) { - upsample6(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels()); + int upsampling = decodeMsg->getUpsampling(); + upsampling = upsampling > 6 ? 6 : upsampling < 1 ? 1 : upsampling; + + if (upsampling > 1) { + upsample(upsampling, m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels()); } else { noUpsample(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels()); } @@ -121,11 +124,11 @@ void DVSerialWorker::pushMbeFrame(const unsigned char *mbeFrame, int mbeVolumeIndex, unsigned char channels, bool useHP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo) { m_audioFifo = audioFifo; - m_inputMessageQueue.push(MsgMbeDecode::create(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upSample48k, audioFifo)); + m_inputMessageQueue.push(MsgMbeDecode::create(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upsampling, audioFifo)); } bool DVSerialWorker::isAvailable() @@ -170,6 +173,34 @@ void DVSerialWorker::upsample6(short *in, int nbSamplesIn, unsigned char channel } } +void DVSerialWorker::upsample(int upsampling, short *in, int nbSamplesIn, unsigned char channels) +{ + for (int i = 0; i < nbSamplesIn; i++) + { + int cur = (int) in[i]; + int prev = (int) m_upsamplerLastValue; + qint16 upsample; + + for (int j = 1; j <= upsampling; j++) + { + upsample = m_upsampleFilter.run((qint16) ((cur*j + prev*(upsampling-j)) / upsampling)); + m_audioBuffer[m_audioBufferFill].l = channels & 1 ? upsample : 0; + m_audioBuffer[m_audioBufferFill].r = (channels>>1) & 1 ? upsample : 0; + + if (m_audioBufferFill < m_audioBuffer.size() - 1) + { + ++m_audioBufferFill; + } + else + { + qDebug("DVSerialWorker::upsample6: audio buffer is full check its size"); + } + } + + m_upsamplerLastValue = in[i]; + } +} + void DVSerialWorker::noUpsample(short *in, int nbSamplesIn, unsigned char channels) { for (int i = 0; i < nbSamplesIn; i++) diff --git a/sdrbase/dsp/dvserialworker.h b/sdrbase/dsp/dvserialworker.h index c38b7dfeb..87f2d44ef 100644 --- a/sdrbase/dsp/dvserialworker.h +++ b/sdrbase/dsp/dvserialworker.h @@ -56,7 +56,7 @@ public: int getVolumeIndex() const { return m_volumeIndex; } unsigned char getChannels() const { return m_channels % 4; } bool getUseHP() const { return m_useHP; } - bool getUpsample48k() const { return m_upSample48k; } + int getUpsampling() const { return m_upsampling; } AudioFifo *getAudioFifo() { return m_audioFifo; } static MsgMbeDecode* create( @@ -65,10 +65,10 @@ public: int volumeIndex, unsigned char channels, bool useHP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo) { - return new MsgMbeDecode(mbeFrame, (SerialDV::DVRate) mbeRateIndex, volumeIndex, channels, useHP, upSample48k, audioFifo); + return new MsgMbeDecode(mbeFrame, (SerialDV::DVRate) mbeRateIndex, volumeIndex, channels, useHP, upsampling, audioFifo); } private: @@ -77,7 +77,7 @@ public: int m_volumeIndex; unsigned char m_channels; bool m_useHP; - bool m_upSample48k; + int m_upsampling; AudioFifo *m_audioFifo; MsgMbeDecode(const unsigned char *mbeFrame, @@ -85,14 +85,14 @@ public: int volumeIndex, unsigned char channels, bool useHP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo) : Message(), m_mbeRate(mbeRate), m_volumeIndex(volumeIndex), m_channels(channels), m_useHP(useHP), - m_upSample48k(upSample48k), + m_upsampling(upsampling), m_audioFifo(audioFifo) { memcpy((void *) m_mbeFrame, (const void *) mbeFrame, SerialDV::DVController::getNbMbeBytes(m_mbeRate)); @@ -107,7 +107,7 @@ public: int mbeVolumeIndex, unsigned char channels, bool useHP, - bool upSample48k, + int upsampling, AudioFifo *audioFifo); bool open(const std::string& serialDevice); @@ -136,6 +136,7 @@ public slots: private: //void upsample6(short *in, short *out, int nbSamplesIn); void upsample6(short *in, int nbSamplesIn, unsigned char channels); + void upsample(int upsampling, short *in, int nbSamplesIn, unsigned char channels); void noUpsample(short *in, int nbSamplesIn, unsigned char channels); SerialDV::DVController m_dvController;