Fix IQ recorder/player for nrUE
This commit is contained in:
@@ -110,7 +110,10 @@ int load_lib(openair0_device *device,
|
||||
|
||||
openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state));
|
||||
|
||||
if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) {
|
||||
if (openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) {
|
||||
set_softmodem_optmask(SOFTMODEM_RECRECORD_BIT); // softmodem has to know we use the iqrecorder to workaround randomized algorithms
|
||||
}
|
||||
if (openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE) {
|
||||
deflibname=OAI_IQPLAYER_LIBNAME;
|
||||
shlib_fdesc[0].fname="device_init";
|
||||
set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms
|
||||
|
||||
@@ -40,13 +40,11 @@
|
||||
* recplay_state: store recorder or player data while the device runs
|
||||
*/
|
||||
int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {
|
||||
unsigned int u_sf_record = 0; // record mode
|
||||
unsigned int u_sf_replay = 0; // replay mode
|
||||
*recplay_conf = calloc(sizeof(recplay_conf_t),1);
|
||||
paramdef_t device_recplay_params[]=DEVICE_RECPLAY_PARAMS_DESC ;
|
||||
config_get(device_recplay_params,sizeof(device_recplay_params)/sizeof(paramdef_t),DEVICE_RECPLAY_SECTION);
|
||||
|
||||
if (u_sf_record || u_sf_replay ) {
|
||||
if ((*recplay_conf)->u_sf_record || (*recplay_conf)->u_sf_replay ) {
|
||||
struct sysinfo systeminfo;
|
||||
*recplay_state = calloc(sizeof(recplay_state_t),1);
|
||||
|
||||
@@ -62,17 +60,18 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
|
||||
LOG_W(HW,"System with %f GB of mem (<6GB), mmap usage disabled\n",systeminfo.totalram/10E9);
|
||||
(*recplay_conf)->use_mmap = 0;
|
||||
}
|
||||
} else { /* record player enabled */
|
||||
} else { /* player-recorder disable */
|
||||
free(*recplay_conf);
|
||||
*recplay_conf=NULL;
|
||||
return RECPLAY_DISABLED;
|
||||
}
|
||||
|
||||
if (u_sf_replay == 1)
|
||||
if ((*recplay_conf)->u_sf_replay == 1)
|
||||
return RECPLAY_REPLAYMODE;
|
||||
else if (u_sf_record == 1)
|
||||
else if ((*recplay_conf)->u_sf_record == 1)
|
||||
return RECPLAY_RECORDMODE;
|
||||
|
||||
return 0;
|
||||
return RECPLAY_DISABLED;
|
||||
}
|
||||
|
||||
/*! \brief Terminate operation of the oai iq recorder. to be called by any device
|
||||
@@ -81,21 +80,15 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
|
||||
*/
|
||||
void iqrecorder_end(openair0_device *device) {
|
||||
if (device->recplay_state != NULL) { // subframes store
|
||||
iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID};
|
||||
iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID};
|
||||
recplay_state_t *rs = device->recplay_state;
|
||||
recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf;
|
||||
recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf;
|
||||
rs->pFile = fopen (rc->u_sf_filename,"wb+");
|
||||
|
||||
if (rs->pFile == NULL) {
|
||||
LOG_E(HW,"Cannot open %s\n", rc->u_sf_filename);
|
||||
} else {
|
||||
unsigned int i = 0;
|
||||
unsigned int modu = 0;
|
||||
|
||||
if ((modu = rs->nbSamplesBlocks % 10) != 0) {
|
||||
rs->nbSamplesBlocks -= modu; // store entire number of frames
|
||||
}
|
||||
|
||||
fh.nbSamplesBlocks=rs->nbSamplesBlocks;
|
||||
LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename );
|
||||
fwrite(&fh, sizeof(fh), 1, rs->pFile);
|
||||
@@ -103,7 +96,7 @@ void iqrecorder_end(openair0_device *device) {
|
||||
uint8_t *ptr=(uint8_t *)rs->ms_sample;
|
||||
|
||||
for (i = 0; i < rs->nbSamplesBlocks; i++) {
|
||||
int blockBytes=sizeof(iqrec_t)+((iqrec_t *)ptr)->nbBytes;
|
||||
int blockBytes=sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF;
|
||||
fwrite(ptr, sizeof(unsigned char), blockBytes, rs->pFile);
|
||||
ptr+=blockBytes;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,8 @@ extern "C"
|
||||
#define RECPLAY_REPLAYMODE 2
|
||||
|
||||
#define BELL_LABS_IQ_HEADER 0xabababababababab
|
||||
#define BELL_LABS_IQ_PER_SF 46080 // 7680 => 5MHz bw for now; 46080 => 3/4 40MHz (106 PRBs)
|
||||
#define BELL_LABS_IQ_PER_SF 23040 // 23040 => 46080/2 slots => 3/4 40MHz (106 PRBs)
|
||||
#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
|
||||
#define MAX_BELL_LABS_IQ_BYTES_PER_SF BELL_LABS_IQ_BYTES_PER_SF*10
|
||||
|
||||
#define OAIIQFILE_ID {'O', 'I','Q','F'}
|
||||
typedef struct {
|
||||
@@ -61,7 +60,9 @@ typedef struct {
|
||||
int64_t header;
|
||||
int64_t ts;
|
||||
int64_t nbBytes;
|
||||
int64_t rfu2; // pad for 256 bits alignement required by AVX2
|
||||
int64_t tv_sec; // nb of secs since EPOCH
|
||||
int64_t tv_usec; // nb of µsecs since EPOCH
|
||||
int64_t rfu2; // pad for 256 bits alignement required by AVX2
|
||||
} iqrec_t;
|
||||
#define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz)
|
||||
#define DEF_SF_FILE "/tmp/iqfile" // default subframes file name
|
||||
@@ -95,29 +96,31 @@ typedef struct {
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define DEVICE_RECPLAY_PARAMS_DESC { \
|
||||
{CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:&((*recplay_conf)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 0}, \
|
||||
{CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&(u_sf_record), defuintval:0, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&(u_sf_replay), defuintval:0, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_conf)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_USE_MMAP, CONFIG_HLP_USE_MMAP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->use_mmap), defuintval:1, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:&((*recplay_conf)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 0}, \
|
||||
{CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->u_sf_record), defuintval:0, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->u_sf_replay), defuintval:0, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_conf)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \
|
||||
{CONFIG_OPT_USE_MMAP, CONFIG_HLP_USE_MMAP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->use_mmap), defuintval:1, TYPE_UINT, 0}, \
|
||||
}/*! \brief Record Player Configuration and state */
|
||||
typedef struct {
|
||||
char *u_sf_filename; // subframes file path
|
||||
unsigned int u_sf_max ; // max number of recorded subframes
|
||||
unsigned int u_sf_loops ; // number of loops in replay mode
|
||||
char *u_sf_filename; // subframes file path
|
||||
unsigned int u_sf_max ; // max number of recorded subframes
|
||||
unsigned int u_sf_loops ; // number of loops in replay mode
|
||||
unsigned int u_sf_read_delay; // read delay in replay mode
|
||||
unsigned int u_sf_write_delay ; // write delay in replay mode
|
||||
unsigned int use_mmap; // default is to use mmap
|
||||
unsigned int use_mmap; // default is to use mmap
|
||||
unsigned int u_sf_replay; // replay mode (if 1)
|
||||
unsigned int u_sf_record; // record mode (if 1)
|
||||
} recplay_conf_t;
|
||||
|
||||
typedef struct {
|
||||
size_t mapsize;
|
||||
FILE *pFile;
|
||||
int fd;
|
||||
iqrec_t *ms_sample; // memory for all subframes
|
||||
iqrec_t *ms_sample; // memory for all subframes
|
||||
unsigned int nbSamplesBlocks;
|
||||
uint8_t *currentPtr;
|
||||
uint64_t currentTs;
|
||||
|
||||
Reference in New Issue
Block a user