refactored device inheritance

main
Tom Early 4 years ago
parent 1a0701e51e
commit e160df052b

@ -160,8 +160,8 @@ bool CController::InitVocoders()
}
Edvtype dvtype = Edvtype::dv3003;
if (0==desc.compare("ThumbDV") || 0==desc.compare("DVstick-33") || 0==desc.compare("USB-3000"))
dvtype = Edvtype::dv3000;
if (0==desc.compare("ThumbDV") || 0==desc.compare("DVstick-30") || 0==desc.compare("USB-3000"))
dvtype = Edvtype::dv3000;
if (modules.size() > ((Edvtype::dv3000 == dvtype) ? 1 : 3))
{

@ -42,123 +42,14 @@ CDV3000::CDV3000(Encoding t) : CDVDevice(t) {}
CDV3000::~CDV3000() {}
void CDV3000::FeedDevice()
void CDV3000::PushWaitingPacket(unsigned int /* channel */, std::shared_ptr<CTranscoderPacket> packet)
{
const std::string modules(TRANSCODED_MODULES);
const auto n = modules.size();
while (keep_running)
{
auto packet = input_queue.pop(); // blocks until there is something to pop
while (keep_running) // wait until there is room
{
if (buffer_depth < 2)
break;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
if (keep_running)
{
auto index = modules.find(packet->GetModule());
// save the packet in the vocoder's queue while the vocoder does its magic
if (std::string::npos == index)
{
std::cerr << "Module '" << packet->GetModule() << "' is not configured on " << description << std::endl;
}
else
{
waiting_packet.push(packet);
const bool needs_audio = (Encoding::dstar==type) ? packet->DStarIsSet() : packet->DMRIsSet();
if (needs_audio)
{
SendData(index, (Encoding::dstar==type) ? packet->GetDStarData() : packet->GetDMRData());
}
else
{
SendAudio(index, packet->GetAudioSamples());
}
buffer_depth++;
}
}
}
waiting_packet.push(packet);
}
void CDV3000::ReadDevice()
std::shared_ptr<CTranscoderPacket> CDV3000::PopWaitingPacket(unsigned int /* channel */)
{
while (keep_running)
{
// wait for something to read...
DWORD RxBytes = 0;
while (0 == RxBytes)
{
EVENT_HANDLE eh;
pthread_mutex_init(&eh.eMutex, NULL);
pthread_cond_init(&eh.eCondVar, NULL);
DWORD EventMask = FT_EVENT_RXCHAR;
auto status = FT_SetEventNotification(ftHandle, EventMask, &eh);
if (FT_OK != status)
{
FTDI_Error("Setting Event Notification", status);
}
pthread_mutex_lock(&eh.eMutex);
pthread_cond_wait(&eh.eCondVar, &eh.eMutex);
pthread_mutex_unlock(&eh.eMutex);
DWORD EventDWord, TxBytes, Status;
status = FT_GetStatus(ftHandle, &RxBytes, &TxBytes, &EventDWord);
if (FT_OK != status)
{
FTDI_Error("Getting Event Status", status);
}
}
SDV_Packet p;
if (! GetResponse(p))
{
unsigned int channel = p.field_id - PKT_CHANNEL0;
auto packet = waiting_packet.pop();
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)
dump("Improper ambe packet:", &p, packet_size(p));
buffer_depth--;
if (Encoding::dstar == type)
packet->SetDStarData(p.payload.ambe.data);
else
packet->SetDMRData(p.payload.ambe.data);
}
else if (PKT_SPEECH == p.header.packet_type)
{
if (323!=ntohs(p.header.payload_length) || PKT_SPEECHD!=p.payload.audio.speechd || 160!=p.payload.audio.num_samples)
dump("Improper audio packet:", &p, packet_size(p));
buffer_depth--;
packet->SetAudioSamples(p.payload.audio.samples, true);
}
else
{
dump("ReadDevice() ERROR: Read an unexpected device packet:", &p, packet_size(p));
continue;
}
if (Encoding::dstar == type) // is this a DMR or a DStar device?
{
Controller.dstar_mux.lock();
Controller.RouteDstPacket(packet);
Controller.dstar_mux.unlock();
}
else
{
Controller.dmrst_mux.lock();
Controller.RouteDmrPacket(packet);
Controller.dmrst_mux.unlock();
}
}
}
return waiting_packet.pop();
}
bool CDV3000::SendAudio(const uint8_t /*channel*/, const int16_t *audio) const

@ -26,8 +26,8 @@ public:
virtual ~CDV3000();
protected:
void FeedDevice();
void ReadDevice();
void PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet);
std::shared_ptr<CTranscoderPacket> PopWaitingPacket(unsigned int channel);
bool SendAudio(const uint8_t channel, const int16_t *audio) const;
bool SendData(const uint8_t channel, const uint8_t *data) const;

@ -42,123 +42,14 @@ CDV3003::CDV3003(Encoding t) : CDVDevice(t) {}
CDV3003::~CDV3003() {}
void CDV3003::FeedDevice()
void CDV3003::PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet)
{
const std::string modules(TRANSCODED_MODULES);
const auto n = modules.size();
while (keep_running)
{
auto packet = input_queue.pop(); // blocks until there is something to pop
while (keep_running) // wait until there is room
{
if (buffer_depth < 2)
break;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
if (keep_running)
{
auto index = modules.find(packet->GetModule());
// save the packet in the vocoder's queue while the vocoder does its magic
if (std::string::npos == index)
{
std::cerr << "Module '" << packet->GetModule() << "' is not configured on " << description << std::endl;
}
else
{
waiting_packet[index].push(packet);
const bool needs_audio = (Encoding::dstar==type) ? packet->DStarIsSet() : packet->DMRIsSet();
if (needs_audio)
{
SendData(index, (Encoding::dstar==type) ? packet->GetDStarData() : packet->GetDMRData());
}
else
{
SendAudio(index, packet->GetAudioSamples());
}
buffer_depth++;
}
}
}
waiting_packet[channel].push(packet);
}
void CDV3003::ReadDevice()
std::shared_ptr<CTranscoderPacket> CDV3003::PopWaitingPacket(unsigned int channel)
{
while (keep_running)
{
// wait for something to read...
DWORD RxBytes = 0;
while (0 == RxBytes)
{
EVENT_HANDLE eh;
pthread_mutex_init(&eh.eMutex, NULL);
pthread_cond_init(&eh.eCondVar, NULL);
DWORD EventMask = FT_EVENT_RXCHAR;
auto status = FT_SetEventNotification(ftHandle, EventMask, &eh);
if (FT_OK != status)
{
FTDI_Error("Setting Event Notification", status);
}
pthread_mutex_lock(&eh.eMutex);
pthread_cond_wait(&eh.eCondVar, &eh.eMutex);
pthread_mutex_unlock(&eh.eMutex);
DWORD EventDWord, TxBytes, Status;
status = FT_GetStatus(ftHandle, &RxBytes, &TxBytes, &EventDWord);
if (FT_OK != status)
{
FTDI_Error("Getting Event Status", status);
}
}
SDV_Packet p;
if (! GetResponse(p))
{
unsigned int channel = p.field_id - PKT_CHANNEL0;
auto packet = waiting_packet[channel].pop();
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)
dump("Improper ambe packet:", &p, packet_size(p));
buffer_depth--;
if (Encoding::dstar == type)
packet->SetDStarData(p.payload.ambe.data);
else
packet->SetDMRData(p.payload.ambe.data);
}
else if (PKT_SPEECH == p.header.packet_type)
{
if (323!=ntohs(p.header.payload_length) || PKT_SPEECHD!=p.payload.audio.speechd || 160!=p.payload.audio.num_samples)
dump("Improper audio packet:", &p, packet_size(p));
buffer_depth--;
packet->SetAudioSamples(p.payload.audio.samples, true);
}
else
{
dump("ReadDevice() ERROR: Read an unexpected device packet:", &p, packet_size(p));
continue;
}
if (Encoding::dstar == type) // is this a DMR or a DStar device?
{
Controller.dstar_mux.lock();
Controller.RouteDstPacket(packet);
Controller.dstar_mux.unlock();
}
else
{
Controller.dmrst_mux.lock();
Controller.RouteDmrPacket(packet);
Controller.dmrst_mux.unlock();
}
}
}
return waiting_packet[channel].pop();
}
bool CDV3003::SendAudio(const uint8_t channel, const int16_t *audio) const

@ -26,8 +26,8 @@ public:
virtual ~CDV3003();
protected:
void FeedDevice();
void ReadDevice();
void PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet);
std::shared_ptr<CTranscoderPacket> PopWaitingPacket(unsigned int channel);
bool SendAudio(const uint8_t channel, const int16_t *audio) const;
bool SendData(const uint8_t channel, const uint8_t *data) const;

@ -228,10 +228,10 @@ bool CDVDevice::OpenDevice(const std::string &serialno, const std::string &desc,
// }
description.assign(desc);
description.append("-");
description.append(" ");
description.append(serialno);
std::cout << "Opened " << description << " at " << baudrate << " baud with a " << maxsize << "byte max transfer size" << std::endl;
std::cout << "Opened " << description << " at " << baudrate << " baud with a " << maxsize << " byte max transfer size" << std::endl;
if (InitDevice())
return true;
@ -555,3 +555,122 @@ void CDVDevice::dump(const char *title, void *pointer, int length) const
length = 0;
}
}
void CDVDevice::FeedDevice()
{
const std::string modules(TRANSCODED_MODULES);
const auto n = modules.size();
while (keep_running)
{
auto packet = input_queue.pop(); // blocks until there is something to pop
while (keep_running) // wait until there is room
{
if (buffer_depth < 2)
break;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
if (keep_running)
{
auto index = modules.find(packet->GetModule());
// save the packet in the vocoder's queue while the vocoder does its magic
if (std::string::npos == index)
{
std::cerr << "Module '" << packet->GetModule() << "' is not configured on " << description << std::endl;
}
else
{
PushWaitingPacket(index, packet);
const bool needs_audio = (Encoding::dstar==type) ? packet->DStarIsSet() : packet->DMRIsSet();
if (needs_audio)
{
SendData(index, (Encoding::dstar==type) ? packet->GetDStarData() : packet->GetDMRData());
}
else
{
SendAudio(index, packet->GetAudioSamples());
}
buffer_depth++;
}
}
}
}
void CDVDevice::ReadDevice()
{
while (keep_running)
{
// wait for something to read...
DWORD RxBytes = 0;
while (0 == RxBytes)
{
EVENT_HANDLE eh;
pthread_mutex_init(&eh.eMutex, NULL);
pthread_cond_init(&eh.eCondVar, NULL);
DWORD EventMask = FT_EVENT_RXCHAR;
auto status = FT_SetEventNotification(ftHandle, EventMask, &eh);
if (FT_OK != status)
{
FTDI_Error("Setting Event Notification", status);
}
pthread_mutex_lock(&eh.eMutex);
pthread_cond_wait(&eh.eCondVar, &eh.eMutex);
pthread_mutex_unlock(&eh.eMutex);
DWORD EventDWord, TxBytes, Status;
status = FT_GetStatus(ftHandle, &RxBytes, &TxBytes, &EventDWord);
if (FT_OK != status)
{
FTDI_Error("Getting Event Status", status);
}
}
SDV_Packet p;
if (! GetResponse(p))
{
unsigned int channel = p.field_id - PKT_CHANNEL0;
auto packet = PopWaitingPacket(channel);
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)
dump("Improper ambe packet:", &p, packet_size(p));
buffer_depth--;
if (Encoding::dstar == type)
packet->SetDStarData(p.payload.ambe.data);
else
packet->SetDMRData(p.payload.ambe.data);
}
else if (PKT_SPEECH == p.header.packet_type)
{
if (323!=ntohs(p.header.payload_length) || PKT_SPEECHD!=p.payload.audio.speechd || 160!=p.payload.audio.num_samples)
dump("Improper audio packet:", &p, packet_size(p));
buffer_depth--;
packet->SetAudioSamples(p.payload.audio.samples, true);
}
else
{
dump("ReadDevice() ERROR: Read an unexpected device packet:", &p, packet_size(p));
continue;
}
if (Encoding::dstar == type) // is this a DMR or a DStar device?
{
Controller.dstar_mux.lock();
Controller.RouteDstPacket(packet);
Controller.dstar_mux.unlock();
}
else
{
Controller.dmrst_mux.lock();
Controller.RouteDmrPacket(packet);
Controller.dmrst_mux.unlock();
}
}
}
}

@ -47,15 +47,18 @@ protected:
std::string description;
bool DiscoverFtdiDevices();
void FTDI_Error(const char *where, FT_STATUS status) const;
bool InitDevice();
bool ConfigureVocoder(uint8_t pkt_ch, Encoding type);
bool checkResponse(SDV_Packet &responsePacket, uint8_t response) const;
bool GetResponse(SDV_Packet &packet);
bool InitDevice();
void FeedDevice();
void ReadDevice();
void FTDI_Error(const char *where, FT_STATUS status) const;
void dump(const char *title, void *data, int length) const;
// pure virtual methods unique to the device type
virtual void FeedDevice() = 0;
virtual void ReadDevice() = 0;
virtual void PushWaitingPacket(unsigned int channel, std::shared_ptr<CTranscoderPacket> packet) = 0;
virtual std::shared_ptr<CTranscoderPacket> PopWaitingPacket(unsigned int channel) = 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;
};

Loading…
Cancel
Save

Powered by TurnKey Linux.