From: drowe67 Date: Tue, 26 May 2015 07:28:08 +0000 (+0000) Subject: non linear carrier spacing and clipping code added, C and Octave match nicely X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=0efb8100f188236cbadd04a1b4c9447d54921a12;p=freetel-svn-tracking.git non linear carrier spacing and clipping code added, C and Octave match nicely git-svn-id: https://svn.code.sf.net/p/freetel/code@2149 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/tcohpsk.m b/codec2-dev/octave/tcohpsk.m index caa83b9e..7364a06b 100644 --- a/codec2-dev/octave/tcohpsk.m +++ b/codec2-dev/octave/tcohpsk.m @@ -120,7 +120,7 @@ Nsw = 3; % frames we demod for initial sync window afdmdv.Nsym = 6; % size of tx/tx root nyquist filter in symbols afdmdv.Nt = 5; % number of symbols we estimate timing over -clip = 65; % Clipping of tx signal to reduce PAPR. Adjust by +clip = 6.5; % Clipping of tx signal to reduce PAPR. Adjust by % experiment as Nc and Nd change. Check out no noise % scatter diagram and AWGN/fading BER perf % at operating points @@ -144,7 +144,8 @@ afdmdv.gt_alpha5_root = gen_rn_coeffs(excess_bw, 1/Fs, Rs, afdmdv.Nsym, afdmdv.M Fcentre = afdmdv.Fcentre = 1500; afdmdv.Fsep = afdmdv.Rs*(1+excess_bw); afdmdv.phase_tx = ones(afdmdv.Nc+1,1); -freq_hz = afdmdv.Fsep*( -Nc*Nd/2 - 0.5 + (1:Nc*Nd).^1 ); +% non linear carrier spacing, combined with clip, helps PAPR a lot! +freq_hz = afdmdv.Fsep*( -Nc*Nd/2 - 0.5 + (1:Nc*Nd).^0.98 ); afdmdv.freq_pol = 2*pi*freq_hz/Fs; afdmdv.freq = exp(j*afdmdv.freq_pol); afdmdv.Fcentre = 1500; diff --git a/codec2-dev/src/codec2_cohpsk.h b/codec2-dev/src/codec2_cohpsk.h index b4e227c5..aa1ccbb2 100644 --- a/codec2-dev/src/codec2_cohpsk.h +++ b/codec2-dev/src/codec2_cohpsk.h @@ -42,6 +42,7 @@ struct COHPSK; struct COHPSK *cohpsk_create(void); void cohpsk_destroy(struct COHPSK *coh); void cohpsk_mod(struct COHPSK *cohpsk, COMP tx_fdm[], int tx_bits[]); +void cohpsk_clip(COMP tx_fdm[]); void cohpsk_demod(struct COHPSK *cohpsk, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin_frame); #endif diff --git a/codec2-dev/src/cohpsk.c b/codec2-dev/src/cohpsk.c index 5d04b4b4..e26c310e 100644 --- a/codec2-dev/src/cohpsk.c +++ b/codec2-dev/src/cohpsk.c @@ -135,13 +135,15 @@ struct COHPSK *cohpsk_create(void) fdmdv->phase_tx[c].real = 1.0; fdmdv->phase_tx[c].imag = 0.0; - freq_hz = fdmdv->fsep*( -(COHPSK_NC*ND)/2 - 0.5 + c + 1.0 ); + /* note non-linear carrier spacing to help PAPR, works v well in conjunction with CLIP */ + + freq_hz = fdmdv->fsep*( -(COHPSK_NC*ND)/2 - 0.5 + pow(c + 1.0, 0.98) ); fdmdv->freq[c].real = cosf(2.0*M_PI*freq_hz/COHPSK_FS); fdmdv->freq[c].imag = sinf(2.0*M_PI*freq_hz/COHPSK_FS); fdmdv->freq_pol[c] = 2.0*M_PI*freq_hz/COHPSK_FS; - printf("c: %d %f %f\n",c,freq_hz,fdmdv->freq_pol[c]); + //printf("c: %d %f %f\n",c,freq_hz,fdmdv->freq_pol[c]); for(i=0; irx_filter_memory[c][i].real = 0.0; coh->rx_filter_memory[c][i].imag = 0.0; @@ -616,8 +618,8 @@ int sync_state_machine(struct COHPSK *coh, int sync, int next_sync) void cohpsk_mod(struct COHPSK *coh, COMP tx_fdm[], int tx_bits[]) { struct FDMDV *fdmdv = coh->fdmdv; - COMP tx_symb[NSYMROWPILOT][COHPSK_NC*ND]; - COMP tx_onesym[COHPSK_NC*ND]; + COMP tx_symb[NSYMROWPILOT][COHPSK_NC*ND]; + COMP tx_onesym[COHPSK_NC*ND]; int r,c; bits_to_qpsk_symbols(tx_symb, tx_bits, COHPSK_BITS_PER_FRAME); @@ -631,6 +633,33 @@ void cohpsk_mod(struct COHPSK *coh, COMP tx_fdm[], int tx_bits[]) } +/*---------------------------------------------------------------------------*\ + + FUNCTION....: cohpsk_clip() + AUTHOR......: David Rowe + DATE CREATED: May 2015 + + Hard clips a cohpsk modulator signal to improve PAPR, CLIP threshold + hard coded and will need to be changed if NC*ND does. + +\*---------------------------------------------------------------------------*/ + +void cohpsk_clip(COMP tx_fdm[]) +{ + COMP sam; + float mag; + int i; + + for(i=0; i COHPSK_CLIP) { + sam = fcmult( COHPSK_CLIP/mag, sam); + } + tx_fdm[i] = sam; + } + } + /*---------------------------------------------------------------------------*\ FUNCTION....: fdm_downconvert_coh diff --git a/codec2-dev/src/cohpsk_internal.h b/codec2-dev/src/cohpsk_internal.h index c98c580b..5a8c0474 100644 --- a/codec2-dev/src/cohpsk_internal.h +++ b/codec2-dev/src/cohpsk_internal.h @@ -38,7 +38,8 @@ #define COHPSK_NFILTER (COHPSK_NSYM*COHPSK_M) #define COHPSK_EXCESS_BW 0.5 /* excess BW factor of root nyq filter */ #define COHPSK_NT 5 /* number of symbols we estimate timing over */ - +#define COHPSK_CLIP 6.5 /* hard clipping for Nc*Nc=14 to reduce PAPR */ + #include "fdmdv_internal.h" #include "kiss_fft.h" diff --git a/codec2-dev/unittest/tcohpsk.c b/codec2-dev/unittest/tcohpsk.c index 7b16e4f0..49a0c9ce 100644 --- a/codec2-dev/unittest/tcohpsk.c +++ b/codec2-dev/unittest/tcohpsk.c @@ -158,6 +158,7 @@ int main(int argc, char *argv[]) tx_filter_and_upconvert_coh(&tx_fdm_frame[r*COHPSK_M], COHPSK_NC*ND , tx_onesym, fdmdv->tx_filter_memory, fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect); } + cohpsk_clip(tx_fdm_frame); /* --------------------------------------------------------*\ Channel