Multiple audio support: DSD demodulator: allow to use native 8k decoder if audio sample rate is 8k

This commit is contained in:
f4exb 2018-03-28 08:43:11 +02:00
parent c4b092dff0
commit f71446b6ec
9 changed files with 112 additions and 66 deletions

View File

@ -36,6 +36,11 @@ DSDDecoder::~DSDDecoder()
{
}
void DSDDecoder::set48k(bool to48k)
{
m_decoder.setUpsampling(to48k ? 6 : 0);
}
void DSDDecoder::setBaudRate(int baudRate)
{
if (baudRate == 2400)

View File

@ -71,6 +71,7 @@ public:
void setBaudRate(int baudRate);
void setSymbolPLLLock(bool pllLock) { m_decoder.setSymbolPLLLock(pllLock); }
void useHPMbelib(bool useHP) { m_decoder.useHPMbelib(useHP); }
void set48k(bool to48k);
private:
DSDcc::DSDDecoder m_decoder;

View File

@ -217,6 +217,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_audioFifo1);
}
@ -233,6 +234,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_audioFifo2);
}
@ -391,10 +393,12 @@ void DSDDemod::applyAudioSampleRate(int sampleRate)
{
qDebug("DSDDemod::applyAudioSampleRate: %d", sampleRate);
if (sampleRate != 48000) {
qWarning("DSDDemod::applyAudioSampleRate: audio does not work properly with sample rates other than 48 kS/s");
if ((sampleRate != 48000) || (sampleRate != 8000)) {
qWarning("DSDDemod::applyAudioSampleRate: audio does not work properly with sample rates other than 48 or 8 kS/s");
}
m_dsdDecoder.set48k(sampleRate != 8000);
m_audioSampleRate = sampleRate;
}

View File

@ -164,9 +164,10 @@ void DSPEngine::pushMbeFrame(
int mbeVolumeIndex,
unsigned char channels,
bool useHP,
bool upSample48k,
AudioFifo *audioFifo)
{
m_dvSerialEngine.pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, audioFifo);
m_dvSerialEngine.pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upSample48k, audioFifo);
}
#else
void DSPEngine::pushMbeFrame(
@ -175,6 +176,7 @@ void DSPEngine::pushMbeFrame(
int mbeVolumeIndex __attribute((unused)),
unsigned char channels __attribute((unused)),
bool useHP __attribute((unused)),
bool upSample48k __attribute((unused)),
AudioFifo *audioFifo __attribute((unused)))
{}
#endif

View File

@ -68,6 +68,7 @@ public:
int mbeVolumeIndex,
unsigned char channels,
bool useHP,
bool upSample48k,
AudioFifo *audioFifo);
const QTimer& getMasterTimer() const { return m_masterTimer; }

View File

@ -253,6 +253,7 @@ void DVSerialEngine::pushMbeFrame(
int mbeVolumeIndex,
unsigned char channels,
bool useLP,
bool upSample48k,
AudioFifo *audioFifo)
{
std::vector<DVSerialController>::iterator it = m_controllers.begin();
@ -264,7 +265,7 @@ void DVSerialEngine::pushMbeFrame(
{
if (it->worker->hasFifo(audioFifo))
{
it->worker->pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useLP, audioFifo);
it->worker->pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useLP, upSample48k, audioFifo);
done = true;
}
else if (it->worker->isAvailable())
@ -282,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, audioFifo);
itAvail->worker->pushMbeFrame(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useLP, upSample48k, audioFifo);
}
else
{

View File

@ -49,6 +49,7 @@ public:
int mbeVolumeIndex,
unsigned char channels,
bool useHP,
bool upSample48k,
AudioFifo *audioFifo);
private:

View File

@ -86,7 +86,12 @@ void DVSerialWorker::handleInputMessages()
if (m_dvController.decode(m_dvAudioSamples, decodeMsg->getMbeFrame(), decodeMsg->getMbeRate(), dBVolume))
{
upsample6(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels());
if (decodeMsg->getUpsample48k()) {
upsample6(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels());
} else {
noUpsample(m_dvAudioSamples, SerialDV::MBE_AUDIO_BLOCK_SIZE, decodeMsg->getChannels());
}
audioFifo = decodeMsg->getAudioFifo();
}
else
@ -116,10 +121,11 @@ void DVSerialWorker::pushMbeFrame(const unsigned char *mbeFrame,
int mbeVolumeIndex,
unsigned char channels,
bool useHP,
bool upSample48k,
AudioFifo *audioFifo)
{
m_audioFifo = audioFifo;
m_inputMessageQueue.push(MsgMbeDecode::create(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, audioFifo));
m_inputMessageQueue.push(MsgMbeDecode::create(mbeFrame, mbeRateIndex, mbeVolumeIndex, channels, useHP, upSample48k, audioFifo));
}
bool DVSerialWorker::isAvailable()
@ -164,66 +170,84 @@ void DVSerialWorker::upsample6(short *in, int nbSamplesIn, unsigned char channel
}
}
void DVSerialWorker::upsample6(short *in, short *out, int nbSamplesIn)
void DVSerialWorker::noUpsample(short *in, int nbSamplesIn, unsigned char channels)
{
for (int i = 0; i < nbSamplesIn; i++)
{
int cur = (int) in[i];
int prev = (int) m_upsamplerLastValue;
short up;
m_audioBuffer[m_audioBufferFill].l = channels & 1 ? in[i] : 0;
m_audioBuffer[m_audioBufferFill].r = (channels>>1) & 1 ? in[i] : 0;
// DEBUG:
// for (int j = 0; j < 6; j++)
// {
// up = 32768.0f * cos(m_phase);
// *out = up;
// out ++;
// *out = up;
// out ++;
// m_phase += M_PI / 6.0;
// }
//
// if ((i % 2) == 1)
// {
// m_phase = 0.0f;
// }
up = m_upsampleFilter.run((cur*1 + prev*5) / 6);
*out = up;
out++;
*out = up;
out++;
up = m_upsampleFilter.run((cur*2 + prev*4) / 6);
*out = up;
out++;
*out = up;
out++;
up = m_upsampleFilter.run((cur*3 + prev*3) / 6);
*out = up;
out++;
*out = up;
out++;
up = m_upsampleFilter.run((cur*4 + prev*2) / 6);
*out = up;
out++;
*out = up;
out++;
up = m_upsampleFilter.run((cur*5 + prev*1) / 6);
*out = up;
out++;
*out = up;
out++;
up = m_upsampleFilter.run(in[i]);
*out = up;
out++;
*out = up;
out++;
m_upsamplerLastValue = in[i];
if (m_audioBufferFill < m_audioBuffer.size() - 1)
{
++m_audioBufferFill;
}
else
{
qDebug("DVSerialWorker::noUpsample: audio buffer is full check its size");
}
}
}
//void DVSerialWorker::upsample6(short *in, short *out, int nbSamplesIn)
//{
// for (int i = 0; i < nbSamplesIn; i++)
// {
// int cur = (int) in[i];
// int prev = (int) m_upsamplerLastValue;
// short up;
//
//// DEBUG:
//// for (int j = 0; j < 6; j++)
//// {
//// up = 32768.0f * cos(m_phase);
//// *out = up;
//// out ++;
//// *out = up;
//// out ++;
//// m_phase += M_PI / 6.0;
//// }
////
//// if ((i % 2) == 1)
//// {
//// m_phase = 0.0f;
//// }
//
// up = m_upsampleFilter.run((cur*1 + prev*5) / 6);
// *out = up;
// out++;
// *out = up;
// out++;
//
// up = m_upsampleFilter.run((cur*2 + prev*4) / 6);
// *out = up;
// out++;
// *out = up;
// out++;
//
// up = m_upsampleFilter.run((cur*3 + prev*3) / 6);
// *out = up;
// out++;
// *out = up;
// out++;
//
// up = m_upsampleFilter.run((cur*4 + prev*2) / 6);
// *out = up;
// out++;
// *out = up;
// out++;
//
// up = m_upsampleFilter.run((cur*5 + prev*1) / 6);
// *out = up;
// out++;
// *out = up;
// out++;
//
// up = m_upsampleFilter.run(in[i]);
// *out = up;
// out++;
// *out = up;
// out++;
//
// m_upsamplerLastValue = in[i];
// }
//}

View File

@ -56,6 +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; }
AudioFifo *getAudioFifo() { return m_audioFifo; }
static MsgMbeDecode* create(
@ -64,9 +65,10 @@ public:
int volumeIndex,
unsigned char channels,
bool useHP,
bool upSample48k,
AudioFifo *audioFifo)
{
return new MsgMbeDecode(mbeFrame, (SerialDV::DVRate) mbeRateIndex, volumeIndex, channels, useHP, audioFifo);
return new MsgMbeDecode(mbeFrame, (SerialDV::DVRate) mbeRateIndex, volumeIndex, channels, useHP, upSample48k, audioFifo);
}
private:
@ -75,6 +77,7 @@ public:
int m_volumeIndex;
unsigned char m_channels;
bool m_useHP;
bool m_upSample48k;
AudioFifo *m_audioFifo;
MsgMbeDecode(const unsigned char *mbeFrame,
@ -82,12 +85,14 @@ public:
int volumeIndex,
unsigned char channels,
bool useHP,
bool upSample48k,
AudioFifo *audioFifo) :
Message(),
m_mbeRate(mbeRate),
m_volumeIndex(volumeIndex),
m_channels(channels),
m_useHP(useHP),
m_upSample48k(upSample48k),
m_audioFifo(audioFifo)
{
memcpy((void *) m_mbeFrame, (const void *) mbeFrame, SerialDV::DVController::getNbMbeBytes(m_mbeRate));
@ -102,6 +107,7 @@ public:
int mbeVolumeIndex,
unsigned char channels,
bool useHP,
bool upSample48k,
AudioFifo *audioFifo);
bool open(const std::string& serialDevice);
@ -128,8 +134,9 @@ public slots:
void handleInputMessages();
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 noUpsample(short *in, int nbSamplesIn, unsigned char channels);
SerialDV::DVController m_dvController;
volatile bool m_running;