1
0
mirror of https://github.com/DigitalDevices/dddvb.git synced 2023-10-10 13:37:43 +02:00

add --pam (-a) option for IQ data output in pam format to stdout.

Needs a number >0 as argument.
This commit is contained in:
drmocm 2020-10-10 17:32:56 +02:00
parent 7f19a0c04b
commit 97a88de738
2 changed files with 198 additions and 7 deletions

View File

@ -13,10 +13,10 @@ install: all
$(CC) $(CFLAGS) -fPIC -c $<
dddvb_test: dddvb_test.o
$(CC) -o dddvb_test $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi
$(CC) -o dddvb_test $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi
ddzap: ddzap.o
$(CC) -o ddzap $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi
$(CC) -o ddzap $< -L ./src -l dddvb -l pthread -l dvben50221 -l dvbapi -l ucsi -lm
clean:
make -C ./src clean

View File

@ -10,6 +10,8 @@
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <time.h>
char line_start[16] = "";
char line_end[16] = "\r";
@ -22,6 +24,175 @@ uint32_t packet_errors = 0;
uint8_t cc[8192] = { 0 };
enum { IQ_RED=1, IQ_GREE, IQ_BLUE , IQ_EVIL, IQ_LOG_RED, IQ_LOG_GREEN, IQ_LOG_BLUE , IQ_LOG_EVIL , IQ_TEST, };
typedef struct pamdata_
{
unsigned char *data_points;
uint64_t *data;
int col;
} pamdata;
int init_pamdata(pamdata *iq,int color)
{
iq->col = 0;
if (!( iq->data=(uint64_t *) malloc(sizeof(uint64_t) *256*256)))
{
fprintf(stderr,"not enough memory\n");
return -1;
}
memset(iq->data,0,256*256*sizeof(uint64_t));
if (!( iq->data_points=(unsigned char *) malloc(sizeof(unsigned char) *
256*256*3)))
{
fprintf(stderr,"not enough memory\n");
return -1;
}
memset(iq->data_points,0,256*256*3*sizeof(char));
iq->col = color;
return 0;
}
static long getutime(){
struct timespec t0;
clock_gettime(CLOCK_MONOTONIC_RAW,&t0);
return t0.tv_sec * (int)1e9 + t0.tv_nsec;
}
void pam_coordinate_axes(pamdata *iq, unsigned char r,
unsigned char g, unsigned char b){
int i;
for (i = 0; i < 256*3; i+=3){
// coordinate axes
int xr = i + 256*128*3;
int yr =128*3 + i*256;
iq->data_points[xr] = r;
iq->data_points[yr] = r;
iq->data_points[xr+1] = g;
iq->data_points[yr+1] = g;
iq->data_points[xr+2] = b;
iq->data_points[yr+2] = b;
}
}
void pam_data_convert(pamdata *iq ,uint64_t maxd)
{
int i;
uint64_t m = 255*maxd;
double lm = log((double)m);
memset(iq->data_points,0,256*256*3*sizeof(char));
for (i = 0; i < 256*256*3; i+=3){
// IQ data plot
int r = i;
int g = i+1;
int b = i+2;
uint64_t odata = iq->data[i/3];
uint64_t data = 255*iq->data[i/3];
double lod = log((double)odata);
double q = lod/lm;
if (data){
switch (iq->col){
case IQ_LOG_EVIL:
if ( q < 0.25){
iq->data_points[b] = (int)(1024.0*q);
} else {
if (q >0.5) iq->data_points[g] = (int)(255.0*q);
else
iq->data_points[r] = (int)(512.0*q);
}
break;
case IQ_LOG_RED:
iq->data_points[r] = (int)(255.0*q)&0xff;
break;
case IQ_LOG_GREEN:
iq->data_points[g] = (int)(255.0*q)&0xff;
break;
case IQ_LOG_BLUE:
iq->data_points[b] = (int)(255.0*q)&0xff;
break;
case IQ_EVIL:
if (data < m/4){
iq->data_points[b] = ((4*data)/maxd)&0xff;
} else {
if (data >m/2) iq->data_points[g] = (data/maxd)&0xff;
else iq->data_points[r] = (2*data/maxd)&0xff;
}
break;
case IQ_TEST:
if (data < m/4){
iq->data_points[b] = ((4*data)/maxd)&0xff;
iq->data_points[g] = ((4*data)/maxd)&0xff;
} else {
if (data >m/2) {
iq->data_points[g] = (data/maxd)&0xff;
} else {
iq->data_points[g] = (2*data/maxd)&0xff;
iq->data_points[r] = (2*data/maxd)&0xff;
}
}
break;
case IQ_RED:
iq->data_points[r] = (data/maxd)&0xff;
break;
case IQ_BLUE:
iq->data_points[b] = (data/maxd)&0xff;
break;
default:
case IQ_GREE:
iq->data_points[g] = (data/maxd)&0xff;
break;
}
}
}
}
#define TS_SIZE 188
#define BSIZE 100*TS_SIZE
#define DTIME 40000000ULL
void pam_read_data (int fdin, pamdata *iq)
{
int8_t buf[BSIZE];
int i,j;
long t0;
long t1;
uint64_t maxd = 0;
t0 = getutime();
t1 = t0;
while ((t1 - t0) < DTIME){
int re =0;
if ((re=read(fdin,(char *)buf, BSIZE)) < 0){
return;
}
for (i=0; i < re; i+=TS_SIZE){
for (j=4; j<TS_SIZE; j+=2){
uint8_t ix = buf[i+j]+128;
uint8_t qy = 128-buf[i+j+1];
iq->data[ix|(qy<<8)] += 1;
uint64_t c = iq->data[ix|(qy<<8)];
if ( c > maxd) maxd = c;
}
}
t1 = getutime();
}
pam_data_convert(iq, maxd);
pam_coordinate_axes(iq, 255,255 ,0);
memset(iq->data,0,256*256*sizeof(uint64_t));
}
void pam_write (int fd, pamdata *iq){
char *HEAD="P7\nWIDTH 256\nHEIGHT 256\nDEPTH 3\nMAXVAL 255\nTUPLTYPE RGB\nENDHDR\n";
int headlen = strlen(HEAD);
int we=0;
we=write(fd,HEAD,headlen);
we=write(fd,iq->data_points,256*256*3);
memset(iq->data_points,0,256*256*3*sizeof(char));
}
void proc_ts(int i, uint8_t *buf)
{
uint16_t pid=0x1fff&((buf[1]<<8)|buf[2]);
@ -111,6 +282,9 @@ int main(int argc, char **argv)
int odvr = 0;
FILE *fout = stdout;
int line = -1;
int color = 0;
pamdata iq;
while (1) {
int cur_optind = optind ? optind : 1;
@ -134,16 +308,21 @@ int main(int argc, char **argv)
{"tscheck", no_argument, 0, 't'},
{"tscheck_l", required_argument, 0, 'a'},
{"nodvr", no_argument , 0, 'q'},
{"pam", no_argument , 0, 'a'},
{"help", no_argument , 0, 'h'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv,
"c:i:f:s:d:p:hg:r:n:b:l:v:m:ota:q",
"e:c:i:f:s:d:p:hg:r:n:b:l:v:m:ota:q",
long_options, &option_index);
if (c==-1)
break;
switch (c) {
case 'e':
odvr = 2;
color = strtoul(optarg, NULL, 0);
break;
case 'o':
fout = stderr;
if (odvr) {
@ -352,10 +531,22 @@ int main(int argc, char **argv)
if ((fd = open(filename ,O_RDONLY)) < 0){
fprintf(stderr,"Error opening input file:%s\n",filename);
}
if (odvr == 1){
while(1){
read(fd,buf,BUFFSIZE);
write(fileno(stdout),buf,BUFFSIZE);
if (odvr > 0){
switch (odvr){
case 1:
while(1){
read(fd,buf,BUFFSIZE);
write(fileno(stdout),buf,BUFFSIZE);
}
break;
case 2:
fprintf(stderr,"writing pamdata\n");
init_pamdata(&iq,color);
while(1){
pam_read_data(fd, &iq);
pam_write(STDOUT_FILENO, &iq);
}
break;
}
} else {
if( line >= 0 && line < 64 ){