Implement shift_addition_fc for downconversion of real signal
This commit is contained in:
parent
5a46f15d1b
commit
1446b62959
3 changed files with 77 additions and 0 deletions
49
csdr.c
49
csdr.c
|
@ -717,6 +717,55 @@ int main(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!strcmp(argv[1],"shift_addition_fc"))
|
||||||
|
{
|
||||||
|
bigbufs=1;
|
||||||
|
|
||||||
|
float starting_phase=0;
|
||||||
|
float rate;
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
if(fd=init_fifo(argc,argv))
|
||||||
|
{
|
||||||
|
while(!read_fifo_ctl(fd,"%g\n",&rate)) usleep(10000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(argc<=2) return badsyntax("need required parameter (rate)");
|
||||||
|
sscanf(argv[2],"%g",&rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!sendbufsize(initialize_buffers())) return -2;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
shift_addition_data_t data=shift_addition_init(rate);
|
||||||
|
fprintf(stderr,"shift_addition_fc: reinitialized to %g\n",rate);
|
||||||
|
int remain, current_size;
|
||||||
|
float* ibufptr;
|
||||||
|
float* obufptr;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
FEOF_CHECK;
|
||||||
|
if(!FREAD_R) break;
|
||||||
|
remain=the_bufsize;
|
||||||
|
ibufptr=input_buffer;
|
||||||
|
obufptr=output_buffer;
|
||||||
|
while(remain)
|
||||||
|
{
|
||||||
|
current_size=(remain>1024)?1024:remain;
|
||||||
|
starting_phase=shift_addition_fc(ibufptr, (complexf*)obufptr, current_size, data, starting_phase);
|
||||||
|
ibufptr+=current_size;
|
||||||
|
obufptr+=current_size*2;
|
||||||
|
remain-=current_size;
|
||||||
|
}
|
||||||
|
FWRITE_C;
|
||||||
|
if(read_fifo_ctl(fd,"%g\n",&rate)) break;
|
||||||
|
TRY_YIELD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(!strcmp(argv[1],"shift_addition_cc_test"))
|
if(!strcmp(argv[1],"shift_addition_cc_test"))
|
||||||
{
|
{
|
||||||
if(argc<=2) return badsyntax("need required parameter (rate)");
|
if(argc<=2) return badsyntax("need required parameter (rate)");
|
||||||
|
|
|
@ -51,6 +51,33 @@ float shift_addition_cc(complexf *input, complexf* output, int input_size, shift
|
||||||
return starting_phase;
|
return starting_phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float shift_addition_fc(float *input, complexf* output, int input_size, shift_addition_data_t d, float starting_phase)
|
||||||
|
{
|
||||||
|
//The original idea was taken from wdsp:
|
||||||
|
//http://svn.tapr.org/repos_sdr_hpsdr/trunk/W5WC/PowerSDR_HPSDR_mRX_PS/Source/wdsp/shift.c
|
||||||
|
|
||||||
|
//However, this method introduces noise (from floating point rounding errors), which increases until the end of the buffer.
|
||||||
|
//fprintf(stderr, "cosd=%g sind=%g\n", d.cosdelta, d.sindelta);
|
||||||
|
float cosphi=cos(starting_phase);
|
||||||
|
float sinphi=sin(starting_phase);
|
||||||
|
float cosphi_last, sinphi_last;
|
||||||
|
for(int i=0;i<input_size;i++) //@shift_addition_cc: work
|
||||||
|
{
|
||||||
|
iof(output,i)=cosphi*input[i];
|
||||||
|
qof(output,i)=sinphi*input[i];
|
||||||
|
//using the trigonometric addition formulas
|
||||||
|
//cos(phi+delta)=cos(phi)cos(delta)-sin(phi)*sin(delta)
|
||||||
|
cosphi_last=cosphi;
|
||||||
|
sinphi_last=sinphi;
|
||||||
|
cosphi=cosphi_last*d.cosdelta-sinphi_last*d.sindelta;
|
||||||
|
sinphi=sinphi_last*d.cosdelta+cosphi_last*d.sindelta;
|
||||||
|
}
|
||||||
|
starting_phase+=d.rate*PI*input_size;
|
||||||
|
while(starting_phase>PI) starting_phase-=2*PI; //@shift_addition_cc: normalize starting_phase
|
||||||
|
while(starting_phase<-PI) starting_phase+=2*PI;
|
||||||
|
return starting_phase;
|
||||||
|
}
|
||||||
|
|
||||||
shift_addition_data_t shift_addition_init(float rate)
|
shift_addition_data_t shift_addition_init(float rate)
|
||||||
{
|
{
|
||||||
rate*=2;
|
rate*=2;
|
||||||
|
|
|
@ -31,6 +31,7 @@ typedef struct shift_addition_data_s
|
||||||
} shift_addition_data_t;
|
} shift_addition_data_t;
|
||||||
shift_addition_data_t shift_addition_init(float rate);
|
shift_addition_data_t shift_addition_init(float rate);
|
||||||
float shift_addition_cc(complexf *input, complexf* output, int input_size, shift_addition_data_t d, float starting_phase);
|
float shift_addition_cc(complexf *input, complexf* output, int input_size, shift_addition_data_t d, float starting_phase);
|
||||||
|
float shift_addition_fc(float *input, complexf* output, int input_size, shift_addition_data_t d, float starting_phase);
|
||||||
void shift_addition_cc_test(shift_addition_data_t d);
|
void shift_addition_cc_test(shift_addition_data_t d);
|
||||||
|
|
||||||
float agc_ff(float* input, float* output, int input_size, float reference, float attack_rate, float decay_rate, float max_gain, short hang_time, short attack_wait_time, float gain_filter_alpha, float last_gain);
|
float agc_ff(float* input, float* output, int input_size, float reference, float attack_rate, float decay_rate, float max_gain, short hang_time, short attack_wait_time, float gain_filter_alpha, float last_gain);
|
||||||
|
|
Loading…
Reference in a new issue