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;
|
||||
}
|
||||
|
||||
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(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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
rate*=2;
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef struct shift_addition_data_s
|
|||
} shift_addition_data_t;
|
||||
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_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);
|
||||
|
||||
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