You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.4 KiB

/*
* Copyright (C) 2014 by Jonathan Naylor, G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "DongleThread.h"
#include "DStarDefines.h"
#include "Bleeper.h"
// A 3 kHz low pass filter at a sample rate of 48000 samples/sec. Calculated by the fir1 command in
// MATLAB.
const wxFloat32 FIR_TAPS[] = {
0.001215122399171F, 0.001363519692447F, 0.001447384226195F, 0.001287712318712F, 0.000614680825630F,
-0.000833383976996F, -0.003176495118124F, -0.006261958697776F, -0.009578203328048F, -0.012249770207721F,
-0.013132705407240F, -0.011005254575316F, -0.004822958879920F, 0.006013373011413F, 0.021438048217733F,
0.040605942188804F, 0.061921094815680F, 0.083217403172960F, 0.102067175368858F, 0.116163746412471F,
0.123705527541065F, 0.123705527541065F, 0.116163746412471F, 0.102067175368858F, 0.083217403172960F,
0.061921094815680F, 0.040605942188804F, 0.021438048217733F, 0.006013373011413F, -0.004822958879920F,
-0.011005254575316F, -0.013132705407240F, -0.012249770207721F, -0.009578203328048F, -0.006261958697776F,
-0.003176495118124F, -0.000833383976996F, 0.000614680825630F, 0.001287712318712F, 0.001447384226195F,
0.001363519692447F, 0.001215122399171F};
const unsigned int FIR_LEN = 42U;
const wxFloat32 UPSAMPLE_AMP = 6.0F;
const wxFloat32 DOWNSAMPLE_AMP = 0.9F;
CDongleThread::CDongleThread() :
wxThread(wxTHREAD_JOINABLE),
m_encodeCallback(NULL),
m_decodeCallback(NULL),
m_encodeAudio(DSTAR_RADIO_BLOCK_SIZE * 30U),
m_decodeData(VOICE_FRAME_LENGTH_BYTES * 30U),
m_bleep(true),
m_killed(false),
m_filter(FIR_TAPS, FIR_LEN)
{
}
CDongleThread::~CDongleThread()
{
}
void CDongleThread::setEncodeCallback(IEncodeCallback* callback)
{
wxASSERT(callback != NULL);
m_encodeCallback = callback;
}
void CDongleThread::setDecodeCallback(IDecodeCallback* callback)
{
wxASSERT(callback != NULL);
m_decodeCallback = callback;
}
unsigned int CDongleThread::getEncodeSpace() const
{
return m_encodeAudio.freeSpace();
}
unsigned int CDongleThread::getDecodeSpace() const
{
return m_decodeData.freeSpace();
}
unsigned int CDongleThread::writeEncode(const wxFloat32* audio, unsigned int length)
{
wxASSERT(audio != NULL);
return m_encodeAudio.addData(audio, length);
}
unsigned int CDongleThread::writeDecode(const unsigned char* ambe, unsigned int length)
{
wxASSERT(ambe != NULL);
return m_decodeData.addData(ambe, length);
}
void CDongleThread::setBleep(bool on)
{
m_bleep = on;
}
void CDongleThread::kill()
{
m_killed = true;
Wait();
}
void CDongleThread::reset()
{
m_filter.reset();
}
void CDongleThread::sendBleep()
{
wxFloat32 audio[DSTAR_RADIO_BLOCK_SIZE];
unsigned int n;
CBleeper bleep(DSTAR_RADIO_SAMPLE_RATE, DSTAR_BLEEP_FREQ, DSTAR_BLEEP_LENGTH, DSTAR_BLEEP_AMPL);
while ((n = bleep.getAudio(audio, DSTAR_RADIO_BLOCK_SIZE)) > 0U)
m_decodeCallback->decodeCallback(audio, n);
}
// Convert from 8000 samples/sec to 48000 samples/sec
void CDongleThread::upSample(const wxFloat32* audioIn, wxFloat32* audioOut)
{
unsigned int out = 0U;
for (unsigned int in = 0U; in < DSTAR_AUDIO_BLOCK_SIZE; in++) {
audioOut[out++] = m_filter.process(audioIn[in]) * UPSAMPLE_AMP;
audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP;
audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP;
audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP;
audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP;
audioOut[out++] = m_filter.process(0.0F) * UPSAMPLE_AMP;
}
}
// Convert from 48000 samples/sec to 8000 samples/sec
void CDongleThread::downSample(const wxFloat32* audioIn, wxFloat32* audioOut)
{
unsigned int in = 0U;
for (unsigned int out = 0U; out < DSTAR_AUDIO_BLOCK_SIZE; out++) {
audioOut[out] = m_filter.process(audioIn[in++]) * DOWNSAMPLE_AMP;
m_filter.process(audioIn[in++]);
m_filter.process(audioIn[in++]);
m_filter.process(audioIn[in++]);
m_filter.process(audioIn[in++]);
m_filter.process(audioIn[in++]);
}
}

Powered by TurnKey Linux.