From eca614d3d36e4d5a0c844b33c2f7ab293b347780 Mon Sep 17 00:00:00 2001 From: Tom Early Date: Sun, 26 Dec 2021 10:04:43 -0700 Subject: [PATCH] several improvements to CTranscoderPacket --- Controller.cpp | 44 ++++++++++++++++++++++++++++++++------------ DV3003.cpp | 15 ++++++++------- DV3003.h | 2 +- Main.cpp | 2 +- Timer.h | 1 + TranscoderPacket.cpp | 29 +++++++++++++++++++++++------ TranscoderPacket.h | 7 +++++-- 7 files changed, 71 insertions(+), 29 deletions(-) create mode 120000 Timer.h diff --git a/Controller.cpp b/Controller.cpp index 5a43c6b..91e6bd6 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -112,17 +112,29 @@ void CController::ReadReflectorThread() add_dst_mux.lock(); dstar_device.AddPacket(packet); add_dst_mux.unlock(); +#ifdef DEBUG + if (0 == packet->GetSequence()) + Dump(packet, "DStar from reflect to decode:"); +#endif break; case ECodecType::dmr: add_dmr_mux.lock(); dmr_device.AddPacket(packet); add_dmr_mux.unlock(); +#ifdef DEBUG + if (0 == packet->GetSequence()) + Dump(packet, "DMR from reflect to decode:"); +#endif break; case ECodecType::c2_1600: case ECodecType::c2_3200: c2_mux.lock(); codec2_queue.push(packet); c2_mux.unlock(); +#ifdef DEBUG + if (0 == packet->GetSequence()) + Dump(packet, "M17 from reflect to decode:"); +#endif break; default: Dump(packet, "ERROR: Received a reflector packet with unknown Codec:"); @@ -144,17 +156,17 @@ void CController::AudiotoCodec2(std::shared_ptr packet) // get the first half from the store memcpy(m17data, data_store[packet->GetModule()], 8); // and then calculate the second half - c2_32.codec2_encode(m17data+8, packet->GetAudio()); - packet->SetM17Data(m17data, true); + c2_32.codec2_encode(m17data+8, packet->GetAudioSamples()); + packet->SetM17Data(m17data); } else /* the packet is first */ { // calculate the first half... - c2_32.codec2_encode(m17data, packet->GetAudio()); + c2_32.codec2_encode(m17data, packet->GetAudioSamples()); // and then copy the calculated data to the data_store memcpy(data_store[packet->GetModule()], m17data, 8); // set the m17_is_set flag if this is the last packet - packet->SetM17Data(m17data, packet->IsLast()); + packet->SetM17Data(m17data); } // we might be all done... if (packet->AllCodecsAreSet()) @@ -175,13 +187,15 @@ void CController::Codec2toAudio(std::shared_ptr packet) { // we've already calculated the audio in the previous packet // copy the audio from local audio store - memcpy(packet->GetAudio(), audio_store[packet->GetModule()], 320); + packet->SetAudioSamples(audio_store[packet->GetModule()], false); } else /* codec_in is ECodecType::c2_3200 */ { + int16_t tmp[160]; // decode the second 8 data bytes // and put it in the packet - c2_32.codec2_decode(packet->GetAudio(), packet->GetM17Data()+8); + c2_32.codec2_decode(tmp, packet->GetM17Data()+8); + packet->SetAudioSamples(tmp, false); } } else /* it's a "first packet" */ @@ -195,13 +209,15 @@ void CController::Codec2toAudio(std::shared_ptr packet) c2_16.codec2_decode(tmp, packet->GetM17Data()); // 8 bytes input produces 320 audio points // move the first and second half // the first half is for the packet - memcpy(packet->GetAudio(), tmp, 320); + packet->SetAudioSamples(tmp, false); // and the second half goes into the audio store - memcpy(audio_store[packet->GetModule()], tmp+160, 320); + memcpy(audio_store[packet->GetModule()], &(tmp[160]), 320); } else /* codec_in is ECodecType::c2_3200 */ { - c2_32.codec2_decode(packet->GetAudio(), packet->GetM17Data()); + int16_t tmp[160]; + c2_32.codec2_decode(tmp, packet->GetM17Data()); + packet->SetAudioSamples(tmp, false); } } // the only thing left is to encode the two ambe, so push the packet onto both AMBE queues @@ -252,6 +268,10 @@ void CController::SendToReflector(std::shared_ptr packet) // send the packet over the socket socket.Send(packet->GetTCPacket()); // the socket will automatically close after sending +#ifdef DEBUG + if (0 == packet->GetSequence()) + Dump(packet, "Complete:"); +#endif } void CController::RouteDstPacket(std::shared_ptr packet) @@ -304,7 +324,7 @@ void CController::AppendWave(const std::shared_ptr packet) co std::ofstream pcmfile(sstr.str(), std::ofstream::app | std::ofstream::binary); if (pcmfile.good()) { - pcmfile.write(reinterpret_cast(packet->GetAudio()), 320); + pcmfile.write(reinterpret_cast(packet->GetAudioSamples()), 320); pcmfile.close(); } @@ -330,11 +350,11 @@ void CController::AppendM17(const std::shared_ptr packet) con void CController::Dump(const std::shared_ptr p, const std::string &title) const { std::stringstream line; - line << title << " Mod='" << p->GetModule() << "' SID=" << std::showbase << std::hex << ntohs(p->GetStreamId()) << std::noshowbase; + line << title << " Mod='" << p->GetModule() << "' SID=" << std::showbase << std::hex << ntohs(p->GetStreamId()) << std::noshowbase << " ET:" << std::setprecision(3) << p->GetTimeMS(); ECodecType in = p->GetCodecIn(); if (p->DStarIsSet()) - line << " D-Star"; + line << " DStar"; if (ECodecType::dstar == in) line << '*'; if (p->DMRIsSet()) diff --git a/DV3003.cpp b/DV3003.cpp index 384e422..d628b85 100644 --- a/DV3003.cpp +++ b/DV3003.cpp @@ -414,11 +414,11 @@ void CDV3003::FeedDevice() } else { - SendAudio(current_vocoder, packet->GetAudio()); + SendAudio(current_vocoder, packet->GetAudioSamples()); sp_depth++; } - if(++current_vocoder > 2) - current_vocoder = 0; + // if(++current_vocoder > 2) + // current_vocoder = 0; } } else // no packet is in the input queue @@ -457,6 +457,8 @@ void CDV3003::ReadDevice() auto packet = vocq[channel].pop(); if (PKT_CHANNEL == p.header.packet_type) { + if (12!=ntohs(p.header.payload_length) || 1!=p.payload.ambe.chand || 72!=p.payload.ambe.num_bits) + dump("Improper ambe packet:", &p, packet_size(p)); sp_depth--; if (Encoding::dstar == type) packet->SetDStarData(p.payload.ambe.data); @@ -466,11 +468,10 @@ void CDV3003::ReadDevice() } else if (PKT_SPEECH == p.header.packet_type) { + if (323!=ntohs(p.header.payload_length) || 0!=p.payload.audio.speechd || 160!=p.payload.audio.num_samples) + dump("Improper audio packet:", &p, packet_size(p)); ch_depth--; - auto pPCM = packet->GetAudio(); - for (unsigned int i=0; i<160; i++) - pPCM[i] = ntohs(p.payload.audio.samples[i]); - + packet->SetAudioSamples(p.payload.audio.samples, true); } else { diff --git a/DV3003.h b/DV3003.h index e0aba13..4b2c8d2 100644 --- a/DV3003.h +++ b/DV3003.h @@ -54,7 +54,7 @@ #define PKT_SPCHFMT 0x16 #define PKT_GAIN 0x4B -#define packet_size(a) int(1 + sizeof((a).header) + ntohs((a).header.payload_length)) +#define packet_size(a) int(4 + ntohs((a).header.payload_length)) #pragma pack(push, 1) struct dv3003_packet { diff --git a/Main.cpp b/Main.cpp index 1f37f10..192513d 100644 --- a/Main.cpp +++ b/Main.cpp @@ -27,7 +27,7 @@ int main() if (Controller.Start()) return EXIT_FAILURE; - std::cout << "Hybrid Transcoder Version #211221 Successfully started" << std::endl; + std::cout << "Hybrid Transcoder Version #211224 Successfully started" << std::endl; pause(); diff --git a/Timer.h b/Timer.h new file mode 120000 index 0000000..6d26c33 --- /dev/null +++ b/Timer.h @@ -0,0 +1 @@ +../urfd/reflector/Timer.h \ No newline at end of file diff --git a/TranscoderPacket.cpp b/TranscoderPacket.cpp index 7cca4de..0b95fe1 100644 --- a/TranscoderPacket.cpp +++ b/TranscoderPacket.cpp @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include #include #include "TranscoderPacket.h" @@ -22,9 +23,9 @@ CTranscoderPacket::CTranscoderPacket(const STCPacket &tcp) : dstar_set(false), d { tcpacket.module = tcp.module; tcpacket.is_last = tcp.is_last; - tcpacket.is_second = tcp.is_second; tcpacket.streamid = tcp.streamid; tcpacket.codec_in = tcp.codec_in; + tcpacket.sequence = tcp.sequence; switch (tcp.codec_in) { case ECodecType::dstar: @@ -35,7 +36,7 @@ CTranscoderPacket::CTranscoderPacket(const STCPacket &tcp) : dstar_set(false), d break; case ECodecType::c2_1600: case ECodecType::c2_3200: - SetM17Data(tcp.m17, true); + SetM17Data(tcp.m17); break; default: std::cerr << "Trying to allocate CTranscoderPacket with an unknown codec type!" << std::endl; @@ -68,10 +69,10 @@ const STCPacket *CTranscoderPacket::GetTCPacket() const return &tcpacket; } -void CTranscoderPacket::SetM17Data(const uint8_t *data, bool is_set) +void CTranscoderPacket::SetM17Data(const uint8_t *data) { memcpy(tcpacket.m17, data, 16); - m17_set = is_set; + m17_set = true; } void CTranscoderPacket::SetDStarData(const uint8_t *dstar) @@ -86,7 +87,13 @@ void CTranscoderPacket::SetDMRData(const uint8_t *dmr) dmr_set = true; } -int16_t *CTranscoderPacket::GetAudio() +void CTranscoderPacket::SetAudioSamples(const int16_t *sample, bool swap) +{ + for (unsigned int i=0; i<160; i++) + audio[i] = swap ? ntohs(sample[i]) : sample[i]; +} + +const int16_t *CTranscoderPacket::GetAudioSamples() const { return audio; } @@ -101,6 +108,16 @@ uint16_t CTranscoderPacket::GetStreamId() const return tcpacket.streamid; } +uint32_t CTranscoderPacket::GetSequence() const +{ + return tcpacket.sequence; +} + +double CTranscoderPacket::GetTimeMS() const +{ + return 1000.0 * tcpacket.rt_timer.time(); +} + bool CTranscoderPacket::IsLast() const { return tcpacket.is_last; @@ -108,7 +125,7 @@ bool CTranscoderPacket::IsLast() const bool CTranscoderPacket::IsSecond() const { - return tcpacket.is_second; + return (1 == tcpacket.sequence % 2); } bool CTranscoderPacket::DStarIsSet() const diff --git a/TranscoderPacket.h b/TranscoderPacket.h index f75dd9b..43e3e34 100644 --- a/TranscoderPacket.h +++ b/TranscoderPacket.h @@ -38,14 +38,17 @@ public: const uint8_t *GetM17Data() const; void SetDStarData(const uint8_t *dstar); void SetDMRData(const uint8_t *dmr); - void SetM17Data(const uint8_t *m17, bool is_set); + void SetM17Data(const uint8_t *m17); + void SetAudioSamples(const int16_t *samples, bool swap); // audio - int16_t *GetAudio(); + const int16_t *GetAudioSamples() const; // state of packet ECodecType GetCodecIn() const; uint16_t GetStreamId() const; + uint32_t GetSequence() const; + double GetTimeMS() const; bool IsLast() const; bool IsSecond() const; bool DStarIsSet() const;