diff --git a/Controller.cpp b/Controller.cpp index 97a0d58..6dd8dc7 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -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)) { diff --git a/DV3000.cpp b/DV3000.cpp index e065c95..657c066 100644 --- a/DV3000.cpp +++ b/DV3000.cpp @@ -42,123 +42,14 @@ CDV3000::CDV3000(Encoding t) : CDVDevice(t) {} CDV3000::~CDV3000() {} -void CDV3000::FeedDevice() +void CDV3000::PushWaitingPacket(unsigned int /* channel */, std::shared_ptr 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 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 diff --git a/DV3000.h b/DV3000.h index 8a0b8a9..b87f268 100644 --- a/DV3000.h +++ b/DV3000.h @@ -26,8 +26,8 @@ public: virtual ~CDV3000(); protected: - void FeedDevice(); - void ReadDevice(); + void PushWaitingPacket(unsigned int channel, std::shared_ptr packet); + std::shared_ptr 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; diff --git a/DV3003.cpp b/DV3003.cpp index e26faae..a64716d 100644 --- a/DV3003.cpp +++ b/DV3003.cpp @@ -42,123 +42,14 @@ CDV3003::CDV3003(Encoding t) : CDVDevice(t) {} CDV3003::~CDV3003() {} -void CDV3003::FeedDevice() +void CDV3003::PushWaitingPacket(unsigned int channel, std::shared_ptr 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 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 diff --git a/DV3003.h b/DV3003.h index b6a761f..f1794bb 100644 --- a/DV3003.h +++ b/DV3003.h @@ -26,8 +26,8 @@ public: virtual ~CDV3003(); protected: - void FeedDevice(); - void ReadDevice(); + void PushWaitingPacket(unsigned int channel, std::shared_ptr packet); + std::shared_ptr 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; diff --git a/DVSIDevice.cpp b/DVSIDevice.cpp index b75b5ac..adffb80 100644 --- a/DVSIDevice.cpp +++ b/DVSIDevice.cpp @@ -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(); + } + } + } +} diff --git a/DVSIDevice.h b/DVSIDevice.h index a087298..b701698 100644 --- a/DVSIDevice.h +++ b/DVSIDevice.h @@ -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 packet) = 0; + virtual std::shared_ptr 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; };