Updates from master

main
Doug McLain 3 years ago
parent 657a8bf836
commit a598966deb

@ -30,8 +30,8 @@
#include "Controller.h"
#define AMBE_GAIN 16 //Encoder gain in dB (I use 16 here)
#define AMBE2_GAIN -24 //Encoder gain in dB (I use -24 here)
//#define AMBE_GAIN 16 //Encoder gain in dB (I use 16 here)
//#define AMBE2_GAIN -24 //Encoder gain in dB (I use -24 here)
#define USRP_RXGAIN -6
#define USRP_TXGAIN 3
@ -196,7 +196,7 @@ bool CController::InitVocoders()
dstar_device = std::unique_ptr<CDVDevice>(new CDV3000(Encoding::dstar));
#ifdef USE_SW_AMBE2
md380_init();
ambe_gain = calcGainVal(AMBE2_GAIN);
ambe_gain = calcGainVal(DMR_IN_GAIN);
#else
dmrsf_device = std::unique_ptr<CDVDevice>(new CDV3000(Encoding::dmrsf));
#endif
@ -213,7 +213,7 @@ bool CController::InitVocoders()
if (dstar_device)
{
if (dstar_device->OpenDevice(deviceset.front().first, deviceset.front().second, dvtype, calcGainVal(AMBE_GAIN)))
if (dstar_device->OpenDevice(deviceset.front().first, deviceset.front().second, dvtype, DSTAR_IN_GAIN, DSTAR_OUT_GAIN))
return true;
deviceset.pop_front();
}
@ -225,7 +225,7 @@ bool CController::InitVocoders()
#ifndef USE_SW_AMBE2
if (dmrsf_device)
{
if (dmrsf_device->OpenDevice(deviceset.front().first, deviceset.front().second, dvtype, calcGainVal(AMBE2_GAIN)))
if (dmrsf_device->OpenDevice(deviceset.front().first, deviceset.front().second, dvtype, DMR_IN_GAIN, DMR_OUT_GAIN))
return true;
deviceset.pop_front();
}

@ -32,7 +32,6 @@
#include "UnixDgramSocket.h"
#include "configure.h"
class CController
{
public:

@ -40,7 +40,10 @@ extern CController Controller;
CDV3000::CDV3000(Encoding t) : CDVDevice(t) {}
CDV3000::~CDV3000() {}
CDV3000::~CDV3000()
{
waiting_packet.Shutdown();
}
void CDV3000::PushWaitingPacket(unsigned int /* channel */, std::shared_ptr<CTranscoderPacket> packet)
{
@ -52,7 +55,7 @@ std::shared_ptr<CTranscoderPacket> CDV3000::PopWaitingPacket(unsigned int /* cha
return waiting_packet.pop();
}
bool CDV3000::SendAudio(const uint8_t /*channel*/, const int16_t *audio, const int gain) const
bool CDV3000::SendAudio(const uint8_t /*channel*/, const int16_t *audio) const
{
// Create Audio packet based on input int8_ts
SDV_Packet p;
@ -61,16 +64,9 @@ bool CDV3000::SendAudio(const uint8_t /*channel*/, const int16_t *audio, const i
p.header.packet_type = PKT_SPEECH;
p.field_id = PKT_SPEECHD;
p.payload.audio3k.num_samples = 160U;
const uint32_t g = abs(gain);
for (int i=0; i<160; i++)
p.payload.audio3k.samples[i] = htons(audio[i]);
for (int i=0; i<160; i++){
if(gain < 0){
p.payload.audio3k.samples[i] = htons(audio[i] / g);
}
else{
p.payload.audio3k.samples[i] = htons(audio[i] * g);
}
}
// send audio packet to DV3000
const DWORD size = packet_size(p);
DWORD written;
@ -121,6 +117,8 @@ bool CDV3000::SendData(const uint8_t /* channel */, const uint8_t *data) const
void CDV3000::ProcessPacket(const SDV_Packet &p)
{
auto packet = PopWaitingPacket(PKT_CHANNEL0);
if (packet)
{
if (PKT_CHANNEL == p.header.packet_type)
{
if (11!=ntohs(p.header.payload_length) || PKT_CHAND!=p.field_id || 72!=p.payload.ambe3k.num_bits)
@ -157,3 +155,4 @@ void CDV3000::ProcessPacket(const SDV_Packet &p)
Controller.dmrst_mux.unlock();
}
}
}

@ -29,7 +29,7 @@ protected:
void PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet);
std::shared_ptr<CTranscoderPacket> PopWaitingPacket(unsigned int channel);
void ProcessPacket(const SDV_Packet &p);
bool SendAudio(const uint8_t channel, const int16_t *audio, const int gain) const;
bool SendAudio(const uint8_t channel, const int16_t *audio) const;
bool SendData(const uint8_t channel, const uint8_t *data) const;
private:

@ -40,7 +40,11 @@ extern CController Controller;
CDV3003::CDV3003(Encoding t) : CDVDevice(t) {}
CDV3003::~CDV3003() {}
CDV3003::~CDV3003()
{
for (int i=0; i<3; i++)
waiting_packet[i].Shutdown();
}
void CDV3003::PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet)
{
@ -52,7 +56,7 @@ std::shared_ptr<CTranscoderPacket> CDV3003::PopWaitingPacket(unsigned int channe
return waiting_packet[channel].pop();
}
bool CDV3003::SendAudio(const uint8_t channel, const int16_t *audio, const int gain) const
bool CDV3003::SendAudio(const uint8_t channel, const int16_t *audio) const
{
// Create Audio packet based on input int8_ts
SDV_Packet p;
@ -62,16 +66,8 @@ bool CDV3003::SendAudio(const uint8_t channel, const int16_t *audio, const int g
p.field_id = channel + PKT_CHANNEL0;
p.payload.audio.speechd = PKT_SPEECHD;
p.payload.audio.num_samples = 160U;
const uint32_t g = abs(gain);
for (int i=0; i<160; i++){
if(gain < 0){
p.payload.audio3k.samples[i] = htons(audio[i]) / g;
}
else{
p.payload.audio3k.samples[i] = htons(audio[i]) * g;
}
}
for (int i=0; i<160; i++)
p.payload.audio.samples[i] = htons(audio[i]);
// send audio packet to DV3000
const DWORD size = packet_size(p);
@ -125,6 +121,8 @@ void CDV3003::ProcessPacket(const SDV_Packet &p)
{
unsigned int channel = p.field_id - PKT_CHANNEL0;
auto packet = PopWaitingPacket(channel);
if (packet)
{
if (PKT_CHANNEL == p.header.packet_type)
{
if (12!=ntohs(p.header.payload_length) || PKT_CHAND!=p.payload.ambe.chand || 72!=p.payload.ambe.num_bits)
@ -161,3 +159,4 @@ void CDV3003::ProcessPacket(const SDV_Packet &p)
Controller.dmrst_mux.unlock();
}
}
}

@ -29,7 +29,7 @@ protected:
void PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet);
std::shared_ptr<CTranscoderPacket> PopWaitingPacket(unsigned int channel);
void ProcessPacket(const SDV_Packet &p);
bool SendAudio(const uint8_t channel, const int16_t *audio, const int gain) const;
bool SendAudio(const uint8_t channel, const int16_t *audio) const;
bool SendData(const uint8_t channel, const uint8_t *data) const;
private:

@ -7,7 +7,7 @@
*/
// tcd - a hybid transcoder using DVSI hardware and Codec2 software
// Copyright © 2022 Thomas A. Early N7TAE
// Copyright © 2022-2023 Thomas A. Early N7TAE
// 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
@ -23,6 +23,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <sys/select.h>
#include <csignal>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
@ -49,6 +50,7 @@ CDVDevice::~CDVDevice()
void CDVDevice::CloseDevice()
{
input_queue.Shutdown();
keep_running = false;
if (ftHandle)
{
@ -140,7 +142,7 @@ bool CDVDevice::checkResponse(SDV_Packet &p, uint8_t response) const
return false;
}
bool CDVDevice::OpenDevice(const std::string &serialno, const std::string &desc, Edvtype dvtype, int16_t g)
bool CDVDevice::OpenDevice(const std::string &serialno, const std::string &desc, Edvtype dvtype, int8_t in_gain, int8_t out_gain)
{
auto status = FT_OpenEx((PVOID)serialno.c_str(), FT_OPEN_BY_SERIAL_NUMBER, &ftHandle);
if (FT_OK != status)
@ -149,7 +151,6 @@ bool CDVDevice::OpenDevice(const std::string &serialno, const std::string &desc,
return true;
}
gain = g;
std::this_thread::sleep_for(std::chrono::milliseconds(50));
FT_Purge(ftHandle, FT_PURGE_RX | FT_PURGE_TX );
std::this_thread::sleep_for(std::chrono::milliseconds(50));
@ -240,7 +241,7 @@ bool CDVDevice::OpenDevice(const std::string &serialno, const std::string &desc,
const uint8_t limit = (Edvtype::dv3000 == dvtype) ? PKT_CHANNEL0 : PKT_CHANNEL2;
for (uint8_t ch=PKT_CHANNEL0; ch<=limit; ch++)
{
if (ConfigureVocoder(ch, type))
if (ConfigureVocoder(ch, type, in_gain, out_gain))
return true;
}
return false;
@ -388,7 +389,7 @@ void CDVDevice::Start()
readFuture = std::async(std::launch::async, &CDVDevice::ReadDevice, this);
}
bool CDVDevice::ConfigureVocoder(uint8_t pkt_ch, Encoding type)
bool CDVDevice::ConfigureVocoder(uint8_t pkt_ch, Encoding type, int8_t in_gain, int8_t out_gain)
{
SDV_Packet controlPacket, responsePacket;
const uint8_t ecmode[] { PKT_ECMODE, 0x0, 0x0 };
@ -397,7 +398,7 @@ bool CDVDevice::ConfigureVocoder(uint8_t pkt_ch, Encoding type)
const uint8_t dmr[] { PKT_RATEP, 0x04U, 0x31U, 0x07U, 0x54U, 0x24U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x6FU, 0x48U };
const uint8_t chfmt[] { PKT_CHANFMT, 0x0, 0x0 };
const uint8_t spfmt[] { PKT_SPCHFMT, 0x0, 0x0 };
const uint8_t gain[] { PKT_GAIN, 0x0, 0x0 };
const uint8_t gain[] { PKT_GAIN, uint8_t(in_gain), uint8_t(out_gain) };
const uint8_t init[] { PKT_INIT, 0x3U };
const uint8_t resp[] { 0x0, PKT_ECMODE, 0x0, PKT_DCMODE, 0x0, PKT_RATEP, 0x0, PKT_CHANFMT, 0x0, PKT_SPCHFMT, 0x0, PKT_GAIN, 0x0, PKT_INIT, 0x0 };
@ -511,7 +512,12 @@ bool CDVDevice::GetResponse(SDV_Packet &packet)
void CDVDevice::AddPacket(const std::shared_ptr<CTranscoderPacket> packet)
{
input_queue.push(packet);
auto size = input_queue.push(packet);
if (size > 200)
{
std::cerr << ((type==Encoding::dstar) ? "DStar" : "DMR/YSF") << " inQ size is overflowing! Shutting down..." << std::endl;
raise(SIGINT);
}
}
void CDVDevice::dump(const char *title, const void *pointer, int length) const
@ -563,9 +569,10 @@ void CDVDevice::FeedDevice()
const auto n = modules.size();
while (keep_running)
{
auto packet = input_queue.pop(); // blocks until there is something to pop
auto packet = input_queue.pop(); // blocks until there is something to pop, unless shutting down
if (packet)
{
while (keep_running) // wait until there is room
{
if (buffer_depth < 2)
@ -594,13 +601,14 @@ void CDVDevice::FeedDevice()
}
else
{
SendAudio(index, packet->GetAudioSamples(), gain);
SendAudio(index, packet->GetAudioSamples());
}
buffer_depth++;
}
}
}
}
}
void CDVDevice::ReadDevice()
{
@ -614,15 +622,15 @@ void CDVDevice::ReadDevice()
if (FT_OK != status)
{
FTDI_Error("FT_GetQueueStatus", status);
std::cerr << "Shutting down..." << std::endl;
raise(SIGTERM);
}
if (RxBytes)
{
break;
}
else
if (0 == RxBytes)
{
std::this_thread::sleep_for(std::chrono::milliseconds(2));
std::this_thread::sleep_for(std::chrono::milliseconds(3));
if (! keep_running)
return;
}
}

@ -32,7 +32,7 @@ public:
CDVDevice(Encoding t);
virtual ~CDVDevice();
bool OpenDevice(const std::string &serialno, const std::string &desc, Edvtype dvtype, int16_t g);
bool OpenDevice(const std::string &serialno, const std::string &desc, Edvtype dvtype, int8_t in_gain, int8_t out_gain);
void Start();
void CloseDevice();
void AddPacket(const std::shared_ptr<CTranscoderPacket> packet);
@ -46,10 +46,9 @@ protected:
CPacketQueue input_queue;
std::future<void> feedFuture, readFuture;
std::string description, productid;
int16_t gain;
bool DiscoverFtdiDevices();
bool ConfigureVocoder(uint8_t pkt_ch, Encoding type);
bool ConfigureVocoder(uint8_t pkt_ch, Encoding type, int8_t in_gain, int8_t out_gain);
bool checkResponse(SDV_Packet &responsePacket, uint8_t response) const;
bool GetResponse(SDV_Packet &packet);
bool InitDevice();
@ -62,6 +61,6 @@ protected:
virtual void PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet) = 0;
virtual std::shared_ptr<CTranscoderPacket> PopWaitingPacket(unsigned int channel) = 0;
virtual void ProcessPacket(const SDV_Packet &p) = 0;
virtual bool SendAudio(const uint8_t channel, const int16_t *audio, const int gain) const = 0;
virtual bool SendAudio(const uint8_t channel, const int16_t *audio) const = 0;
virtual bool SendData(const uint8_t channel, const uint8_t *data) const = 0;
};

@ -1,5 +1,5 @@
// tcd - a hybrid transcoder using DVSI hardware and Codec2 software
// Copyright © 2021 Thomas A. Early N7TAE
// Copyright © 2021,2023 Thomas A. Early N7TAE
//
// 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
@ -27,7 +27,7 @@ int main()
if (Controller.Start())
return EXIT_FAILURE;
std::cout << "Hybrid Transcoder version 0.0.1 successfully started" << std::endl;
std::cout << "Hybrid Transcoder version 0.0.5 successfully started" << std::endl;
pause();

@ -30,27 +30,59 @@
class CPacketQueue
{
public:
// blocks until there's something to pop
CPacketQueue() : keep_running(true) {}
std::shared_ptr<CTranscoderPacket> pop()
{
std::unique_lock<std::mutex> lock(m);
while (q.empty()) {
c.wait(lock);
std::shared_ptr<CTranscoderPacket> rval; // the return value
std::unique_lock<std::mutex> lock(mx);
while (keep_running && q.empty())
cv.wait(lock);
if (keep_running)
{
rval = q.front();
q.pop();
}
auto pack = q.front();
else
{
while (! q.empty())
q.pop();
return pack;
}
void push(std::shared_ptr<CTranscoderPacket> packet)
return rval;
}
std::size_t push(std::shared_ptr<CTranscoderPacket> item)
{
std::unique_lock<std::mutex> lock(mx);
bool was_empty = q.empty();
q.push(item);
if (was_empty)
cv.notify_one();
return q.size();
}
bool IsEmpty()
{
std::lock_guard<std::mutex> lock(mx);
return q.empty();
}
void Shutdown()
{
std::lock_guard<std::mutex> lock(m);
q.push(packet);
c.notify_one();
std::lock_guard<std::mutex> lock(mx);
keep_running = false;
cv.notify_all();
}
private:
std::mutex mx;
std::condition_variable cv;
std::queue<std::shared_ptr<CTranscoderPacket>> q;
mutable std::mutex m;
std::condition_variable c;
std::atomic<bool> keep_running;
};

Loading…
Cancel
Save

Powered by TurnKey Linux.