Make software ambe+2 vocoding via md380_vocoder a compile time option

main
Doug McLain 3 years ago
parent 38c10f5533
commit 657a8bf836

@ -22,11 +22,14 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <thread> #include <thread>
#ifdef USE_SW_AMBE2
#include <md380_vocoder.h> #include <md380_vocoder.h>
#endif
#include "TranscoderPacket.h" #include "TranscoderPacket.h"
#include "Controller.h" #include "Controller.h"
#define AMBE_GAIN 16 //Encoder gain in dB (I use 16 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 AMBE2_GAIN -24 //Encoder gain in dB (I use -24 here)
#define USRP_RXGAIN -6 #define USRP_RXGAIN -6
@ -47,7 +50,6 @@ CController::CController() : keep_running(true) {}
bool CController::Start() bool CController::Start()
{ {
swambe2 = true;
usrp_rxgain = calcGainVal(USRP_RXGAIN); usrp_rxgain = calcGainVal(USRP_RXGAIN);
usrp_txgain = calcGainVal(USRP_TXGAIN); usrp_txgain = calcGainVal(USRP_TXGAIN);
@ -58,9 +60,11 @@ bool CController::Start()
} }
reflectorFuture = std::async(std::launch::async, &CController::ReadReflectorThread, this); reflectorFuture = std::async(std::launch::async, &CController::ReadReflectorThread, this);
c2Future = std::async(std::launch::async, &CController::ProcessC2Thread, this); c2Future = std::async(std::launch::async, &CController::ProcessC2Thread, this);
swambe2Future = std::async(std::launch::async, &CController::ProcessSWAMBE2Thread,this);
imbeFuture = std::async(std::launch::async, &CController::ProcessIMBEThread, this); imbeFuture = std::async(std::launch::async, &CController::ProcessIMBEThread, this);
usrpFuture = std::async(std::launch::async, &CController::ProcessUSRPThread, this); usrpFuture = std::async(std::launch::async, &CController::ProcessUSRPThread, this);
#ifdef USE_SW_AMBE2
swambe2Future = std::async(std::launch::async, &CController::ProcessSWAMBE2Thread,this);
#endif
return false; return false;
} }
@ -146,13 +150,14 @@ bool CController::InitVocoders()
if (2 != deviceset.size()) if (2 != deviceset.size())
{ {
if(swambe2 && (deviceset.size() == 1)){ #ifdef USE_SW_AMBE2
if(deviceset.size() == 1){
std::cout << "Using one DVSI device and md380_vocoder" << std::endl; std::cout << "Using one DVSI device and md380_vocoder" << std::endl;
} }
else{ #else
std::cerr << "Could not find exactly two DVSI devices" << std::endl; std::cerr << "Could not find exactly two DVSI devices" << std::endl;
return true; return true;
} #endif
} }
const auto desc(deviceset.front().second); const auto desc(deviceset.front().second);
@ -189,21 +194,21 @@ bool CController::InitVocoders()
if (Edvtype::dv3000 == dvtype) if (Edvtype::dv3000 == dvtype)
{ {
dstar_device = std::unique_ptr<CDVDevice>(new CDV3000(Encoding::dstar)); dstar_device = std::unique_ptr<CDVDevice>(new CDV3000(Encoding::dstar));
if(swambe2){ #ifdef USE_SW_AMBE2
md380_init(); md380_init();
ambe_gain = calcGainVal(AMBE2_GAIN); ambe_gain = calcGainVal(AMBE2_GAIN);
} #else
else dmrsf_device = std::unique_ptr<CDVDevice>(new CDV3000(Encoding::dmrsf));
dmrsf_device = std::unique_ptr<CDVDevice>(new CDV3000(Encoding::dmrsf)); #endif
} }
else else
{ {
dstar_device = std::unique_ptr<CDVDevice>(new CDV3003(Encoding::dstar)); dstar_device = std::unique_ptr<CDVDevice>(new CDV3003(Encoding::dstar));
if(swambe2){ #ifdef USE_SW_AMBE2
md380_init(); md380_init();
} #else
else dmrsf_device = std::unique_ptr<CDVDevice>(new CDV3003(Encoding::dmrsf));
dmrsf_device = std::unique_ptr<CDVDevice>(new CDV3003(Encoding::dmrsf)); #endif
} }
if (dstar_device) if (dstar_device)
@ -217,25 +222,27 @@ bool CController::InitVocoders()
std::cerr << "Could not create DVSI devices!" << std::endl; std::cerr << "Could not create DVSI devices!" << std::endl;
return true; return true;
} }
#ifndef USE_SW_AMBE2
if (!swambe2 && dmrsf_device) 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, calcGainVal(AMBE2_GAIN)))
return true; return true;
deviceset.pop_front(); deviceset.pop_front();
} }
else if(!swambe2) else
{ {
std::cerr << "Could not create DVSI devices!" << std::endl; std::cerr << "Could not create DVSI devices!" << std::endl;
return true; return true;
} }
#endif
} }
// and start them (or it) up! // and start them (or it) up!
dstar_device->Start(); dstar_device->Start();
if(!swambe2) #ifndef USE_SW_AMBE2
dmrsf_device->Start(); dmrsf_device->Start();
#endif
deviceset.clear(); deviceset.clear();
@ -262,10 +269,11 @@ void CController::ReadReflectorThread()
dstar_device->AddPacket(packet); dstar_device->AddPacket(packet);
break; break;
case ECodecType::dmr: case ECodecType::dmr:
if(swambe2) #ifdef USE_SW_AMBE2
swambe2_queue.push(packet); swambe2_queue.push(packet);
else #else
dmrsf_device->AddPacket(packet); dmrsf_device->AddPacket(packet);
#endif
break; break;
case ECodecType::p25: case ECodecType::p25:
imbe_queue.push(packet); imbe_queue.push(packet);
@ -367,7 +375,12 @@ void CController::Codec2toAudio(std::shared_ptr<CTranscoderPacket> packet)
// the only thing left is to encode the two ambe, so push the packet onto both AMBE queues // the only thing left is to encode the two ambe, so push the packet onto both AMBE queues
dstar_device->AddPacket(packet); dstar_device->AddPacket(packet);
#ifdef USE_SW_AMBE2
md380_encode_fec(ambe2, packet->GetAudioSamples()); md380_encode_fec(ambe2, packet->GetAudioSamples());
#else
dmrsf_device->AddPacket(packet);
#endif
packet->SetDMRData(ambe2); packet->SetDMRData(ambe2);
p25vocoder.encode_4400((int16_t*)packet->GetAudioSamples(), imbe); p25vocoder.encode_4400((int16_t*)packet->GetAudioSamples(), imbe);
packet->SetP25Data(imbe); packet->SetP25Data(imbe);
@ -400,6 +413,7 @@ void CController::ProcessC2Thread()
} }
} }
#ifdef USE_SW_AMBE2
void CController::AudiotoSWAMBE2(std::shared_ptr<CTranscoderPacket> packet) void CController::AudiotoSWAMBE2(std::shared_ptr<CTranscoderPacket> packet)
{ {
const auto m = packet->GetModule(); const auto m = packet->GetModule();
@ -459,6 +473,7 @@ void CController::ProcessSWAMBE2Thread()
} }
} }
} }
#endif
void CController::AudiotoIMBE(std::shared_ptr<CTranscoderPacket> packet) void CController::AudiotoIMBE(std::shared_ptr<CTranscoderPacket> packet)
{ {
@ -479,7 +494,13 @@ void CController::IMBEtoAudio(std::shared_ptr<CTranscoderPacket> packet)
packet->SetAudioSamples(tmp, false); packet->SetAudioSamples(tmp, false);
dstar_device->AddPacket(packet); dstar_device->AddPacket(packet);
codec2_queue.push(packet); codec2_queue.push(packet);
#ifdef USE_SW_AMBE2
swambe2_queue.push(packet); swambe2_queue.push(packet);
#else
dmrsf_device->AddPacket(packet);
#endif
usrp_queue.push(packet); usrp_queue.push(packet);
} }
@ -548,7 +569,13 @@ void CController::USRPtoAudio(std::shared_ptr<CTranscoderPacket> packet)
packet->SetAudioSamples(tmp, false); packet->SetAudioSamples(tmp, false);
dstar_device->AddPacket(packet); dstar_device->AddPacket(packet);
codec2_queue.push(packet); codec2_queue.push(packet);
#ifdef USE_SW_AMBE2
swambe2_queue.push(packet); swambe2_queue.push(packet);
#else
dmrsf_device->AddPacket(packet);
#endif
imbe_queue.push(packet); imbe_queue.push(packet);
} }
@ -596,10 +623,11 @@ void CController::RouteDstPacket(std::shared_ptr<CTranscoderPacket> packet)
codec2_queue.push(packet); codec2_queue.push(packet);
imbe_queue.push(packet); imbe_queue.push(packet);
usrp_queue.push(packet); usrp_queue.push(packet);
if(swambe2) #ifdef USE_SW_AMBE2
swambe2_queue.push(packet); swambe2_queue.push(packet);
else #else
dmrsf_device->AddPacket(packet); dmrsf_device->AddPacket(packet);
#endif
} }
else else
{ {

@ -32,6 +32,7 @@
#include "UnixDgramSocket.h" #include "UnixDgramSocket.h"
#include "configure.h" #include "configure.h"
class CController class CController
{ {
public: public:
@ -46,7 +47,7 @@ public:
protected: protected:
std::atomic<bool> keep_running; std::atomic<bool> keep_running;
std::future<void> reflectorFuture, c2Future, swambe2Future, imbeFuture, usrpFuture; std::future<void> reflectorFuture, c2Future, imbeFuture, usrpFuture;
std::unordered_map<char, int16_t[160]> audio_store; std::unordered_map<char, int16_t[160]> audio_store;
std::unordered_map<char, uint8_t[8]> data_store; std::unordered_map<char, uint8_t[8]> data_store;
CUnixDgramReader reader; CUnixDgramReader reader;
@ -55,14 +56,13 @@ protected:
std::unique_ptr<CDVDevice> dstar_device, dmrsf_device; std::unique_ptr<CDVDevice> dstar_device, dmrsf_device;
CPacketQueue codec2_queue; CPacketQueue codec2_queue;
CPacketQueue swambe2_queue;
CPacketQueue imbe_queue; CPacketQueue imbe_queue;
CPacketQueue usrp_queue; CPacketQueue usrp_queue;
std::mutex send_mux; std::mutex send_mux;
int16_t ambe_gain; int16_t ambe_gain;
int16_t usrp_rxgain; int16_t usrp_rxgain;
int16_t usrp_txgain; int16_t usrp_txgain;
bool swambe2;
imbe_vocoder p25vocoder; imbe_vocoder p25vocoder;
bool DiscoverFtdiDevices(std::list<std::pair<std::string, std::string>> &found); bool DiscoverFtdiDevices(std::list<std::pair<std::string, std::string>> &found);
@ -70,16 +70,21 @@ protected:
// processing threads // processing threads
void ReadReflectorThread(); void ReadReflectorThread();
void ProcessC2Thread(); void ProcessC2Thread();
void ProcessSWAMBE2Thread();
void ProcessIMBEThread(); void ProcessIMBEThread();
void ProcessUSRPThread(); void ProcessUSRPThread();
void Codec2toAudio(std::shared_ptr<CTranscoderPacket> packet); void Codec2toAudio(std::shared_ptr<CTranscoderPacket> packet);
void AudiotoCodec2(std::shared_ptr<CTranscoderPacket> packet); void AudiotoCodec2(std::shared_ptr<CTranscoderPacket> packet);
void SWAMBE2toAudio(std::shared_ptr<CTranscoderPacket> packet);
void AudiotoSWAMBE2(std::shared_ptr<CTranscoderPacket> packet);
void IMBEtoAudio(std::shared_ptr<CTranscoderPacket> packet); void IMBEtoAudio(std::shared_ptr<CTranscoderPacket> packet);
void AudiotoIMBE(std::shared_ptr<CTranscoderPacket> packet); void AudiotoIMBE(std::shared_ptr<CTranscoderPacket> packet);
void USRPtoAudio(std::shared_ptr<CTranscoderPacket> packet); void USRPtoAudio(std::shared_ptr<CTranscoderPacket> packet);
void AudiotoUSRP(std::shared_ptr<CTranscoderPacket> packet); void AudiotoUSRP(std::shared_ptr<CTranscoderPacket> packet);
void SendToReflector(std::shared_ptr<CTranscoderPacket> packet); void SendToReflector(std::shared_ptr<CTranscoderPacket> packet);
#ifdef USE_SW_AMBE2
std::future<void> swambe2Future;
CPacketQueue swambe2_queue;
void ProcessSWAMBE2Thread();
void SWAMBE2toAudio(std::shared_ptr<CTranscoderPacket> packet);
void AudiotoSWAMBE2(std::shared_ptr<CTranscoderPacket> packet);
#endif
}; };

@ -6,6 +6,8 @@ include configure.mk
# need to update the systemd service script # need to update the systemd service script
BINDIR = /usr/local/bin BINDIR = /usr/local/bin
swambe2 = false
GCC = g++ GCC = g++
ifeq ($(debug), true) ifeq ($(debug), true)
@ -14,7 +16,15 @@ else
CFLAGS = -W -Werror -Icodec2 -MMD -MD -std=c++11 CFLAGS = -W -Werror -Icodec2 -MMD -MD -std=c++11
endif endif
LDFLAGS = -lftd2xx -lmd380_vocoder -limbe_vocoder -pthread ifeq ($(swambe2), true)
CFLAGS+= -DUSE_SW_AMBE2
endif
LDFLAGS = -lftd2xx -limbe_vocoder -pthread
ifeq ($(swambe2), true)
LDFLAGS += -lmd380_vocoder
endif
SRCS = $(wildcard *.cpp) $(wildcard codec2/*.cpp) SRCS = $(wildcard *.cpp) $(wildcard codec2/*.cpp)
OBJS = $(SRCS:.cpp=.o) OBJS = $(SRCS:.cpp=.o)
@ -22,7 +32,11 @@ DEPS = $(SRCS:.cpp=.d)
EXE = tcd EXE = tcd
$(EXE) : $(OBJS) $(EXE) : $(OBJS)
ifeq ($(swambe2), true)
$(GCC) $(OBJS) $(LDFLAGS) -o $@ -Xlinker --section-start=.firmware=0x0800C000 -Xlinker --section-start=.sram=0x20000000 $(GCC) $(OBJS) $(LDFLAGS) -o $@ -Xlinker --section-start=.firmware=0x0800C000 -Xlinker --section-start=.sram=0x20000000
else
$(GCC) $(OBJS) $(LDFLAGS) -o $@
endif
%.o : %.cpp %.o : %.cpp
$(GCC) $(CFLAGS) -c $< -o $@ $(GCC) $(CFLAGS) -c $< -o $@

Loading…
Cancel
Save

Powered by TurnKey Linux.