mirror of
https://github.com/ShaYmez/xlxd.git
synced 2024-12-21 17:10:59 -05:00
ambed 1.3.0
Improved performances. Most device configuration can now run all available channels concurrently. See readme for details.
This commit is contained in:
parent
ddc52640df
commit
18a5cd9544
@ -48,6 +48,9 @@ public:
|
||||
// destructor
|
||||
virtual ~CAmbePacket();
|
||||
|
||||
// identity
|
||||
bool IsAmbe(void) const { return true; }
|
||||
|
||||
// get
|
||||
uint8 GetCodec(void) const { return m_uiCodec; }
|
||||
uint8 *GetAmbe(void) { return m_uiAmbe; }
|
||||
|
@ -40,13 +40,17 @@ public:
|
||||
// destructor
|
||||
virtual ~CPacket() {};
|
||||
|
||||
// identity
|
||||
virtual bool IsVoice(void) const { return false; }
|
||||
virtual bool IsAmbe(void) const { return false; }
|
||||
|
||||
// get
|
||||
int GetChannel(void) const { return m_iCh; }
|
||||
uint8 GetPid(void) const { return m_uiPid; }
|
||||
int GetChannel(void) const { return m_iCh; }
|
||||
uint8 GetPid(void) const { return m_uiPid; }
|
||||
|
||||
// set
|
||||
void SetChannel(int i) { m_iCh = i; }
|
||||
void SetPid(uint8 ui) { m_uiPid = ui; }
|
||||
void SetChannel(int i) { m_iCh = i; }
|
||||
void SetPid(uint8 ui) { m_uiPid = ui; }
|
||||
|
||||
protected:
|
||||
// data
|
||||
|
@ -70,6 +70,7 @@ protected:
|
||||
bool OpenDevice(void);
|
||||
bool ResetDevice(void);
|
||||
bool ConfigureDevice(void);
|
||||
int GetDeviceFifoSize(void) const { return 2; }
|
||||
|
||||
// data
|
||||
uint8 m_uiChCodecs[USB3003_NB_CH];
|
||||
|
@ -39,12 +39,12 @@
|
||||
CUsb3xxxInterface::CUsb3xxxInterface(uint32 uiVid, uint32 uiPid, const char *szDeviceName, const char *szDeviceSerial)
|
||||
{
|
||||
m_FtdiHandle = NULL;
|
||||
m_iDeviceFifoLevel = 0;
|
||||
m_iActiveQueue = QUEUE_CHANNEL;
|
||||
m_uiVid = uiVid;
|
||||
m_uiPid = uiPid;
|
||||
::strcpy(m_szDeviceName, szDeviceName);
|
||||
::strcpy(m_szDeviceSerial, szDeviceSerial);
|
||||
m_iSpeechFifolLevel = 0;
|
||||
m_iChannelFifolLevel = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -52,6 +52,19 @@ CUsb3xxxInterface::CUsb3xxxInterface(uint32 uiVid, uint32 uiPid, const char *szD
|
||||
|
||||
CUsb3xxxInterface::~CUsb3xxxInterface()
|
||||
{
|
||||
// delete m_SpeechQueues
|
||||
for ( int i = 0; i < m_SpeechQueues.size(); i++ )
|
||||
{
|
||||
delete m_SpeechQueues[i];
|
||||
}
|
||||
m_SpeechQueues.clear();
|
||||
|
||||
// delete m_ChannelQueues
|
||||
for ( int i = 0; i < m_ChannelQueues.size(); i++ )
|
||||
{
|
||||
delete m_ChannelQueues[i];
|
||||
}
|
||||
m_ChannelQueues.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -82,6 +95,13 @@ bool CUsb3xxxInterface::Init(void)
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// create our queues
|
||||
for ( int i = 0; i < GetNbChannels(); i++ )
|
||||
{
|
||||
m_SpeechQueues.push_back(new CPacketQueue);
|
||||
m_ChannelQueues.push_back(new CPacketQueue);
|
||||
}
|
||||
|
||||
// base class
|
||||
if ( ok )
|
||||
{
|
||||
@ -118,11 +138,10 @@ void CUsb3xxxInterface::Task(void)
|
||||
{
|
||||
if ( IsValidSpeechPacket(Buffer, &iCh, &VoicePacket) )
|
||||
{
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "->Sp" << iCh << std::endl; std::cout.flush();
|
||||
#endif
|
||||
// update fifo status
|
||||
m_iDeviceFifoLevel = MAX(m_iDeviceFifoLevel-1, 0);
|
||||
// update fifo level
|
||||
// as we get a speech packet, it means that the device
|
||||
// channel fifo input decreased by 1
|
||||
m_iChannelFifolLevel = MAX(0, m_iChannelFifolLevel-1);
|
||||
|
||||
// push back to relevant channel voice queue
|
||||
// our incoming channel packet has now been through the decoder
|
||||
@ -140,13 +159,14 @@ void CUsb3xxxInterface::Task(void)
|
||||
}
|
||||
else if ( IsValidChannelPacket(Buffer, &iCh, &AmbePacket) )
|
||||
{
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "->Ch" << iCh << std::endl; std::cout.flush();
|
||||
#endif
|
||||
// update fifo status
|
||||
m_iDeviceFifoLevel = MAX(m_iDeviceFifoLevel-1, 0);
|
||||
|
||||
// update fifo level
|
||||
// as we get a channel packet, it means that the device
|
||||
// speech fifo input decreased by 1
|
||||
m_iSpeechFifolLevel = MAX(0, m_iSpeechFifolLevel-1);
|
||||
|
||||
// push back to relevant channel outcoming queue
|
||||
// we are done with this packet transcoding
|
||||
// it's final step
|
||||
Channel = GetChannelWithChannelOut(iCh);
|
||||
if ( Channel != NULL )
|
||||
{
|
||||
@ -178,9 +198,12 @@ void CUsb3xxxInterface::Task(void)
|
||||
// get packet
|
||||
CVoicePacket *Packet = (CVoicePacket *)Queue->front();
|
||||
Queue->pop();
|
||||
// this is second step of transcoding
|
||||
// we just received from hardware a decoded speech packet
|
||||
// post it to relevant channel encoder
|
||||
Packet->SetChannel(Channel->GetChannelOut());
|
||||
m_SpeechQueue.push(Packet);
|
||||
int i = Channel->GetChannelOut();
|
||||
Packet->SetChannel(i);
|
||||
m_SpeechQueues[i]->push(Packet);
|
||||
// done
|
||||
done = false;
|
||||
}
|
||||
@ -196,9 +219,12 @@ void CUsb3xxxInterface::Task(void)
|
||||
// get packet
|
||||
CAmbePacket *Packet = (CAmbePacket *)Queue->front();
|
||||
Queue->pop();
|
||||
// this is first step of transcoding
|
||||
// a fresh new packet to be transcoded is showing up
|
||||
// post it to relevant channel decoder
|
||||
Packet->SetChannel(Channel->GetChannelIn());
|
||||
m_ChannelQueue.push(Packet);
|
||||
int i = Channel->GetChannelIn();
|
||||
Packet->SetChannel(i);
|
||||
m_ChannelQueues[i]->push(Packet);
|
||||
// done
|
||||
done = false;
|
||||
}
|
||||
@ -207,57 +233,94 @@ void CUsb3xxxInterface::Task(void)
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
// process device incoming queues
|
||||
// process device incoming queues (aka to device)
|
||||
// interlace speech and channels packets
|
||||
// and make sure that the fifo is always
|
||||
// fed.
|
||||
unsigned long iQueueLevel = m_SpeechQueue.size() + m_ChannelQueue.size();
|
||||
if ( ((m_iDeviceFifoLevel == 0) && (iQueueLevel >= 2)) || (m_iDeviceFifoLevel == 1) )
|
||||
// and post to final device queue
|
||||
do
|
||||
{
|
||||
if ( m_iActiveQueue == QUEUE_CHANNEL )
|
||||
done = true;
|
||||
// loop on all channels
|
||||
for ( int i = 0; i < GetNbChannels(); i++ )
|
||||
{
|
||||
// post next channel packet
|
||||
if ( !m_ChannelQueue.empty() )
|
||||
// speech
|
||||
if ( !m_SpeechQueues[i]->empty() )
|
||||
{
|
||||
// get packet
|
||||
CAmbePacket *Packet = (CAmbePacket *)m_ChannelQueue.front();
|
||||
m_ChannelQueue.pop();
|
||||
//Post it
|
||||
EncodeChannelPacket(&Buffer, Packet->GetChannel(), Packet);
|
||||
WriteBuffer(Buffer);
|
||||
m_iDeviceFifoLevel++;
|
||||
// and delete it
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Ch" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
delete Packet;
|
||||
}
|
||||
// and interlace
|
||||
m_iActiveQueue = QUEUE_SPEECH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// post next speech packet
|
||||
if ( !m_SpeechQueue.empty() )
|
||||
{
|
||||
// get packet
|
||||
CVoicePacket *Packet = (CVoicePacket *)m_SpeechQueue.front();
|
||||
m_SpeechQueue.pop();
|
||||
//Post it
|
||||
EncodeSpeechPacket(&Buffer, Packet->GetChannel(), Packet);
|
||||
WriteBuffer(Buffer);
|
||||
m_iDeviceFifoLevel++;
|
||||
// and delete it
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Sp" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
delete Packet;
|
||||
CPacket *Packet = m_SpeechQueues[i]->front();
|
||||
m_SpeechQueues[i]->pop();
|
||||
// and push to device queue
|
||||
m_DeviceQueue.push(Packet);
|
||||
// next
|
||||
done = false;
|
||||
}
|
||||
// ambe
|
||||
if ( !m_ChannelQueues[i]->empty() )
|
||||
{
|
||||
// get packet
|
||||
CPacket *Packet = m_ChannelQueues[i]->front();
|
||||
m_ChannelQueues[i]->pop();
|
||||
// and push to device queue
|
||||
m_DeviceQueue.push(Packet);
|
||||
// done = false;
|
||||
}
|
||||
// and interlace
|
||||
m_iActiveQueue = QUEUE_CHANNEL;
|
||||
}
|
||||
}
|
||||
|
||||
} while (!done);
|
||||
|
||||
// process device queue to feed hardware
|
||||
// make sure that device fifo is fed all the time
|
||||
int fifoSize = GetDeviceFifoSize();
|
||||
do
|
||||
{
|
||||
done = true;
|
||||
// if device fifo level is zero (device idle)
|
||||
// wait that at least 3 packets are in incoming
|
||||
// queue before restarting
|
||||
if ( ((m_iSpeechFifolLevel+m_iChannelFifolLevel) > 0) || (m_DeviceQueue.size() >= (fifoSize+1)) )
|
||||
{
|
||||
// any packet to send ?
|
||||
if ( m_DeviceQueue.size() > 0 )
|
||||
{
|
||||
// yes, get it
|
||||
CPacket *Packet = m_DeviceQueue.front();
|
||||
if ( Packet->IsVoice() && (m_iSpeechFifolLevel < fifoSize) )
|
||||
{
|
||||
// encode & post
|
||||
EncodeSpeechPacket(&Buffer, Packet->GetChannel(), (CVoicePacket *)Packet);
|
||||
WriteBuffer(Buffer);
|
||||
// remove from queue
|
||||
m_DeviceQueue.pop();
|
||||
// and delete it
|
||||
delete Packet;
|
||||
// update fifo level
|
||||
m_iSpeechFifolLevel++;
|
||||
// next
|
||||
done = false;
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Sp" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
}
|
||||
else if ( Packet->IsAmbe() && (m_iChannelFifolLevel < fifoSize) )
|
||||
{
|
||||
// encode & post
|
||||
EncodeChannelPacket(&Buffer, Packet->GetChannel(), (CAmbePacket *)Packet);
|
||||
WriteBuffer(Buffer);
|
||||
// remove from queue
|
||||
m_DeviceQueue.pop();
|
||||
// and delete it
|
||||
delete Packet;
|
||||
// update fifo level
|
||||
m_iChannelFifolLevel++;
|
||||
// next
|
||||
done = false;
|
||||
#ifdef DEBUG_DUMPFILE
|
||||
g_AmbeServer.m_DebugFile << m_szDeviceName << "\t" << "Ch" << Packet->GetChannel() << "->" << std::endl; std::cout.flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
// and wait a bit
|
||||
CTimePoint::TaskSleepFor(2);
|
||||
|
@ -98,12 +98,13 @@ protected:
|
||||
virtual void EncodeSpeechPacket(CBuffer *, int, CVoicePacket *) {}
|
||||
|
||||
// low level
|
||||
virtual bool OpenDevice(void) { return false; }
|
||||
virtual bool ResetDevice(void) { return false; }
|
||||
virtual bool OpenDevice(void) { return false; }
|
||||
virtual bool ResetDevice(void) { return false; }
|
||||
bool ReadDeviceVersion(void);
|
||||
bool DisableParity(void);
|
||||
virtual bool ConfigureDevice(void) { return false; }
|
||||
virtual bool ConfigureDevice(void) { return false; }
|
||||
bool ConfigureChannel(uint8, const uint8 *, int, int);
|
||||
virtual int GetDeviceFifoSize(void) const { return 1; }
|
||||
|
||||
// io level
|
||||
bool ReadBuffer(CBuffer *);
|
||||
@ -117,17 +118,18 @@ protected:
|
||||
|
||||
protected:
|
||||
// data
|
||||
uint32 m_uiVid;
|
||||
uint32 m_uiPid;
|
||||
char m_szDeviceName[FTDI_MAX_STRINGLENGTH];
|
||||
char m_szDeviceSerial[FTDI_MAX_STRINGLENGTH];
|
||||
FT_HANDLE m_FtdiHandle;
|
||||
uint32 m_uiVid;
|
||||
uint32 m_uiPid;
|
||||
char m_szDeviceName[FTDI_MAX_STRINGLENGTH];
|
||||
char m_szDeviceSerial[FTDI_MAX_STRINGLENGTH];
|
||||
FT_HANDLE m_FtdiHandle;
|
||||
|
||||
// queue
|
||||
CPacketQueue m_SpeechQueue;
|
||||
CPacketQueue m_ChannelQueue;
|
||||
int m_iDeviceFifoLevel;
|
||||
int m_iActiveQueue;
|
||||
std::vector<CPacketQueue*> m_SpeechQueues;
|
||||
std::vector<CPacketQueue*> m_ChannelQueues;
|
||||
CPacketQueue m_DeviceQueue;
|
||||
int m_iSpeechFifolLevel;
|
||||
int m_iChannelFifolLevel;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -47,7 +47,10 @@ public:
|
||||
|
||||
// destructor
|
||||
virtual ~CVoicePacket();
|
||||
|
||||
|
||||
// identity
|
||||
bool IsVoice(void) const { return true; }
|
||||
|
||||
// get
|
||||
uint8 *GetVoice(void) { return m_uiVoice; }
|
||||
int GetVoiceSize(void) const { return m_iSize; }
|
||||
|
@ -48,8 +48,8 @@
|
||||
// version -----------------------------------------------------
|
||||
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_REVISION 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 0
|
||||
|
||||
// global ------------------------------------------------------
|
||||
|
||||
|
11
ambed/readme
11
ambed/readme
@ -22,6 +22,7 @@
|
||||
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
VERSION: 1.3.0
|
||||
|
||||
Hardware compatibility.
|
||||
======================
|
||||
@ -37,13 +38,13 @@ This version of ambed is compatible with:
|
||||
Available transcoding channels per device:
|
||||
|
||||
device DMR->DSTAR DSTAR->DMR Nb Of concurrent channels
|
||||
----------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------
|
||||
3000(pair) 1 1 2
|
||||
3003 1 1 1
|
||||
3003(pair) 3 3 not tested
|
||||
3003 1 1 2
|
||||
3003(pair) 3 3 4
|
||||
3003-3000(pair) 2 2 not tested
|
||||
3006 3 3 4
|
||||
3012 6 6 8
|
||||
3006 3 3 6
|
||||
3012 6 6 12
|
||||
|
||||
Multiple devices can be used at the same time.
|
||||
You need to use 3000 by pairs or paired with a 3003
|
||||
|
@ -45,6 +45,7 @@ CCodecStream::CCodecStream(uint16 uiId, uint8 uiCodecIn, uint8 uiCodecOut)
|
||||
m_bConnected = false;
|
||||
m_iAmbeSrcPtr = 0;
|
||||
m_iAmbeDestPtr = 0;
|
||||
m_uiNbTotalPacketSent = 0;
|
||||
m_uiNbPacketSent = 0;
|
||||
m_uiNbPacketReceived = 0;
|
||||
m_uiNbPacketBad = 0;
|
||||
@ -120,6 +121,7 @@ bool CCodecStream::Init(uint16 uiPort)
|
||||
m_pThread = new std::thread(CCodecStream::Thread, this);
|
||||
m_bConnected = true;
|
||||
m_FrameTimer.Now();
|
||||
m_uiNbTotalPacketSent = 0;
|
||||
ResetStats();
|
||||
}
|
||||
else
|
||||
@ -181,11 +183,12 @@ void CCodecStream::Task(void)
|
||||
|
||||
// and increment pointer
|
||||
m_iAmbeSrcPtr = (m_iAmbeSrcPtr + 1) % m_AmbeSrc.size();
|
||||
m_uiNbTotalPacketSent++;
|
||||
m_uiNbPacketSent++;
|
||||
}*/
|
||||
|
||||
// any packt to send to trancoder ?
|
||||
uint32 uiNbPacketToSend = (uint32)(m_FrameTimer.DurationSinceNow() * 50.0) - m_uiNbPacketSent;
|
||||
uint32 uiNbPacketToSend = (uint32)(m_FrameTimer.DurationSinceNow() * 50.0) - m_uiNbTotalPacketSent;
|
||||
if ( uiNbPacketToSend > 0 )
|
||||
{
|
||||
for ( int i = 0; i < uiNbPacketToSend; i++ )
|
||||
@ -196,6 +199,7 @@ void CCodecStream::Task(void)
|
||||
|
||||
// and increment pointer
|
||||
m_iAmbeSrcPtr = (m_iAmbeSrcPtr + 1) % m_AmbeSrc.size();
|
||||
m_uiNbTotalPacketSent++;
|
||||
m_uiNbPacketSent++;
|
||||
}
|
||||
}
|
||||
@ -283,15 +287,19 @@ void CCodecStream::ResetStats(void)
|
||||
|
||||
void CCodecStream::DisplayStats(void)
|
||||
{
|
||||
//double fps = (double)m_uiNbPacketSent / m_StatsTimer.DurationSinceNow();
|
||||
double fps = (double)m_uiNbPacketReceived / m_StatsTimer.DurationSinceNow();
|
||||
// get stats
|
||||
uint32 uiSent = m_uiNbPacketSent;
|
||||
uint32 uiReceived = m_uiNbPacketReceived;
|
||||
uint32 uiBad = m_uiNbPacketBad;
|
||||
double fps = (double)uiReceived / m_StatsTimer.DurationSinceNow();
|
||||
|
||||
std::cout << "Stream " << (int)m_uiStreamId << " (" << (int)m_uiCodecIn << "->" << (int)m_uiCodecOut << ") : ";
|
||||
std::cout << m_uiNbPacketSent << " / " << m_uiNbPacketReceived << " / " << m_uiNbPacketTimeout;
|
||||
//std::cout << " / " << m_uiNbPacketBad;
|
||||
std::cout << " ; " << fps << " fps";
|
||||
// resets
|
||||
ResetStats();
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
m_uiNbPacketBad = 0;
|
||||
// displays
|
||||
char sz[256];
|
||||
sprintf(sz, "Stream %d (%d->%d) : %u / %u / %u : %.1f fps",
|
||||
m_uiStreamId, m_uiCodecIn, m_uiCodecOut,
|
||||
uiSent, uiReceived, uiBad, fps);
|
||||
std::cout << sz << std::endl;
|
||||
}
|
||||
|
@ -99,6 +99,7 @@ protected:
|
||||
std::thread *m_pThread;
|
||||
CTimePoint m_TimeoutTimer;
|
||||
CTimePoint m_FrameTimer;
|
||||
uint32 m_uiNbTotalPacketSent;
|
||||
|
||||
// stats
|
||||
CTimePoint m_StatsTimer;
|
||||
|
@ -8,10 +8,10 @@ EXECUTABLE=ambedtest
|
||||
all: $(SOURCES) $(EXECUTABLE)
|
||||
|
||||
$(EXECUTABLE): $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) -Wl,-rpath,/usr/local/lib -o $@
|
||||
$(CC) $(LDFLAGS) $(OBJECTS) -lftd2xx -Wl,-rpath,/usr/local/lib -o $@
|
||||
|
||||
.cpp.o:
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) $(EXECUTABLE) *.o
|
||||
$(RM) *.o
|
||||
|
Loading…
Reference in New Issue
Block a user