module based vocoding

main
Tom Early 4 years ago
parent eca614d3d3
commit 090b7379ea

@ -55,8 +55,43 @@ void CController::Stop()
dmr_device.CloseDevice();
}
bool CController::CheckTCModules() const
{
// make sure the configured transcoded modules seems okay
const std::string modules(TRANSCODED_MODULES);
bool trouble = false;
if (modules.size() > 3)
{
std::cerr << "Too many transcoded modules defined!" << std::endl;
trouble = true;
}
for (unsigned int i =0; i<modules.size(); i++)
{
auto c = modules.at(i);
if (c < 'A' || c > 'Z') {
std::cerr << "Transcoded modules[" << i << "] is not an uppercase letter!" << std::endl;
trouble = true;
}
}
return trouble;
}
bool CController::InitDevices()
{
if (CheckTCModules())
return true;
// M17 "devices", one for each module
const std::string modules(TRANSCODED_MODULES);
for ( auto c : modules)
{
c2_16[c] = std::unique_ptr<CCodec2>(new CCodec2(false));
c2_32[c] = std::unique_ptr<CCodec2>(new CCodec2(true));
}
// the 3003 devices
std::vector<std::string> deviceset;
std::string device;
@ -151,18 +186,19 @@ void CController::AudiotoCodec2(std::shared_ptr<CTranscoderPacket> packet)
{
// the second half is silent in case this is frame is last.
uint8_t m17data[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x01, 0x43, 0x09, 0xe4, 0x9c, 0x08, 0x21 };
const auto m = packet->GetModule();
if (packet->IsSecond())
{
// 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->GetAudioSamples());
c2_32[m]->codec2_encode(m17data+8, packet->GetAudioSamples());
packet->SetM17Data(m17data);
}
else /* the packet is first */
{
// calculate the first half...
c2_32.codec2_encode(m17data, packet->GetAudioSamples());
c2_32[m]->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
@ -194,19 +230,20 @@ void CController::Codec2toAudio(std::shared_ptr<CTranscoderPacket> packet)
int16_t tmp[160];
// decode the second 8 data bytes
// and put it in the packet
c2_32.codec2_decode(tmp, packet->GetM17Data()+8);
c2_32[packet->GetModule()]->codec2_decode(tmp, packet->GetM17Data()+8);
packet->SetAudioSamples(tmp, false);
}
}
else /* it's a "first packet" */
{
const auto m = packet->GetModule();
if (packet->GetCodecIn() == ECodecType::c2_1600)
{
// c2_1600 encodes 40 ms of audio, 320 points, so...
// we need some temporary audio storage for decoding c2_1600:
int16_t tmp[320];
// decode it into the temporary storage
c2_16.codec2_decode(tmp, packet->GetM17Data()); // 8 bytes input produces 320 audio points
c2_16[m]->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
packet->SetAudioSamples(tmp, false);
@ -216,7 +253,7 @@ void CController::Codec2toAudio(std::shared_ptr<CTranscoderPacket> packet)
else /* codec_in is ECodecType::c2_3200 */
{
int16_t tmp[160];
c2_32.codec2_decode(tmp, packet->GetM17Data());
c2_32[m]->codec2_decode(tmp, packet->GetM17Data());
packet->SetAudioSamples(tmp, false);
}
}

@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <map>
#include <unordered_map>
#include <memory>
#include <atomic>
#include <future>
@ -44,12 +44,11 @@ public:
protected:
std::atomic<bool> keep_running;
std::future<void> reflectorFuture, c2Future;
std::map<char, int16_t[160]> audio_store;
std::map<char, uint8_t[8]> data_store;
std::unordered_map<char, int16_t[160]> audio_store;
std::unordered_map<char, uint8_t[8]> data_store;
CUnixDgramReader reader;
CUnixDgramWriter writer;
CCodec2 c2_16{false};
CCodec2 c2_32{true};
std::unordered_map<char, std::unique_ptr<CCodec2>> c2_16, c2_32;
CDV3003 dstar_device{Encoding::dstar};
CDV3003 dmr_device{Encoding::dmr};
@ -60,6 +59,7 @@ protected:
// processing threads
void ReadReflectorThread();
void ProcessC2Thread();
bool CheckTCModules() const;
void Codec2toAudio(std::shared_ptr<CTranscoderPacket> packet);
void AudiotoCodec2(std::shared_ptr<CTranscoderPacket> packet);
void SendToReflector(std::shared_ptr<CTranscoderPacket> packet);

@ -377,7 +377,7 @@ bool CDV3003::GetResponse(SDV3003_Packet &packet)
void CDV3003::FeedDevice()
{
uint8_t current_vocoder = 0;
const std::string modules(TRANSCODED_MODULES);
while (keep_running)
{
auto packet = inq.pop();
@ -404,21 +404,20 @@ void CDV3003::FeedDevice()
if (keep_running)
{
auto index = modules.find(packet->GetModule());
// save the packet in the vocoder's queue while the vocoder does its magic
vocq[current_vocoder].push(packet);
vocq[index].push(packet);
if (needs_audio)
{
SendData(current_vocoder, (Encoding::dstar==type) ? packet->GetDStarData() : packet->GetDMRData());
SendData(index, (Encoding::dstar==type) ? packet->GetDStarData() : packet->GetDMRData());
ch_depth++;
}
else
{
SendAudio(current_vocoder, packet->GetAudioSamples());
SendAudio(index, packet->GetAudioSamples());
sp_depth++;
}
// if(++current_vocoder > 2)
// current_vocoder = 0;
}
}
else // no packet is in the input queue

@ -27,7 +27,7 @@ int main()
if (Controller.Start())
return EXIT_FAILURE;
std::cout << "Hybrid Transcoder Version #211224 Successfully started" << std::endl;
std::cout << "Hybrid Transcoder version #211227 successfully started" << std::endl;
pause();

Loading…
Cancel
Save

Powered by TurnKey Linux.