from scipy import *
from pylab import *

from pyspuc import *
from pyspuc.sim_qpsk_double import *
from pyspuc.qpsk_double import *
from pyspuc.noise import *
from pyspuc.loop_filter_double import *
from pyspuc.qpsk_ber_test import *
from pyspuc.complex_double import *

# Parameters that influence initial conditions,errors and receiver behaviour

# Whether initial timing offset is 0 or not 
NOOFFSET=0
# Whether random seed changes depending on time sim is run
NORAND=1
# Whether there is timing drift or not
TIME=0
# Whether there is a frequency error or not
FREQ=0
# Whether frequency correction is done or not
FREQC=0

# When to turn on the Symbol timing loop if enabled
SYM_LOOP_ON = 10
# When to turn on the Carrier PLL if enabled
CAR_LOOP_ON = 1000
# How many symbols to discard before attempting to synchronize to
# tx pattern
WAITSYMBOLS = 2900

# Signal to noise ratio in dBs
snr=20
# Number of symbols simulated
num = 10000
# Oversampling ratio
actual_over=2.00
# Create the Simulation class
ENV = sim_qpsk_double()

# Random offset used for initial timing error if desired
random_offset = noise()
if(NORAND): random_offset.set_seed(123)
else: random_offset.set_seed(10*time())

if(NOOFFSET): timing_offset = 0
else: timing_offset = 0.5*random_offset.uni()*actual_over

ENV.num = num
ENV.snr = snr
ENV.time = TIME
ENV.freq = FREQ

# Create the QSPK receiver using C++ template instantiated with double
MYQPSK = qpsk_double()

# initialise classes, etc - separate from contructor to allow re-init
ENV.loop_init(actual_over, timing_offset)
# Initial delay for PN sequence to compare against - makes sync easier
ENV.BER_mon.init_delay(68)

rcv_symbols=0
symbols = 0

y = zeros(num)
inc = 0

SAMPF = open("samp.dat","w")
RESF = open("res.dat","w")

while (symbols < num):
    ENV.step()
    #############DEBUG STUFF#######################################
    tmp = str(ENV.RECEIVER.baseband.re)
    adc = str(ENV.adc_out.re)
    base = str(ENV.base.re)
    RESF.write(base+"\n")
    if(inc < num-1):
        y[inc] = (float)(ENV.base.re)
        inc = inc + 1
    ############# END DEBUG STUFF#######################################
    if(TIME) :
        if(ENV.rcv_symbols == SYM_LOOP_ON) :
            ENV.RECEIVER.symbol_loop_filter.k0_en = 1
    if(FREQC) :
        if(ENV.rcv_symbols == CAR_LOOP_ON) :
            ENV.RECEIVER.carrier_loop_filter.k1_en = 1
            ENV.RECEIVER.carrier_loop_filter.k0_en = 1

    if (ENV.RECEIVER.symclk()==1):
        if (ENV.rcv_symbols > WAITSYMBOLS):                    
            data = ENV.RECEIVER.data()  
            symbols = ENV.BER_mon.synchronise(symbols,data)
            # if sync found, print out results periodically
            if (ENV.BER_mon.found_sync()):
                ENV.BER_mon.ber_results(symbols) 
            symbols = symbols+1
    #############DEBUG STUFF#######################################
    SAMPF.write(str(ENV.RECEIVER.carrier_error))
    SAMPF.write(' ')
    SAMPF.write(str(ENV.RECEIVER.carrier_loop_out))
    SAMPF.write(' ')
    SAMPF.write(str(ENV.RECEIVER.final_baseband.re))
    SAMPF.write('\n')
    ############# END DEBUG STUFF#######################################
    # if we haven't yet found sync break out of loop
    if (ENV.rcv_symbols > num and not ENV.BER_mon.found_sync()):
        break

# print out final result for this run
ENV.BER_mon.final_results(symbols)
ENV.loop_end()
SAMPF.close()
RESF.close()

# plot
plot(y)