2016-06-19 03:56:49 -04:00
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
# include <QDebug>
# include <cassert>
# include <cstring>
# include <cmath>
# include <lz4.h>
# include "sdrdaemonfecbuffer.h"
const int SDRdaemonFECBuffer : : m_sampleSize = 2 ;
const int SDRdaemonFECBuffer : : m_iqSampleSize = 2 * m_sampleSize ;
SDRdaemonFECBuffer : : SDRdaemonFECBuffer ( uint32_t throttlems ) :
2016-06-19 18:45:24 -04:00
m_frameHead ( 0 ) ,
2016-07-05 18:43:38 -04:00
m_decoderIndexHead ( nbDecoderSlots / 2 ) ,
2016-06-19 18:45:24 -04:00
m_curNbBlocks ( 0 ) ,
m_curNbRecovery ( 0 ) ,
m_throttlemsNominal ( throttlems ) ,
m_readIndex ( 0 ) ,
m_readBuffer ( 0 ) ,
m_readSize ( 0 ) ,
m_bufferLenSec ( 0.0f )
2016-06-19 03:56:49 -04:00
{
m_currentMeta . init ( ) ;
2016-06-21 15:49:27 -04:00
m_framesNbBytes = nbDecoderSlots * sizeof ( BufferFrame ) ;
2016-06-19 18:45:24 -04:00
m_wrDeltaEstimate = m_framesNbBytes / 2 ;
2016-06-22 19:31:40 -04:00
m_paramsCM256 . BlockBytes = sizeof ( ProtectedBlock ) ; // never changes
m_paramsCM256 . OriginalCount = m_nbOriginalBlocks ; // never changes
2016-06-19 03:56:49 -04:00
}
SDRdaemonFECBuffer : : ~ SDRdaemonFECBuffer ( )
{
if ( m_readBuffer ) {
delete [ ] m_readBuffer ;
}
}
2016-06-19 18:45:24 -04:00
void SDRdaemonFECBuffer : : initDecodeAllSlots ( )
2016-06-19 03:56:49 -04:00
{
2016-06-19 18:45:24 -04:00
for ( int i = 0 ; i < nbDecoderSlots ; i + + )
{
m_decoderSlots [ i ] . m_blockCount = 0 ;
m_decoderSlots [ i ] . m_recoveryCount = 0 ;
m_decoderSlots [ i ] . m_decoded = false ;
2016-06-22 18:58:07 -04:00
m_decoderSlots [ i ] . m_metaRetrieved = false ;
2016-07-06 20:54:23 -04:00
MetaDataFEC * metaData = ( MetaDataFEC * ) & m_decoderSlots [ i ] . m_blockZero ;
metaData - > init ( ) ;
2016-06-19 18:45:24 -04:00
}
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
void SDRdaemonFECBuffer : : initReadIndex ( )
2016-06-19 03:56:49 -04:00
{
2016-07-05 18:43:38 -04:00
m_readIndex = ( ( m_decoderIndexHead + ( nbDecoderSlots / 2 ) ) % nbDecoderSlots ) * sizeof ( BufferFrame ) ;
2016-06-19 18:45:24 -04:00
m_wrDeltaEstimate = m_framesNbBytes / 2 ;
2016-06-19 03:56:49 -04:00
}
2016-07-05 20:54:01 -04:00
void SDRdaemonFECBuffer : : checkSlotData ( int slotIndex )
{
if ( ! m_decoderSlots [ slotIndex ] . m_decoded )
{
qDebug ( ) < < " SDRdaemonFECBuffer::checkSlotData: incomplete frame: "
< < " m_blockCount: " < < m_decoderSlots [ slotIndex ] . m_blockCount
< < " m_recoveryCount: " < < m_decoderSlots [ slotIndex ] . m_recoveryCount ;
}
2016-07-06 20:36:44 -04:00
if ( m_decoderSlots [ slotIndex ] . m_metaRetrieved ) // meta data has been retrieved (direct or recovery)
{
2016-07-06 20:54:23 -04:00
MetaDataFEC * metaData = ( MetaDataFEC * ) & m_decoderSlots [ slotIndex ] . m_blockZero ;
if ( ! ( * metaData = = m_currentMeta ) )
2016-07-06 20:36:44 -04:00
{
2016-07-06 20:54:23 -04:00
int sampleRate = metaData - > m_sampleRate ;
2016-07-06 20:36:44 -04:00
if ( sampleRate > 0 ) {
m_bufferLenSec = ( float ) m_framesNbBytes / ( float ) sampleRate ;
}
2016-07-06 20:54:23 -04:00
printMeta ( " SDRdaemonFECBuffer::checkSlotData: new meta " , metaData ) ; // print for change other than timestamp
2016-07-06 20:36:44 -04:00
}
2016-07-06 20:54:23 -04:00
m_currentMeta = * metaData ; // renew current meta
2016-07-06 20:36:44 -04:00
}
2016-07-05 20:54:01 -04:00
}
2016-06-19 18:45:24 -04:00
void SDRdaemonFECBuffer : : initDecodeSlot ( int slotIndex )
2016-06-19 03:56:49 -04:00
{
2016-06-19 18:45:24 -04:00
int pseudoWriteIndex = slotIndex * sizeof ( BufferFrame ) ;
m_wrDeltaEstimate = pseudoWriteIndex - m_readIndex ;
2016-06-21 02:30:32 -04:00
2016-06-19 18:45:24 -04:00
// collect stats before voiding the slot
m_curNbBlocks = m_decoderSlots [ slotIndex ] . m_blockCount ;
m_curNbRecovery = m_decoderSlots [ slotIndex ] . m_recoveryCount ;
m_avgNbBlocks ( m_curNbBlocks ) ;
m_avgNbRecovery ( m_curNbRecovery ) ;
// void the slot
m_decoderSlots [ slotIndex ] . m_blockCount = 0 ;
m_decoderSlots [ slotIndex ] . m_recoveryCount = 0 ;
m_decoderSlots [ slotIndex ] . m_decoded = false ;
2016-06-22 18:58:07 -04:00
m_decoderSlots [ slotIndex ] . m_metaRetrieved = false ;
2016-07-06 20:54:23 -04:00
MetaDataFEC * metaData = ( MetaDataFEC * ) & m_decoderSlots [ slotIndex ] . m_blockZero ;
metaData - > init ( ) ;
2016-07-06 20:36:44 -04:00
memset ( ( void * ) m_frames [ slotIndex ] . m_blocks , 0 , ( m_nbOriginalBlocks - 1 ) * sizeof ( ProtectedBlock ) ) ;
memset ( ( void * ) m_decoderSlots [ slotIndex ] . m_recoveryBlocks , 1 , m_nbOriginalBlocks * sizeof ( ProtectedBlock ) ) ;
2016-06-19 18:45:24 -04:00
}
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
void SDRdaemonFECBuffer : : writeData ( char * array , uint32_t length )
{
2016-06-19 19:32:32 -04:00
assert ( length = = m_udpPayloadSize ) ;
2016-06-19 03:56:49 -04:00
2016-07-06 20:36:44 -04:00
SuperBlock * superBlock = ( SuperBlock * ) array ;
int frameIndex = superBlock - > header . frameIndex ;
int decoderIndex = frameIndex % nbDecoderSlots ;
if ( m_frameHead = = - 1 ) // initial state
{
m_decoderIndexHead = decoderIndex ; // new decoder slot head
m_frameHead = frameIndex ;
initReadIndex ( ) ; // reset read index
initDecodeAllSlots ( ) ; // initialize all slots
}
else if ( m_frameHead ! = frameIndex ) // frame break => new frame starts
{
m_decoderIndexHead = decoderIndex ; // new decoder slot head
m_frameHead = frameIndex ; // new frame head
checkSlotData ( decoderIndex ) ; // check slot before re-init
initDecodeSlot ( decoderIndex ) ; // collect stats and re-initialize current slot
}
int blockCount = m_decoderSlots [ decoderIndex ] . m_blockCount ;
int recoveryCount = m_decoderSlots [ decoderIndex ] . m_recoveryCount ;
int nbOriginalBlocks = 0 ;
if ( blockCount < m_nbOriginalBlocks ) // not enough blocks to decode -> store data
{
int blockIndex = superBlock - > header . blockIndex ;
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockCount ] . Index = blockIndex ;
if ( blockIndex = = 0 ) // first block with meta
{
//qDebug() << "SDRdaemonFECBuffer::writeData(0): frameIndex: " << frameIndex << " blockIndex: " << blockIndex;
2016-07-06 20:54:23 -04:00
m_decoderSlots [ decoderIndex ] . m_blockZero = superBlock - > protectedBlock ;
2016-07-06 20:36:44 -04:00
m_decoderSlots [ decoderIndex ] . m_metaRetrieved = true ;
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockCount ] . Block = ( void * ) & m_decoderSlots [ decoderIndex ] . m_blockZero ;
}
else if ( blockIndex < m_nbOriginalBlocks ) // original data
{
//qDebug() << "SDRdaemonFECBuffer::writeData(<128): frameIndex: " << frameIndex << " blockIndex: " << blockIndex;
m_frames [ decoderIndex ] . m_blocks [ blockIndex - 1 ] = superBlock - > protectedBlock ;
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockCount ] . Block = ( void * ) & m_frames [ decoderIndex ] . m_blocks [ blockIndex - 1 ] ;
}
else // recovery data
{
qDebug ( ) < < " SDRdaemonFECBuffer::writeData(>=128): frameIndex: " < < frameIndex < < " blockIndex: " < < blockIndex ;
if ( recoveryCount = = 0 )
{
nbOriginalBlocks = blockCount ;
}
m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ recoveryCount ] = superBlock - > protectedBlock ;
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockCount ] . Block = ( void * ) & m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ recoveryCount ] ;
m_decoderSlots [ decoderIndex ] . m_recoveryCount + + ;
}
}
else if ( ! m_decoderSlots [ decoderIndex ] . m_decoded ) // ready to decode and not decoded yet
{
if ( m_decoderSlots [ decoderIndex ] . m_recoveryCount > 0 ) // recovery data used => need to decode FEC
{
if ( m_decoderSlots [ decoderIndex ] . m_metaRetrieved ) // block zero with its meta data has been received
{
2016-07-06 20:54:23 -04:00
MetaDataFEC * metaData = ( MetaDataFEC * ) & m_decoderSlots [ decoderIndex ] . m_blockZero ;
m_paramsCM256 . RecoveryCount = metaData - > m_nbFECBlocks ;
2016-07-06 20:36:44 -04:00
}
else
{
m_paramsCM256 . RecoveryCount = m_currentMeta . m_nbFECBlocks ; // take last stored value for number of FEC blocks
}
if ( cm256_decode ( m_paramsCM256 , m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks ) ) // failure to decode
{
qDebug ( ) < < " SDRdaemonFECBuffer::writeData: CM256 decode error: "
< < " BlockBytes: " < < m_paramsCM256 . BlockBytes
< < " OriginalCount: " < < m_paramsCM256 . OriginalCount
< < " RecoveryCount: " < < m_paramsCM256 . RecoveryCount
< < " m_recoveryCount: " < < m_decoderSlots [ decoderIndex ] . m_recoveryCount ;
}
else // success to decode
{
qDebug ( ) < < " SDRdaemonFECBuffer::writeData: CM256 decode success: "
< < " nbOriginalBlocks: " < < nbOriginalBlocks
< < " m_recoveryCount: " < < m_decoderSlots [ decoderIndex ] . m_recoveryCount ;
for ( int ir = 0 ; ir < m_decoderSlots [ decoderIndex ] . m_recoveryCount ; ir + + ) // recover lost blocks
{
int blockIndex = m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ nbOriginalBlocks + ir ] . Index ;
if ( blockIndex > 0 ) // ignore meta data for now
{
m_frames [ decoderIndex ] . m_blocks [ blockIndex - 1 ] = m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] ;
}
qDebug ( ) < < " SDRdaemonFECBuffer::writeData: "
< < " recovered block # " < < blockIndex
< < " i[0]: " < < m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 0 ] . i
< < " q[0]: " < < m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 0 ] . q ;
}
}
}
m_decoderSlots [ decoderIndex ] . m_decoded = true ;
}
m_decoderSlots [ decoderIndex ] . m_blockCount + + ;
}
void SDRdaemonFECBuffer : : writeData0 ( char * array , uint32_t length )
{
assert ( length = = m_udpPayloadSize ) ;
2016-06-19 18:45:24 -04:00
bool dataAvailable = false ;
SuperBlock * superBlock = ( SuperBlock * ) array ;
int frameIndex = superBlock - > header . frameIndex ;
int decoderIndex = frameIndex % nbDecoderSlots ;
2016-07-05 18:43:38 -04:00
int blockIndex = superBlock - > header . blockIndex ;
// qDebug() << "SDRdaemonFECBuffer::writeData:"
// << " frameIndex: " << frameIndex
// << " decoderIndex: " << decoderIndex
// << " blockIndex: " << blockIndex;
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
if ( m_frameHead = = - 1 ) // initial state
{
2016-07-05 18:43:38 -04:00
m_decoderIndexHead = decoderIndex ; // new decoder slot head
2016-06-19 18:45:24 -04:00
m_frameHead = frameIndex ;
initReadIndex ( ) ; // reset read index
initDecodeAllSlots ( ) ; // initialize all slots
}
else
{
int frameDelta = m_frameHead - frameIndex ;
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
if ( frameDelta < 0 )
{
if ( - frameDelta < nbDecoderSlots ) // new frame head not too new
2016-06-19 03:56:49 -04:00
{
2016-07-05 13:59:18 -04:00
//qDebug() << "SDRdaemonFECBuffer::writeData: new frame head (1): " << frameIndex << ":" << frameDelta << ":" << decoderIndex;
2016-07-05 18:43:38 -04:00
m_decoderIndexHead = decoderIndex ; // new decoder slot head
2016-06-19 18:45:24 -04:00
m_frameHead = frameIndex ;
2016-07-05 20:54:01 -04:00
checkSlotData ( decoderIndex ) ;
2016-06-19 18:45:24 -04:00
dataAvailable = true ;
initDecodeSlot ( decoderIndex ) ; // collect stats and re-initialize current slot
2016-06-19 03:56:49 -04:00
}
2016-07-05 13:59:18 -04:00
else if ( - frameDelta < = 65536 - nbDecoderSlots ) // loss of sync start over
2016-06-19 03:56:49 -04:00
{
2016-07-05 13:59:18 -04:00
//qDebug() << "SDRdaemonFECBuffer::writeData: loss of sync start over (1)" << frameIndex << ":" << frameDelta << ":" << decoderIndex;
2016-07-05 18:43:38 -04:00
m_decoderIndexHead = decoderIndex ; // new decoder slot head
2016-06-19 18:45:24 -04:00
m_frameHead = frameIndex ;
initReadIndex ( ) ; // reset read index
initDecodeAllSlots ( ) ; // re-initialize all slots
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
}
else
{
2016-07-05 13:59:18 -04:00
if ( frameDelta > 65536 - nbDecoderSlots ) // new frame head not too new
2016-06-19 03:56:49 -04:00
{
2016-07-05 13:59:18 -04:00
//qDebug() << "SDRdaemonFECBuffer::writeData: new frame head (2): " << frameIndex << ":" << frameDelta << ":" << decoderIndex;
2016-07-05 18:43:38 -04:00
m_decoderIndexHead = decoderIndex ; // new decoder slot head
2016-06-19 18:45:24 -04:00
m_frameHead = frameIndex ;
2016-07-05 20:54:01 -04:00
checkSlotData ( decoderIndex ) ;
2016-06-19 18:45:24 -04:00
dataAvailable = true ;
initDecodeSlot ( decoderIndex ) ; // collect stats and re-initialize current slot
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
else if ( frameDelta > = nbDecoderSlots ) // loss of sync start over
{
2016-07-05 13:59:18 -04:00
//qDebug() << "SDRdaemonFECBuffer::writeData: loss of sync start over (2)" << frameIndex << ":" << frameDelta << ":" << decoderIndex;
2016-07-05 18:43:38 -04:00
m_decoderIndexHead = decoderIndex ; // new decoder slot head
2016-06-19 18:45:24 -04:00
m_frameHead = frameIndex ;
initReadIndex ( ) ; // reset read index
initDecodeAllSlots ( ) ; // re-initialize all slots
}
}
}
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
// decoderIndex should now be correctly set
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
int blockHead = m_decoderSlots [ decoderIndex ] . m_blockCount ;
2016-07-05 20:54:01 -04:00
int recoveryHead = m_decoderSlots [ decoderIndex ] . m_recoveryCount ;
2016-06-19 03:56:49 -04:00
2016-06-19 19:32:32 -04:00
if ( blockHead < m_nbOriginalBlocks ) // not enough blocks to decode -> store data
2016-06-19 03:56:49 -04:00
{
2016-06-19 18:45:24 -04:00
if ( blockIndex = = 0 ) // first block with meta
2016-06-19 03:56:49 -04:00
{
2016-07-06 20:54:23 -04:00
// ProtectedBlockZero *blockZero = (ProtectedBlockZero *) &superBlock->protectedBlock;
// m_decoderSlots[decoderIndex].m_blockZero = *blockZero;
2016-06-19 18:45:24 -04:00
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockHead ] . Block = ( void * ) & m_decoderSlots [ decoderIndex ] . m_blockZero ;
2016-07-05 18:43:38 -04:00
m_decoderSlots [ decoderIndex ] . m_metaRetrieved = true ;
2016-06-19 03:56:49 -04:00
}
2016-06-19 19:32:32 -04:00
else if ( blockIndex < m_nbOriginalBlocks ) // normal block
2016-06-19 18:45:24 -04:00
{
m_frames [ decoderIndex ] . m_blocks [ blockIndex - 1 ] = superBlock - > protectedBlock ;
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockHead ] . Block = ( void * ) & m_frames [ decoderIndex ] . m_blocks [ blockIndex - 1 ] ;
}
else // redundancy block
2016-06-19 03:56:49 -04:00
{
2016-07-05 20:54:01 -04:00
m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ recoveryHead ] = superBlock - > protectedBlock ;
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockHead ] . Block = ( void * ) & m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ recoveryHead ] ;
2016-06-19 18:45:24 -04:00
m_decoderSlots [ decoderIndex ] . m_recoveryCount + + ;
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockHead ] . Index = blockIndex ;
m_decoderSlots [ decoderIndex ] . m_blockCount + + ;
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
else if ( ! m_decoderSlots [ decoderIndex ] . m_decoded ) // ready to decode
{
if ( m_decoderSlots [ decoderIndex ] . m_recoveryCount > 0 ) // recovery data used
{
2016-06-22 19:31:40 -04:00
if ( m_decoderSlots [ decoderIndex ] . m_metaRetrieved ) // block zero with its meta data has been received
{
2016-07-06 20:54:23 -04:00
// m_paramsCM256.RecoveryCount = m_decoderSlots[decoderIndex].m_blockZero.m_metaData.m_nbFECBlocks;
2016-06-22 19:31:40 -04:00
}
else
{
m_paramsCM256 . RecoveryCount = m_currentMeta . m_nbFECBlocks ; // take last stored value for number of FEC blocks
}
2016-06-19 18:45:24 -04:00
if ( cm256_decode ( m_paramsCM256 , m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks ) ) // failure to decode
{
2016-06-22 19:31:40 -04:00
qDebug ( ) < < " SDRdaemonFECBuffer::writeData: CM256 decode error: "
< < " BlockBytes: " < < m_paramsCM256 . BlockBytes
< < " OriginalCount: " < < m_paramsCM256 . OriginalCount
< < " RecoveryCount: " < < m_paramsCM256 . RecoveryCount
< < " m_recoveryCount: " < < m_decoderSlots [ decoderIndex ] . m_recoveryCount ;
2016-06-19 18:45:24 -04:00
}
else // success to decode
{
int nbOriginalBlocks = m_decoderSlots [ decoderIndex ] . m_blockCount - m_decoderSlots [ decoderIndex ] . m_recoveryCount ;
2016-06-22 19:31:40 -04:00
qDebug ( ) < < " SDRdaemonFECBuffer::writeData: CM256 decode success: "
2016-06-21 02:30:32 -04:00
< < " nbOriginalBlocks: " < < nbOriginalBlocks
< < " m_recoveryCount: " < < m_decoderSlots [ decoderIndex ] . m_recoveryCount ;
2016-06-19 18:45:24 -04:00
for ( int ir = 0 ; ir < m_decoderSlots [ decoderIndex ] . m_recoveryCount ; ir + + ) // recover lost blocks
{
int blockIndex = m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ nbOriginalBlocks + ir ] . Index ;
if ( blockIndex = = 0 )
{
2016-07-06 20:54:23 -04:00
// ProtectedBlockZero *recoveredBlockZero = (ProtectedBlockZero *) &m_decoderSlots[decoderIndex].m_recoveryBlocks[ir];
// printMeta("SDRdaemonFECBuffer::writeData: recovered meta", &recoveredBlockZero->m_metaData);
2016-07-05 20:54:01 -04:00
// FEC does not work
// m_decoderSlots[decoderIndex].m_blockZero.m_metaData = recoveredBlockZero->m_metaData;
// m_decoderSlots[decoderIndex].m_metaRetrieved = true;
2016-06-19 18:45:24 -04:00
}
else
{
m_frames [ decoderIndex ] . m_blocks [ blockIndex - 1 ] = m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] ;
}
2016-07-06 20:36:44 -04:00
qDebug ( ) < < " SDRdaemonFECBuffer::writeData: "
< < " recovered block # " < < blockIndex
< < " i[0]: " < < m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 0 ] . i
< < " q[0]: " < < m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 0 ] . q ;
2016-06-19 18:45:24 -04:00
}
}
}
2016-06-19 03:56:49 -04:00
2016-06-21 02:30:32 -04:00
//printMeta("SDRdaemonFECBuffer::writeData", &m_decoderSlots[decoderIndex].m_blockZero.m_metaData);
2016-07-06 20:54:23 -04:00
// if (m_decoderSlots[decoderIndex].m_metaRetrieved) // meta data has been retrieved (direct or recovery)
// {
// if (!(m_decoderSlots[decoderIndex].m_blockZero.m_metaData == m_currentMeta))
// {
// int sampleRate = m_decoderSlots[decoderIndex].m_blockZero.m_metaData.m_sampleRate;
//
// if (sampleRate > 0) {
// m_bufferLenSec = (float) m_framesNbBytes / (float) sampleRate;
// }
//
// printMeta("SDRdaemonFECBuffer::writeData: new meta", &m_decoderSlots[decoderIndex].m_blockZero.m_metaData); // print for change other than timestamp
// }
//
// m_currentMeta = m_decoderSlots[decoderIndex].m_blockZero.m_metaData; // renew current meta
// }
//
2016-06-19 18:45:24 -04:00
m_decoderSlots [ decoderIndex ] . m_decoded = true ;
2016-06-19 03:56:49 -04:00
}
}
2016-06-19 18:45:24 -04:00
uint8_t * SDRdaemonFECBuffer : : readData ( int32_t length )
2016-06-19 03:56:49 -04:00
{
2016-06-19 18:45:24 -04:00
uint8_t * buffer = ( uint8_t * ) m_frames ;
uint32_t readIndex = m_readIndex ;
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
if ( m_readIndex + length < m_framesNbBytes ) // ends before buffer bound
2016-06-19 03:56:49 -04:00
{
2016-06-19 18:45:24 -04:00
m_readIndex + = length ;
return & buffer [ readIndex ] ;
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
else if ( m_readIndex + length = = m_framesNbBytes ) // ends at buffer bound
2016-06-19 03:56:49 -04:00
{
2016-06-19 18:45:24 -04:00
m_readIndex = 0 ;
return & buffer [ readIndex ] ;
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
else // ends after buffer bound
{
if ( length > m_readSize ) // reallocate composition buffer if necessary
{
if ( m_readBuffer ) {
delete [ ] m_readBuffer ;
}
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
m_readBuffer = new uint8_t [ length ] ;
m_readSize = length ;
}
2016-06-19 03:56:49 -04:00
2016-06-19 18:45:24 -04:00
std : : memcpy ( ( void * ) m_readBuffer , ( const void * ) & buffer [ m_readIndex ] , m_framesNbBytes - m_readIndex ) ; // copy end of buffer
length - = m_framesNbBytes - m_readIndex ;
std : : memcpy ( ( void * ) & m_readBuffer [ m_framesNbBytes - m_readIndex ] , ( const void * ) buffer , length ) ; // copy start of buffer
m_readIndex = length ;
return m_readBuffer ;
}
2016-06-19 03:56:49 -04:00
}
2016-06-19 18:45:24 -04:00
void SDRdaemonFECBuffer : : printMeta ( const QString & header , MetaDataFEC * metaData )
2016-06-19 03:56:49 -04:00
{
qDebug ( ) < < header < < " : "
2016-06-19 18:45:24 -04:00
< < " | " < < metaData - > m_centerFrequency
< < " : " < < metaData - > m_sampleRate
< < " : " < < ( int ) ( metaData - > m_sampleBytes & 0xF )
< < " : " < < ( int ) metaData - > m_sampleBits
< < " : " < < ( int ) metaData - > m_nbOriginalBlocks
< < " : " < < ( int ) metaData - > m_nbFECBlocks
< < " | " < < metaData - > m_tv_sec
< < " : " < < metaData - > m_tv_usec
< < " | " ;
2016-06-19 03:56:49 -04:00
}