states.foff_est_hz = 0;
states.sample_point = states.timing_est = 1;
states.nin = states.Nsamperframe;
-
+ states.timing_valid = 0;
+ states.timing_mx = 0;
+ states.coarse_foff_est_hz = 0;
+
% generate OFDM pilot symbol, used for timing and freq offset est
rate_fs_pilot_samples = states.pilots * W/states.M;
states.rate = 1.0;
states.ldpc_en = 0;
+ % init some output states for logging
+
+ states.rx_sym = zeros(1+Ns+1+1, Nc+2);
+
endfunction
endfunction
+% ----------------------------------------------------------------------------------
+% ofdm_sync_search - attempts to find coarse sync parameters for modem initial sync
+% ----------------------------------------------------------------------------------
+
+function [timing_valid states] = ofdm_sync_search(states, rxbuf_in)
+ ofdm_load_const;
+
+ % insert latest input samples into rxbuf so it is primed for when we have to call ofdm_demod()
+
+ states.rxbuf(1:Nrxbuf-states.nin) = states.rxbuf(states.nin+1:Nrxbuf);
+ states.rxbuf(Nrxbuf-states.nin+1:Nrxbuf) = rxbuf_in;
+
+ % Attempt coarse timing estimate (i.e. detect start of frame)
+
+ st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe;
+ [ct_est foff_est timing_valid timing_mx] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
+ if states.verbose
+ printf(" ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx: %d\n", ct_est, foff_est, timing_valid, timing_mx);
+ end
+
+ if timing_valid
+ % potential candidate found ....
+
+ % calculate number of samples we need on next buffer to get into sync
+
+ states.nin = Nsamperframe + ct_est - 1;
+
+ % reset modem states
+
+ states.sample_point = states.timing_est = 1;
+ states.foff_est_hz = foff_est;
+ else
+ states.nin = Nsamperframe;
+ end
+ states.timing_valid = timing_valid;
+ states.timing_mx = timing_mx;
+ states.coarse_foff_est_hz = foff_est;
+endfunction
+
+
% ------------------------------------------
% ofdm_demod - Demodulates one frame of bits
% ------------------------------------------
end
prx += states.nin;
- printf(" states.nin: %d\n", states.nin);
- [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
-
- errors = xor(tx_bits, rx_bits);
- Nerrs = sum(errors);
- aber = Nerrs/Nbitsperframe;
-
- frame_count++;
-
- printf("f: %d state: %s Nerrs: %d aber: %3.2f\n", f, state, Nerrs, aber);
-
+ printf("f: %d state: %s nin: %d\n", f, state, nin);
+
% If looking for sync: check raw BER on frame just received
% against all possible positions in the interleaver frame.
% iterate state machine ------------------------------------
next_state = state;
- if strcmp(state,'searching')
- % If looking for sync: check raw BER on frame just received
- % against all possible positions in the interleaver frame.
+ if strcmp(state,'searching')
+ [timing_valid states] = ofdm_sync_search(states, rxbuf_in);
- if aber < 0.1
+ if timing_valid
next_state = 'synced';
- % make sure we get an interleave frame with correct freq offset
- % note this introduces a lot of delay, a better idea would be to
- % run demod again from interleave_frames back with now-known freq offset
- end
- end
-
- if strcmp(state,'synced')
- if Nerrs/Nbitsperframe > 0.2
- %next_state = 'searching';
end
end
+
+ if strcmp(state,'synced')
- state = next_state;
-
- if strcmp(state,'searching')
-
- % still searching? Attempt coarse timing estimate (i.e. detect start of frame)
-
- st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe;
- [ct_est foff_est] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
- if states.verbose
- printf(" Nerrs: %d ct_est: %4d foff_est: %3.1f\n", Nerrs, ct_est, foff_est);
- end
-
- % calculate number of samples we need on next buffer to get into sync
-
- states.nin = Nsamperframe + ct_est - 1;
-
- % reset modem states
+ printf(" states.nin: %d\n", states.nin);
+ [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
- states.sample_point = states.timing_est = 1;
- states.foff_est_hz = foff_est;
- end
+ errors = xor(tx_bits, rx_bits);
+ Nerrs = sum(errors);
+ aber = Nerrs/Nbitsperframe;
- if strcmp(state,'synced')
-
+ frame_count++;
+
% we are in sync so log states
rx_np_log = [rx_np_log arx_np];
Tbits += Nbitsperframe;
end
end
+
+ state = next_state;
+
end
printf("BER..: %5.4f Tbits: %5d Terrs: %5d\n", Terrs/Tbits, Tbits, Terrs);
i) 10 seconds, AWGN channel at Eb/No=3dB
- octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw', 10,3);
+ octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw', 10, 3);
ii) 10 seconds, HF channel at Eb/No=6dB
complex float acc = 0.0f + 0.0f * I;
for (i = 0; i < length; i++) {
- acc += rx[i] * conjf(rx[i]);
+ acc += crealf(rx[i]) * crealf(rx[i]) + cimagf(rx[i]) * cimagf(rx[i]);
}
av_level = 2.0*sqrt(ofdm->timing_norm*crealf(acc)/length) + 1E-12;
*/
static void ofdm_txframe(struct OFDM *ofdm, complex float tx[OFDM_SAMPLESPERFRAME],
- complex float *tx_sym_lin) {
+ complex float *tx_sym_lin) {
complex float aframe[OFDM_NS][OFDM_NC + 2];
complex float asymbol[OFDM_M];
complex float asymbol_cp[OFDM_M + OFDM_NCP];
}
}
+ for (i = 0; i < OFDM_ROWSPERFRAME*OFDM_NC; i++) {
+ ofdm->rx_np[i] = 0.0f + 0.0f * I;
+ }
+
+ for (i = 0; i < OFDM_ROWSPERFRAME; i++) {
+ for (j = 0; j < OFDM_NC; j++) {
+ ofdm->aphase_est_pilot_log[OFDM_NC*i+j] = 0.0f + 0.0f * I;
+ ofdm->rx_amp[OFDM_NC*i+j] = 0.0f + 0.0f * I;
+ }
+ }
+
/* default settings of options and states */
ofdm->verbose = 0;
}
}
+
+/*
+ * ----------------------------------------------------------------------------------
+ * ofdm_sync_search - attempts to find coarse sync parameters for modem initial sync
+ * ----------------------------------------------------------------------------------
+ */
+
+int ofdm_sync_search(struct OFDM *ofdm, COMP *rxbuf_in)
+{
+ int i,j;
+
+ /* insert latest input samples into rxbuf so it is primed for when
+ we have to call ofdm_demod() */
+
+ for (i = 0, j = ofdm->nin; i < (OFDM_RXBUF - ofdm->nin); i++, j++) {
+ ofdm->rxbuf[i] = ofdm->rxbuf[j];
+ }
+
+ /* insert latest input samples onto tail of rxbuf */
+
+ for (i = (OFDM_RXBUF - ofdm->nin), j = 0; i < OFDM_RXBUF; i++, j++) {
+ ofdm->rxbuf[i] = rxbuf_in[j].real + rxbuf_in[j].imag * I;
+ }
+
+ /* Attempt coarse timing estimate (i.e. detect start of frame) */
+
+ int st = OFDM_M + OFDM_NCP + OFDM_SAMPLESPERFRAME;
+ int en = st + 2*OFDM_SAMPLESPERFRAME;
+ int ct_est = coarse_sync(ofdm, &ofdm->rxbuf[st], (en - st), &ofdm->coarse_foff_est_hz);
+ if (ofdm->verbose) {
+ fprintf(stderr, " ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx: %f\n",
+ ct_est, ofdm->coarse_foff_est_hz, ofdm->timing_valid, ofdm->timing_mx);
+ }
+
+ if (ofdm->timing_valid) {
+ /* potential candidate found .... */
+
+ /* calculate number of samples we need on next buffer to get into sync */
+
+ ofdm->nin = OFDM_SAMPLESPERFRAME + ct_est;
+
+ /* reset modem states */
+
+ ofdm->sample_point = ofdm->timing_est = 0;
+ ofdm->foff_est_hz = ofdm->coarse_foff_est_hz;
+ }
+ else {
+ ofdm->nin = OFDM_SAMPLESPERFRAME;
+ }
+
+ return ofdm->timing_valid;
+}
+
+
+
/*
* ------------------------------------------
* ofdm_demod - Demodulates one frame of bits
if (strcmp(argv[1], "-") == 0) fin = stdin;
else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
- fprintf(stderr, "Error opening input file: %s: %s.\n",
- argv[1], strerror(errno));
- exit(1);
+ fprintf(stderr, "Error opening input file: %s: %s.\n",
+ argv[1], strerror(errno));
+ exit(1);
}
if (strcmp(argv[2], "-") == 0) fout = stdout;
else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
- fprintf(stderr, "Error opening output modem sample file: %s: %s.\n",
- argv[2], strerror(errno));
- exit(1);
+ fprintf(stderr, "Error opening output modem sample file: %s: %s.\n",
+ argv[2], strerror(errno));
+ exit(1);
}
-
+
ofdm = ofdm_create(OFDM_CONFIG_700D);
assert(ofdm != NULL);
int Nbitsperframe = ofdm_get_bits_per_frame(ofdm);
int sample_point_log[NFRAMES];
FILE *fout;
- int f,i,j;
+ int f,i,j, state, next_state;
ofdm = ofdm_create(OFDM_CONFIG_700D);
assert(ofdm != NULL);
+ state = OFDM_SEARCH;
+
/* Main Loop ---------------------------------------------------------------------*/
for(f=0; f<NFRAMES; f++) {
#endif
for(f=0; f<NFRAMES; f++) {
- /* For initial testng, timing est is off, so nin is always
+ /* For initial testing, timing est is off, so nin is always
fixed. TODO: we need a constant for rxbuf_in[] size that
is the maximum possible nin */
}
ofdm_demod(ofdm, rx_bits, rx);
#else
- ofdm_demod(ofdm, rx_bits, rxbuf_in);
+ next_state = state;
+ switch(state) {
+ case OFDM_SEARCH:
+ if (ofdm_sync_search(ofdm, rxbuf_in)) {
+ next_state = OFDM_SYNCED;
+ }
+ break;
+ case OFDM_SYNCED:
+ ofdm_demod(ofdm, rx_bits, rxbuf_in);
+ break;
+ }
+ state = next_state;
#endif
int Nerrs = 0;