mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-09-27 15:26:33 -04:00
DSD demod: allow use of audio rates that are integer multiples of 8k other than 48k (x2,3,4,5)
This commit is contained in:
parent
114e70b595
commit
2efa7ab594
@ -35,7 +35,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
|||||||
*/
|
*/
|
||||||
QCoreApplication::setOrganizationName("f4exb");
|
QCoreApplication::setOrganizationName("f4exb");
|
||||||
QCoreApplication::setApplicationName("SDRangel");
|
QCoreApplication::setApplicationName("SDRangel");
|
||||||
QCoreApplication::setApplicationVersion("3.14.4");
|
QCoreApplication::setApplicationVersion("3.14.5");
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
qApp->setStyle(QStyleFactory::create("fusion"));
|
qApp->setStyle(QStyleFactory::create("fusion"));
|
||||||
|
@ -56,7 +56,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo
|
|||||||
|
|
||||||
QCoreApplication::setOrganizationName("f4exb");
|
QCoreApplication::setOrganizationName("f4exb");
|
||||||
QCoreApplication::setApplicationName("SDRangelSrv");
|
QCoreApplication::setApplicationName("SDRangelSrv");
|
||||||
QCoreApplication::setApplicationVersion("3.14.4");
|
QCoreApplication::setApplicationVersion("3.14.5");
|
||||||
|
|
||||||
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
||||||
std::vector<int> vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
|
std::vector<int> vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
|
||||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -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 <f4exb06@gmail.com> Sun, 29 Apr 2018 17:14:18 +0200
|
||||||
|
|
||||||
sdrangel (3.14.4-1) unstable; urgency=medium
|
sdrangel (3.14.4-1) unstable; urgency=medium
|
||||||
|
|
||||||
* AM demod: squelch buffer to open at start of valid squelch
|
* AM demod: squelch buffer to open at start of valid squelch
|
||||||
|
@ -41,6 +41,11 @@ void DSDDecoder::set48k(bool to48k)
|
|||||||
m_decoder.setUpsampling(to48k ? 6 : 0);
|
m_decoder.setUpsampling(to48k ? 6 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DSDDecoder::setUpsampling(int upsampling)
|
||||||
|
{
|
||||||
|
m_decoder.setUpsampling(upsampling);
|
||||||
|
}
|
||||||
|
|
||||||
void DSDDecoder::setBaudRate(int baudRate)
|
void DSDDecoder::setBaudRate(int baudRate)
|
||||||
{
|
{
|
||||||
if (baudRate == 2400)
|
if (baudRate == 2400)
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
void setSymbolPLLLock(bool pllLock) { m_decoder.setSymbolPLLLock(pllLock); }
|
void setSymbolPLLLock(bool pllLock) { m_decoder.setSymbolPLLLock(pllLock); }
|
||||||
void useHPMbelib(bool useHP) { m_decoder.useHPMbelib(useHP); }
|
void useHPMbelib(bool useHP) { m_decoder.useHPMbelib(useHP); }
|
||||||
void set48k(bool to48k);
|
void set48k(bool to48k);
|
||||||
|
void setUpsampling(int upsampling);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DSDcc::DSDDecoder m_decoder;
|
DSDcc::DSDDecoder m_decoder;
|
||||||
|
@ -238,7 +238,7 @@ void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
|
|||||||
m_settings.m_volume * 10.0,
|
m_settings.m_volume * 10.0,
|
||||||
m_settings.m_tdmaStereo ? 1 : 3, // left or both channels
|
m_settings.m_tdmaStereo ? 1 : 3, // left or both channels
|
||||||
m_settings.m_highPassFilter,
|
m_settings.m_highPassFilter,
|
||||||
m_audioSampleRate != 8000, // upsample to 48k unless native 8k
|
m_audioSampleRate/8000, // upsample from native 8k
|
||||||
&m_audioFifo1);
|
&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_volume * 10.0,
|
||||||
m_settings.m_tdmaStereo ? 2 : 3, // right or both channels
|
m_settings.m_tdmaStereo ? 2 : 3, // right or both channels
|
||||||
m_settings.m_highPassFilter,
|
m_settings.m_highPassFilter,
|
||||||
m_audioSampleRate != 8000, // upsample to 48k unless native 8k
|
m_audioSampleRate/8000, // upsample from native 8k
|
||||||
&m_audioFifo2);
|
&m_audioFifo2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,14 +412,15 @@ bool DSDDemod::handleMessage(const Message& cmd)
|
|||||||
|
|
||||||
void DSDDemod::applyAudioSampleRate(int sampleRate)
|
void DSDDemod::applyAudioSampleRate(int sampleRate)
|
||||||
{
|
{
|
||||||
qDebug("DSDDemod::applyAudioSampleRate: %d", sampleRate);
|
int upsampling = sampleRate / 8000;
|
||||||
|
|
||||||
if ((sampleRate != 48000) && (sampleRate != 8000)) {
|
qDebug("DSDDemod::applyAudioSampleRate: audio rate: %d upsample by %d", sampleRate, upsampling);
|
||||||
qWarning("DSDDemod::applyAudioSampleRate: audio does not work properly with sample rates other than 48 or 8 kS/s");
|
|
||||||
|
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;
|
m_audioSampleRate = sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
const PluginDescriptor DSDDemodPlugin::m_pluginDescriptor = {
|
const PluginDescriptor DSDDemodPlugin::m_pluginDescriptor = {
|
||||||
QString("DSD Demodulator"),
|
QString("DSD Demodulator"),
|
||||||
QString("3.14.4"),
|
QString("3.14.5"),
|
||||||
QString("(c) Edouard Griffiths, F4EXB"),
|
QString("(c) Edouard Griffiths, F4EXB"),
|
||||||
QString("https://github.com/f4exb/sdrangel"),
|
QString("https://github.com/f4exb/sdrangel"),
|
||||||
true,
|
true,
|
||||||
|
@ -164,10 +164,10 @@ void DSPEngine::pushMbeFrame(
|
|||||||
int mbeVolumeIndex,
|
int mbeVolumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useHP,
|
bool useHP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo)
|
AudioFifo *audioFifo)
|
||||||
{
|
{
|
||||||
m_dvSerialEngine.pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upSample48k, audioFifo);
|
m_dvSerialEngine.pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upsampling, audioFifo);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void DSPEngine::pushMbeFrame(
|
void DSPEngine::pushMbeFrame(
|
||||||
@ -176,7 +176,7 @@ void DSPEngine::pushMbeFrame(
|
|||||||
int mbeVolumeIndex __attribute((unused)),
|
int mbeVolumeIndex __attribute((unused)),
|
||||||
unsigned char channels __attribute((unused)),
|
unsigned char channels __attribute((unused)),
|
||||||
bool useHP __attribute((unused)),
|
bool useHP __attribute((unused)),
|
||||||
bool upSample48k __attribute((unused)),
|
int upsampling __attribute((unused)),
|
||||||
AudioFifo *audioFifo __attribute((unused)))
|
AudioFifo *audioFifo __attribute((unused)))
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,7 +68,7 @@ public:
|
|||||||
int mbeVolumeIndex,
|
int mbeVolumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useHP,
|
bool useHP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo);
|
AudioFifo *audioFifo);
|
||||||
|
|
||||||
const QTimer& getMasterTimer() const { return m_masterTimer; }
|
const QTimer& getMasterTimer() const { return m_masterTimer; }
|
||||||
|
@ -253,7 +253,7 @@ void DVSerialEngine::pushMbeFrame(
|
|||||||
int mbeVolumeIndex,
|
int mbeVolumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useLP,
|
bool useLP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo)
|
AudioFifo *audioFifo)
|
||||||
{
|
{
|
||||||
std::vector<DVSerialController>::iterator it = m_controllers.begin();
|
std::vector<DVSerialController>::iterator it = m_controllers.begin();
|
||||||
@ -265,7 +265,7 @@ void DVSerialEngine::pushMbeFrame(
|
|||||||
{
|
{
|
||||||
if (it->worker->hasFifo(audioFifo))
|
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;
|
done = true;
|
||||||
}
|
}
|
||||||
else if (it->worker->isAvailable())
|
else if (it->worker->isAvailable())
|
||||||
@ -283,7 +283,7 @@ void DVSerialEngine::pushMbeFrame(
|
|||||||
int wNum = itAvail - m_controllers.begin();
|
int wNum = itAvail - m_controllers.begin();
|
||||||
|
|
||||||
qDebug("DVSerialEngine::pushMbeFrame: push %p on empty queue %d", audioFifo, wNum);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
int mbeVolumeIndex,
|
int mbeVolumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useHP,
|
bool useHP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo);
|
AudioFifo *audioFifo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -86,8 +86,11 @@ void DVSerialWorker::handleInputMessages()
|
|||||||
|
|
||||||
if (m_dvController.decode(m_dvAudioSamples, decodeMsg->getMbeFrame(), decodeMsg->getMbeRate(), dBVolume))
|
if (m_dvController.decode(m_dvAudioSamples, decodeMsg->getMbeFrame(), decodeMsg->getMbeRate(), dBVolume))
|
||||||
{
|
{
|
||||||
if (decodeMsg->getUpsample48k()) {
|
int upsampling = decodeMsg->getUpsampling();
|
||||||
upsample6(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels());
|
upsampling = upsampling > 6 ? 6 : upsampling < 1 ? 1 : upsampling;
|
||||||
|
|
||||||
|
if (upsampling > 1) {
|
||||||
|
upsample(upsampling, m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels());
|
||||||
} else {
|
} else {
|
||||||
noUpsample(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels());
|
noUpsample(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels());
|
||||||
}
|
}
|
||||||
@ -121,11 +124,11 @@ void DVSerialWorker::pushMbeFrame(const unsigned char *mbeFrame,
|
|||||||
int mbeVolumeIndex,
|
int mbeVolumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useHP,
|
bool useHP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo)
|
AudioFifo *audioFifo)
|
||||||
{
|
{
|
||||||
m_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()
|
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)
|
void DVSerialWorker::noUpsample(short *in, int nbSamplesIn, unsigned char channels)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < nbSamplesIn; i++)
|
for (int i = 0; i < nbSamplesIn; i++)
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
int getVolumeIndex() const { return m_volumeIndex; }
|
int getVolumeIndex() const { return m_volumeIndex; }
|
||||||
unsigned char getChannels() const { return m_channels % 4; }
|
unsigned char getChannels() const { return m_channels % 4; }
|
||||||
bool getUseHP() const { return m_useHP; }
|
bool getUseHP() const { return m_useHP; }
|
||||||
bool getUpsample48k() const { return m_upSample48k; }
|
int getUpsampling() const { return m_upsampling; }
|
||||||
AudioFifo *getAudioFifo() { return m_audioFifo; }
|
AudioFifo *getAudioFifo() { return m_audioFifo; }
|
||||||
|
|
||||||
static MsgMbeDecode* create(
|
static MsgMbeDecode* create(
|
||||||
@ -65,10 +65,10 @@ public:
|
|||||||
int volumeIndex,
|
int volumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useHP,
|
bool useHP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo)
|
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:
|
private:
|
||||||
@ -77,7 +77,7 @@ public:
|
|||||||
int m_volumeIndex;
|
int m_volumeIndex;
|
||||||
unsigned char m_channels;
|
unsigned char m_channels;
|
||||||
bool m_useHP;
|
bool m_useHP;
|
||||||
bool m_upSample48k;
|
int m_upsampling;
|
||||||
AudioFifo *m_audioFifo;
|
AudioFifo *m_audioFifo;
|
||||||
|
|
||||||
MsgMbeDecode(const unsigned char *mbeFrame,
|
MsgMbeDecode(const unsigned char *mbeFrame,
|
||||||
@ -85,14 +85,14 @@ public:
|
|||||||
int volumeIndex,
|
int volumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useHP,
|
bool useHP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo) :
|
AudioFifo *audioFifo) :
|
||||||
Message(),
|
Message(),
|
||||||
m_mbeRate(mbeRate),
|
m_mbeRate(mbeRate),
|
||||||
m_volumeIndex(volumeIndex),
|
m_volumeIndex(volumeIndex),
|
||||||
m_channels(channels),
|
m_channels(channels),
|
||||||
m_useHP(useHP),
|
m_useHP(useHP),
|
||||||
m_upSample48k(upSample48k),
|
m_upsampling(upsampling),
|
||||||
m_audioFifo(audioFifo)
|
m_audioFifo(audioFifo)
|
||||||
{
|
{
|
||||||
memcpy((void *) m_mbeFrame, (const void *) mbeFrame, SerialDV::DVController::getNbMbeBytes(m_mbeRate));
|
memcpy((void *) m_mbeFrame, (const void *) mbeFrame, SerialDV::DVController::getNbMbeBytes(m_mbeRate));
|
||||||
@ -107,7 +107,7 @@ public:
|
|||||||
int mbeVolumeIndex,
|
int mbeVolumeIndex,
|
||||||
unsigned char channels,
|
unsigned char channels,
|
||||||
bool useHP,
|
bool useHP,
|
||||||
bool upSample48k,
|
int upsampling,
|
||||||
AudioFifo *audioFifo);
|
AudioFifo *audioFifo);
|
||||||
|
|
||||||
bool open(const std::string& serialDevice);
|
bool open(const std::string& serialDevice);
|
||||||
@ -136,6 +136,7 @@ public slots:
|
|||||||
private:
|
private:
|
||||||
//void upsample6(short *in, short *out, int nbSamplesIn);
|
//void upsample6(short *in, short *out, int nbSamplesIn);
|
||||||
void upsample6(short *in, int nbSamplesIn, unsigned char channels);
|
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);
|
void noUpsample(short *in, int nbSamplesIn, unsigned char channels);
|
||||||
|
|
||||||
SerialDV::DVController m_dvController;
|
SerialDV::DVController m_dvController;
|
||||||
|
Loading…
Reference in New Issue
Block a user