support Linux versions of the AMBE library as well;

pull/134/head
Bryan Biedenkapp 5 days ago
parent 38604c34f2
commit b08629a896

@ -53,6 +53,7 @@ using namespace network::udp;
#if !defined(_WIN32)
#include <unistd.h>
#include <pwd.h>
#include <dlfcn.h>
#endif // !defined(_WIN32)
// ---------------------------------------------------------------------------
@ -283,20 +284,20 @@ HostBridge::HostBridge(const std::string& confFile) :
m_rtpTimestamp(INVALID_TS),
m_udpNetPktSeq(0U),
m_udpNetLastPktSeq(0U),
m_usrpSeqNo(0U)
#if defined(_WIN32)
,
m_usrpSeqNo(0U),
m_decoderState(nullptr),
m_dcMode(0U),
m_encoderState(nullptr),
m_ecMode(0U),
m_ambeDLL(nullptr),
m_useExternalVocoder(false),
m_frameLengthInBits(0),
m_frameLengthInBytes(0)
m_frameLengthInBytes(0),
#if defined(_WIN32)
m_ambeDLL(nullptr)
#else
m_ambeHandle(nullptr)
#endif // defined(_WIN32)
{
#if defined(_WIN32)
ambe_init_dec = nullptr;
ambe_get_dec_mode = nullptr;
ambe_voice_dec = nullptr;
@ -304,7 +305,7 @@ HostBridge::HostBridge(const std::string& confFile) :
ambe_init_enc = nullptr;
ambe_get_enc_mode = nullptr;
ambe_voice_enc = nullptr;
#endif // defined(_WIN32)
m_ambeBuffer = new uint8_t[27U];
::memset(m_ambeBuffer, 0x00U, 27U);
@ -538,6 +539,9 @@ int HostBridge::run()
#if defined(_WIN32)
initializeAMBEDLL();
#else
initializeAMBELib();
#endif // defined(_WIN32)
if (m_useExternalVocoder) {
m_decoderState = ::malloc(DECSTATE_SIZE);
::memset(m_decoderState, 0x00U, DECSTATE_SIZE);
@ -562,7 +566,6 @@ int HostBridge::run()
ambe_init_enc(m_encoderState, HALF_RATE_MODE, 1);
}
}
#endif // defined(_WIN32)
// set the In-Call Control function callback
if (m_network != nullptr) {
@ -762,13 +765,20 @@ int HostBridge::run()
delete m_mdcDecoder;
if (m_encoderState != nullptr) {
free(m_encoderState);
m_encoderState = nullptr;
}
if (m_decoderState != nullptr) {
free(m_decoderState);
m_decoderState = nullptr;
}
#if defined(_WIN32)
if (m_encoderState != nullptr)
delete m_encoderState;
if (m_decoderState != nullptr)
delete m_decoderState;
if (m_ambeDLL != nullptr)
::FreeLibrary(m_ambeDLL);
#else
if (m_ambeHandle != nullptr)
dlclose(m_ambeHandle);
#endif // defined(_WIN32)
if (m_localAudio) {
@ -793,6 +803,9 @@ void HostBridge::initializeAMBEDLL()
// get a handle to the DLL module.
m_ambeDLL = LoadLibrary(TEXT("AMBE.dll"));
if (m_ambeDLL == nullptr)
m_ambeDLL = LoadLibrary(TEXT("ambe_native.dll"));
if (m_ambeDLL != nullptr)
{
ambe_init_dec = (Tambe_init_dec)GetProcAddress(m_ambeDLL, "ambe_init_dec");
@ -807,6 +820,36 @@ void HostBridge::initializeAMBEDLL()
m_useExternalVocoder = true;
}
}
#else
/* Helper to initialize the use of the external AMBE binary for DVSI USB-3000. */
void HostBridge::initializeAMBELib()
{
m_useExternalVocoder = false;
m_ambeHandle = dlopen("libambe.so", RTLD_LAZY);
if (m_ambeHandle == nullptr)
m_ambeHandle = dlopen("./libambe.so", RTLD_LAZY);
if (m_ambeHandle == nullptr)
m_ambeHandle = dlopen("libambe_native.so", RTLD_LAZY);
if (m_ambeHandle == nullptr)
m_ambeHandle = dlopen("./libambe_native.so", RTLD_LAZY);
if (m_ambeHandle != nullptr)
{
ambe_init_dec = (Tambe_init_dec)dlsym(m_ambeHandle, "ambe_init_dec");
ambe_get_dec_mode = (Tambe_get_dec_mode)dlsym(m_ambeHandle, "ambe_get_dec_mode");
ambe_voice_dec = (Tambe_voice_dec)dlsym(m_ambeHandle, "ambe_voice_dec");
ambe_init_enc = (Tambe_init_enc)dlsym(m_ambeHandle, "ambe_init_enc");
ambe_get_enc_mode = (Tambe_get_enc_mode)dlsym(m_ambeHandle, "ambe_get_enc_mode");
ambe_voice_enc = (Tambe_voice_enc)dlsym(m_ambeHandle, "ambe_voice_enc");
::LogInfoEx(LOG_HOST, "Using external USB vocoder.");
m_useExternalVocoder = true;
}
}
#endif // defined(_WIN32)
/* Helper to unpack the codeword bytes into codeword bits for use with the AMBE decoder. */
@ -869,7 +912,7 @@ int HostBridge::ambeDecode(const uint8_t* codeword, uint32_t codewordLength, sho
::memcpy(cw.get(), codeword, codewordLength);
// is this a DMR codeword?
if (codewordLength > m_frameLengthInBytes && (m_txMode == TX_MODE_DMR || m_txMode == TX_MODE_NXDN) &&
if (codewordLength > (uint32_t)m_frameLengthInBytes && (m_txMode == TX_MODE_DMR || m_txMode == TX_MODE_NXDN) &&
codewordLength == 9)
{
// use the vocoder to retrieve the un-ECC'ed and uninterleaved AMBE bits
@ -881,13 +924,13 @@ int HostBridge::ambeDecode(const uint8_t* codeword, uint32_t codewordLength, sho
codewordLength = m_frameLengthInBytes;
}
if (codewordLength > m_frameLengthInBytes) {
::LogError(LOG_HOST, "Codeword length is > %u", m_frameLengthInBytes);
if (codewordLength > (uint32_t)m_frameLengthInBytes) {
::LogError(LOG_HOST, "Codeword length is > %u", (uint32_t)m_frameLengthInBytes);
return -1;
}
if (codewordLength < m_frameLengthInBytes) {
::LogError(LOG_HOST, "Codeword length is < %u", m_frameLengthInBytes);
if (codewordLength < (uint32_t)m_frameLengthInBytes) {
::LogError(LOG_HOST, "Codeword length is < %u", (uint32_t)m_frameLengthInBytes);
return -1;
}
@ -902,9 +945,9 @@ int HostBridge::ambeDecode(const uint8_t* codeword, uint32_t codewordLength, sho
ambe_voice_dec(n1.get(), AUDIO_SAMPLES_LENGTH / 2, codewordBits.get(), NO_BIT_STEAL, m_dcMode, 1, m_decoderState);
// combine sample segments into contiguous samples
for (int i = 0; i < AUDIO_SAMPLES_LENGTH / 2; i++)
for (int i = 0; i < (int)AUDIO_SAMPLES_LENGTH / 2; i++)
samples[i] = n0[i];
for (int i = 0; i < AUDIO_SAMPLES_LENGTH / 2; i++)
for (int i = 0; i < (int)AUDIO_SAMPLES_LENGTH / 2; i++)
samples[i + (AUDIO_SAMPLES_LENGTH / 2)] = n1[i];
return 0; // this always just returns no errors?
@ -982,13 +1025,13 @@ void HostBridge::ambeEncode(const short* samples, uint32_t sampleLength, uint8_t
// split samples into 2 segments
std::unique_ptr<short[]> n0 = std::make_unique<short[]>(AUDIO_SAMPLES_LENGTH / 2);
for (int i = 0; i < AUDIO_SAMPLES_LENGTH / 2; i++)
for (int i = 0; i < (int)AUDIO_SAMPLES_LENGTH / 2; i++)
n0[i] = samples[i];
ambe_voice_enc(codewordBits.get(), NO_BIT_STEAL, n0.get(), AUDIO_SAMPLES_LENGTH / 2, m_ecMode, 0, 8192, m_encoderState);
std::unique_ptr<short[]> n1 = std::make_unique<short[]>(AUDIO_SAMPLES_LENGTH / 2);
for (int i = 0; i < AUDIO_SAMPLES_LENGTH / 2; i++)
for (int i = 0; i < (int)AUDIO_SAMPLES_LENGTH / 2; i++)
n1[i] = samples[i + (AUDIO_SAMPLES_LENGTH / 2)];
ambe_voice_enc(codewordBits.get(), NO_BIT_STEAL, n1.get(), AUDIO_SAMPLES_LENGTH / 2, m_ecMode, 1, 8192, m_encoderState);
@ -1007,7 +1050,6 @@ void HostBridge::ambeEncode(const short* samples, uint32_t sampleLength, uint8_t
packBitsToBytes(codewordBits.get(), codeword, m_frameLengthInBytes, m_frameLengthInBits);
}
}
#endif // defined(_WIN32)
/* Reads basic configuration parameters from the YAML configuration file. */

@ -327,19 +327,45 @@ private:
static std::mutex s_audioMutex;
static std::mutex s_networkMutex;
#if defined(_WIN32)
void* m_decoderState;
uint16_t m_dcMode;
void* m_encoderState;
uint16_t m_ecMode;
HINSTANCE m_ambeDLL;
bool m_useExternalVocoder;
int m_frameLengthInBits;
int m_frameLengthInBytes;
#if defined(_WIN32)
HINSTANCE m_ambeDLL;
typedef void(__cdecl* Tambe_init_dec)(void* state, short mode);
typedef short(__cdecl* Tambe_get_dec_mode)(void* state);
typedef uint32_t(__cdecl* Tambe_voice_dec)(short* samples, short sampleLength, short* packedCodeword, short bitSteal, uint16_t cmode, short n, void* state);
typedef void(__cdecl* Tambe_init_enc)(void* state, short mode, short initialize);
typedef short(__cdecl* Tambe_get_enc_mode)(void* state);
typedef uint32_t(__cdecl* Tambe_voice_enc)(short* packedCodeword, short bitSteal, short* samples, short sampleLength, uint16_t cmode, short n, short, void* state);
/**
* @brief Helper to initialize the use of the external AMBE.DLL binary for DVSI USB-3000.
*/
void initializeAMBEDLL();
#else
void* m_ambeHandle;
typedef void(*Tambe_init_dec)(void* state, short mode);
typedef short(*Tambe_get_dec_mode)(void* state);
typedef uint32_t(*Tambe_voice_dec)(short* samples, short sampleLength, short* packedCodeword, short bitSteal, uint16_t cmode, short n, void* state);
typedef void(*Tambe_init_enc)(void* state, short mode, short initialize);
typedef short(*Tambe_get_enc_mode)(void* state);
typedef uint32_t(*Tambe_voice_enc)(short* packedCodeword, short bitSteal, short* samples, short sampleLength, uint16_t cmode, short n, short, void* state);
/**
* @brief Helper to initialize the use of the external AMBE binary for DVSI USB-3000.
*/
void initializeAMBELib();
#endif // defined(_WIN32)
/**
* @brief Initialize the AMBE decoder.
* @param[out] state Buffer containing the decoder state to initialize.
@ -347,7 +373,6 @@ private:
*/
Tambe_init_dec ambe_init_dec;
typedef short(__cdecl* Tambe_get_dec_mode)(void* state);
/**
* @brief Get the current operating state of the AMBE decoder.
* @param[out] state Buffer containing the decoder state.
@ -355,7 +380,6 @@ private:
*/
Tambe_get_dec_mode ambe_get_dec_mode;
typedef uint32_t(__cdecl* Tambe_voice_dec)(short* samples, short sampleLength, short* packedCodeword, short bitSteal, uint16_t cmode, short n, void* state);
/**
* @brief Decode AMBE codeword into PCM samples.
* @param[out] samples Audio Output (in short samples)
@ -369,7 +393,6 @@ private:
*/
Tambe_voice_dec ambe_voice_dec;
typedef void(__cdecl* Tambe_init_enc)(void* state, short mode, short initialize);
/**
* @brief Initialize the AMBE decoder.
* @param[out] state Buffer containing the ebncoder state to initialize.
@ -378,7 +401,6 @@ private:
*/
Tambe_init_enc ambe_init_enc;
typedef short(__cdecl* Tambe_get_enc_mode)(void* state);
/**
* @brief Get the current operating state of the AMBE encoder.
* @param[out] state Buffer containing the decoder state.
@ -386,7 +408,6 @@ private:
*/
Tambe_get_enc_mode ambe_get_enc_mode;
typedef uint32_t(__cdecl* Tambe_voice_enc)(short* packedCodeword, short bitSteal, short* samples, short sampleLength, uint16_t cmode, short n, short, void* state);
/**
* @brief Decode AMBE codeword into PCM samples.
* @param[out] packedCodeword AMBE codewords.
@ -401,11 +422,6 @@ private:
*/
Tambe_voice_enc ambe_voice_enc;
/**
* @brief Helper to initialize the use of the external AMBE.DLL binary for DVSI USB-3000.
*/
void initializeAMBEDLL();
/**
* @brief Helper to unpack the codeword bytes into codeword bits for use with the AMBE decoder.
* @param[out] codewordBits Codeword bits.
@ -455,7 +471,6 @@ private:
* @returns int
*/
void ambeEncode(const short* samples, uint32_t sampleLength, uint8_t* codeword);
#endif // defined(_WIN32)
/**
* @brief Reads basic configuration parameters from the INI.

Loading…
Cancel
Save

Powered by TurnKey Linux.